版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BrightLD/article/details/78863086
DOM2的兼容处理
DOM2事件绑定,标准浏览器和IE低版本浏览器中除了语法上的区别,还有其它方面的区别
THIS问题
标准
执行事件池中绑定的方法,方法中的THIS是当前操作的元素;会给方法传递事件对象进来,事件对象中存在TARGET等属性;IE低版本
执行方法的时候,方法中的THIS是WINDOW而不是当前元素;事件对象也传递进来了,但是传递进来的值和window.event一样(和标准浏览器中的事件对象是有区别的)
重复问题
标准
如果我们绑定的方法重复了,浏览器不会把重复的方法添加到事件池中IE低版本
如果我们绑定的方法重复了,浏览器没有内置识别重复的机制,导致事件中有重复的方法,执行的时候,一个方法可能会被执行多次
顺序问题
标准
执行的顺序是按照绑定的顺序(事件池中方法排列的顺序:标准浏览器中会把后面绑定的方法放在事件池的末尾)依次执行的IE低版本
绑定的方法过多的时候,不知道是由于向事件池中增加的时候顺序混乱了,还是执行的时候顺序混乱了,总之执行的顺序和绑定的顺序是没关系的
我们DOM2事件兼容处理,其实就是想把IE低版本浏览器中的机制,改变成为和标准浏览器一模一样的机制(只需要处理IE低版本浏览器即可,高版本或者标准浏览器不去做任何特殊处理,按照浏览器默认的机制来运行即可)
IE低版本浏览器之所以出现这些问题,都是内置的事件池机制惹得祸,如果我们想让他和标准的机制一样,我们无法修改内置的东西,只能自己虚造出一个事件池,让虚造的事件池和标准一样,让IE低版本浏览器走我们自己虚造的事件池
~function () {
/* Array.prototype.myBind=function myBind(context) {
var _this=this;
var outer=[].slice.call(arguments,1);
return function () {
/!* var inner=[].slice.call(arguments);*!/
_this.apply(context,outer)
}
};*/
function on(curEle, type, fn) {
//如果说是在标准浏览器下面的话,我们直接调用addEventListener这个方法即可,下面的代码也不用在执行了。
if ("addEventListener" in curEle) {
curEle.addEventListener(type, fn, false)
}
return;
//我们利用自定义属性来创建一个事件池,让每一个事件对应一个事件池,
if (!curEle[type + "poor"]) {
curEle[type + "poor"] = [];
//代码如果说能执行到这里说明是在IE浏览器下面运行的,调用的是attachEvent进行监听,我们在这里调用run方法,需要改变this我们通过放在一个函数里面在里面通过call方法来改变this的指向,通过传递我们的事件对象window.event
curEle.attachEvent("on" + type, function () {
run.call(curEle, window.event)
})
}
/*
* curEle.attachEvent("on"+type,run.myBind(curEle))
* */
var ary = curEle[type + "poor"];
for (var i = 0; i < ary.length; i++) {
if (ary[i] === fn) return;
ary.push(fn)
}
}
function off(curEle, type, fn) {
if ("removeEventListener" in curEle) {
curEle.removeEventListener(type, fn, false)
}
return;
var ary = curEle[type + "poor"] || [];
for (var i = 0; i < ary.length; i++) {
if (ary[i] === fn) {
ary[i] = null;
break;
}
}
}
function run(e) {
if (!e.target) {
e.target = e.srcElement;
e.pageX = e.clientWidth + (document.documentElement.scrollTop || document.body.scrollTop);
e.pageY = e.clientHeight + (document.documentElement.scrollLeft || document.body.scrollLeft);
e.stopPropagation = function () {
e.cancelBubble = true;
}
e.preventDefault = function () {
e.stopPropagation = false;
}
}
var ary = this[e.type + "poor"];
if (ary) {
for (var i = 0; i < ary.length; i++) {
var item = ary[i];
if (!item) {
//我们在off的时候将其置为了null,!item=true
ary.splice(i, 1);
i--;
//i--是为了解决数组塌陷的问题
continue;
}
ary[i].call(this, e)
//使用call方法来改变this,ie下面没有事件参数,我们需要传递一个。
}
}
}
//将我们定义的方法暴露在全局,方便自己以后调用
window.wgh = {
on: on,
off: off
}
}();
window.wgh.on(document.body, 'click', function () {
console.log('aaa')
});