有一個需求要爲document對象綁定click事件來是想隱藏提示框的交互功能,因而小白寫了以下代碼:瀏覽器
document.onclick = function(e) { e.preventDefault(); if(e.target !== document.getElementById('myinput')) { hidePageAlert(); } } function hidePageAlert() { //隱藏提示框 }
同事小銘看了看代碼說:dom
「首先,你爲document 綁定了click事件,可是onclick是DOM0級事件,也就是說這種方式綁定的時間至關於爲元素綁定了一個時間方法, 因此若是團隊中的其餘人再次經過這種方式爲document綁定click事件時,就至關於重複定義了一個方法,會將你定義的click事件方法覆蓋,以下列程序。」ide
document.onclick= function() { //其餘開發人員從新爲document綁定時間會覆蓋前面定義的DOM0級click事件 }
「因此你這種方式是很危險的。所以你應該用DOM2級事件處理程序提供的方法addEventListener來實現,然而你知道老版本的IE瀏覽器(低於9)是不支持這個方法的,它支持的是attachEvent,固然若是有不支持DOM2級事件處理程序的瀏覽器,你只能用onclick事件方法來綁定事件。」spa
「那麼有沒有一個兼容全部瀏覽器的方式呢?」 小白追問。code
兼容模式對象
// 外觀模式實現 function addEvent(dom, type, fn) { // 對於支持DOM2級事件處理程序addEventListener方法的瀏覽器 if(dom.addEventListener) { dome.addEventListener(type, fn, false); // 對於不支持addEventListener 方法,可是支持attachEvent方法的瀏覽器 }else if(dom.attachEvent) { dom.attachEvent('on' + type, fn); // 對於不支持addEventListener方法也不支持attachEvent方法,但支持on+'事件名'的瀏覽器 }else{ dom['on' + type] = fn; } }
「這樣咱們之後對於支持addEventListener 或 attachEvent方法的瀏覽器就能夠放心的綁定多個事件了, 以下所示。」blog
var myInput = document.getElementById('myinput'); addEvent(myInput, 'click', function(){ console.log('綁定第一個事件') }) addEvent(myInput, 'click', function(){ console.log('綁定第二個事件') })
除此以外接口
「不過以前寫的代碼問題不止一個,以前說了,外觀模式能夠簡化底層接口複雜性,也能夠解決瀏覽器兼容性問題。而你以前寫的代碼除了綁定時間的問題外,另外兩處問題是在其餘IE低版本瀏覽器中不兼容 e.preventDefault 和 e.target。你也能夠經過外觀模式來解決。」事件
// 獲取事件對象 var getEvent = function(event) { // 標準瀏覽器返回event,IE下window.event return event || window.event; } // 獲取元素 var getTarget = function(event) { var event = getEvent(event); // 標準瀏覽器下event.target, IE下event.srcElement return event.target || event.srcElement; } // 阻止默認行爲 var preventDefault = function(event) { var event = getEvent(event); // 標準瀏覽器 if(event.preventDefault) { event.preventDefault(); // IE 瀏覽器 }else { event.returnValue = false; } }
「有了上面的方法,咱們就能夠用兼容的簡單方式來解決上面的問題。」開發
document.onclick = function(e) { // 阻止默認行爲 preventDefault(e); // 獲取事件源目標對象 if(getTarget(e) != document.getElementById('myinput')){ hideInputSug(); } }