DOM2兼容问题,除了语法上的区别,在处理的机制上也有下列问题:顺序问题,重复问题,this对象问题。

语法问题

[标准]
curEle.addEventListener('type', fn, false);
[IE6~8]
curEle.attachEvent('ontype', fn)

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低版本浏览器执行方法顺序是乱序的,而标准浏览器是按照绑定的先后顺序依次执行的。

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次。没有进行去重处理。但是在标准浏览器中只会输出一次。

THIS问题

IE低版本浏览器中,当事件行为触发,把事件池中方法执行,此时方法中的this指向window,而标准浏览器中,this指向当前元素本身。

var fn1 = function (e) { console.log(1, this); }on(document.body, 'click', fn1);

在标准浏览器中 this--> body
在IE低版本中 this--> window

究其根本,都是IE低版本浏览器对于它内置事件池处理机制的不完善导致的。

DOM2事件绑定兼容处理的原理:告别低版本的IE6~8的内置事件池,而是自己创建一个类似于标准浏览器的“自定义事件池”,标准浏览器不需要处理兼容,只有IE6~8中才需要处理兼容。