DOM2兼容問題,除了語法上的區別,在處理的機制上也有下列問題:順序問題,重複問題,this對象問題。瀏覽器
[標準]
curEle.addEventListener('type', fn, false);
[IE6~8]
curEle.attachEvent('ontype', fn)this
var on = function (curEle, type, fn) { if (document.addEventListener) { //標準瀏覽器 curEle.addEventListener(type, fn, false); return; } // IE6~8 curEle.attachEvent('on' + type, fn); } var off = function (curEle, type, fn) { if (document.removeEventListener) { //標準瀏覽器 curEle.removeEventListener(type, fn, false); return; } // IE6~8 curEle.detachEvent('on' + type, fn); };
當事件行爲觸發,執行對應事件池中存放的方法時,IE低版本瀏覽器執行方法順序是亂序的,而標準瀏覽器是按照綁定的前後順序依次執行的。code
var fn1 = function (e) { console.log(1); } var fn2 = function (e) { console.log(2); } var fn3 = function (e) { console.log(3); } var fn4 = function (e) { console.log(4); } on(document.body, 'click', fn1); on(document.body, 'click', fn2); on(document.body, 'click', fn3); on(document.body, 'click', fn4);
標準瀏覽器中輸出結果是: 1 2 3 4
IE6~8瀏覽器中輸出結果是:4 3 2 1
若是添加更多個事件,你會發現他們是亂序的。對象
IE低版本瀏覽器在向事件池中增長方法的時候沒有去重機制,那怕當前方法已經存放過了,還會重複的添加進去,而標準瀏覽器的事件池機制很完善,能夠自動去重(事件池中已經存在的方法,不容許在添加進來)。事件
on(document.body, 'click', fn8); on(document.body, 'click', fn8); on(document.body, 'click', fn8);
IE低版本瀏覽器中,會執行fn8 3次。沒有進行去重處理。可是在標準瀏覽器中只會輸出一次。rem
IE低版本瀏覽器中,當事件行爲觸發,把事件池中方法執行,此時方法中的this指向window,而標準瀏覽器中,this指向當前元素自己。io
var fn1 = function (e) { console.log(1, this); } on(document.body, 'click', fn1);
在標準瀏覽器中 this--> body
在IE低版本中 this--> windowconsole
究其根本,都是IE低版本瀏覽器對於它內置事件池處理機制的不完善致使的。function
DOM2事件綁定兼容處理的原理:告別低版本的IE6~8的內置事件池,而是本身建立一個相似於標準瀏覽器的「自定義事件池」,標準瀏覽器不須要處理兼容,只有IE6~8中才須要處理兼容。原理