DOM2级事件绑定的兼容处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 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')
});

猜你喜欢

转载自blog.csdn.net/BrightLD/article/details/78863086
今日推荐