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中才需要处理兼容。


大煜儿
103 声望7 粉丝

用心走路,给每一个细节打一个结。