ie7、ie8兼容addEventListener和removeEventListener,解決this指向和detachEvent解除綁定事件問題


  • 在瀏覽器中,dom監(jiān)聽事件使用addEventListener(removeEventListener);
    在ie7、ie8中,監(jiān)聽事件使用attachEvent(detachEvent)。
if(document.addEventListener){
    element.addEventListener(type, fun, useCapture);
}else{
    element.addEventListener("on" + type, fun);
}
  • addEventListener綁定的監(jiān)聽事件,事件內(nèi)this指向element。但是attachEvent綁定的監(jiān)聽事件,事件內(nèi)this指向window,使用call或者apply可以解決該問題,修改this指向element,event作為參數(shù)傳遞。
var addListener = (function(){
    if(document.addEventListener){
        return function(element, type, fun, useCapture){
            element.addEventListener(type, fun, useCapture ? useCapture : false);
        };    
    }else{
        return function(element, type, fun){
            element.attachEvent("on" + type, function(event){
                fun.call(element, event);
            });
        };
    }
})();

但是這樣也有個問題,就是detachEvent無法解除監(jiān)聽,因為傳遞的事件已經(jīng)改變了。

  • 通過function.prototype將修改后的函數(shù)和已經(jīng)綁定該事件的dom儲存起來,可以使detachEvent時能獲取到解除監(jiān)聽的函數(shù),并且避免dom多次綁定重復(fù)事件。
/**
 * addEventlistener兼容函數(shù)
 * ie9以上正常使用addEventlistener函數(shù)
 * ie7、ie8用傳遞的function的function.prototype._bindFun儲存經(jīng)過處理的事件和對應(yīng)的節(jié)點
 * function.prototype._bindFun[index].type:綁定的事件類型
 * function.prototype._bindFun[index].element:綁定的節(jié)點
 * function.prototype._bindFun[index].Function:處理的事件
 */

/*** addEventlistener ***/
const addListener = (()=>{
    if(document.addEventListener){
        /* ie9以上正常使用addEventListener */
        return function(element, type, fun, useCapture){
            element.addEventListener(type, fun, useCapture ? useCapture : false);
        };
    }else{
        /* ie7、ie8使用attachEvent */
        return function(element, type, fun){
            if(!fun.prototype._bindFun){
                fun.prototype._bindFun = [];
            }
            // 判斷當(dāng)前的element是否已經(jīng)綁定過該事件
            let s = true;
            for(const i in fun.prototype._bindFun){
                if(fun.prototype._bindFun[i].type === type && fun.prototype._bindFun[i].element === element){
                    s = false;
                    break;
                }
            }
            // 沒有綁定事件
            if(s === true){
                const f = {
                    type: type,
                    element: element,
                    Function: function(event){
                        fun.call(element, event);
                    }
                };
                fun.prototype._bindFun.push(f);
                element.attachEvent(`on${type}`, f.Function);
            }
        };
    }
})();

/*** removeEventlistener ***/
const removeListener = (()=>{
    if(document.addEventListener){
        /* ie9以上正常使用removeEventListener */
        return function(element, type, fun){
            element.removeEventListener(type, fun);
        };
    }else{
        /* ie7、ie8使用detachEvent */
        return function(element, type, fun){
            for(const i in fun.prototype._bindFun){
                if(fun.prototype._bindFun[i].type === type && fun.prototype._bindFun[i].element === element){
                    element.detachEvent(`on${type}`, fun.prototype._bindFun[i].Function);
                    fun.prototype._bindFun.splice(i, 1);
                    break;
                }
            }
        };
    }
})();

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 以下文章為轉(zhuǎn)載,對理解JavaScript中的事件處理機制很有幫助,淺顯易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy閱讀 3,162評論 1 10
  • 聲明:本文來源于http://www.webzsky.com/?p=731我只是在這里作為自己的學(xué)習(xí)筆記整理一下(...
    angryyan閱讀 7,239評論 1 6
  • 什么是事件: 事件是交互體驗的核心功能 一.事件冒泡: 當(dāng)一個事件發(fā)生時,這個事件會從內(nèi)向外逐層傳遞。 二.為什么...
    輕描淡寫mua閱讀 573評論 0 0
  • 事件綁定的方式 給 DOM 元素綁定事件分為兩大類:在 html 中直接綁定 和 在 JavaScript 中綁定...
    Bruce_zhuan閱讀 1,128評論 0 6
  • 和你打電話是很久以前了吧,四五個月,或是更久,生性懶乏,記日子最不在行,不喜歡精確到毫厘的專業(yè),只享受渾渾噩噩地安...
    YUANMBL閱讀 665評論 0 2

友情鏈接更多精彩內(nèi)容