javascript中傳統(tǒng)事件與現(xiàn)代事件
大家都知道,IE中的現(xiàn)代事件綁定(attachEvent)與W3C標(biāo)準(zhǔn)的(addEventListener)相比存在很多問題,
例如:內(nèi)存泄漏,重復(fù)添加事件并觸發(fā)的時候是倒敘執(zhí)行等。
下面是用傳統(tǒng)事件的方法來處理封裝事件的綁定:
addEvent.ID = 1; // 事件計數(shù)器 function addEvent(obj, type, fn){ if(obj.addEventListener){ obj.addEventListener(type, fn, false); } else { // IE // 判斷對象是否存在,保證只有一個對象,否則每執(zhí)行一次,會創(chuàng)建一個事件對象 // 以鍵值對的形式儲存類型與函數(shù)的一個數(shù)組,=======將事件對象數(shù)組掛載到obj對象是為 了方便事件的刪除 if( !obj.events){ // 相當(dāng)于結(jié)構(gòu)為:obj.events : {click:[fn1,fn2], mouserover:[fn1], ...} obj.events = {}; } var flag = false; // 存儲事件對象 if( !obj.events[type]){ // 類型數(shù)據(jù)儲存挨個函數(shù) obj.events[type] = []; // 該類型的第一次事件類型及函數(shù)儲存到該類型數(shù)組中的第一位 obj.events[type][0] = fn; } else { var eventfn = obj.events[type]; // 循環(huán)遍歷該類型對象查詢該事件是否重復(fù),如果重復(fù)flag為true,并return返回 for(var i in eventfn){ if(eventfn[i] == fn ){ flag = true; return; } } // 判斷該事件是否重復(fù),重復(fù)的話就不進(jìn)行事件的函數(shù)的存儲,否則儲存該事件并執(zhí)行 if( !flag ){ // 當(dāng)該類型已經(jīng)存在了,將為該事件進(jìn)行累計時間類型函數(shù)存儲,最后循環(huán)執(zhí)行 eventfn[addEvent.ID++] = fn; } } // 事件函數(shù) 類型數(shù)組 函數(shù)遍歷調(diào)用 obj["on"+type] = function(){ var event = window.event; // 事件對象的儲存 // 在事件對象后添加函數(shù),當(dāng)執(zhí)行的時候調(diào)用,并阻止默認(rèn)行為的發(fā)生,與W3C標(biāo)準(zhǔn)同步 event.preventDefault = function(){ this.returnValue = false; }; // 在事件對象后面添加函數(shù),一個尾巴函數(shù),停止冒泡。 event.stopPropagation = function(){ this.cancelBubble = true; }; // 循環(huán)遍歷執(zhí)行類型儲存的多個函數(shù) var evfn = obj.events[type]; for(var i in evfn){ // 順序執(zhí)行該類型的事件函數(shù),解決了傳統(tǒng)事件的覆蓋問題和現(xiàn)代事件綁定的逆序觸發(fā) 事件的問題 evfn[i].call(this, event); // 將執(zhí)行函數(shù)放置在該對象的環(huán)境下執(zhí)行,并傳遞一個事件對 象給函數(shù)回調(diào)使用 } } } } function removeEvent(obj, type, fn){ if(obj.removeEventListener){ obj.removeEventListener(type, fn, false); } else { // 循環(huán)遍歷該對象下該類型的事件函數(shù)是否函數(shù)該函數(shù),如果有就將該事件函數(shù)刪除 var evefn = obj.events[type]; for(var i in evefn){ if(evefn[i] == fn){ // delete evefn[i]; 該方法也可以刪除該數(shù)組的該項,但是會保留該位置當(dāng)訪問的時候值 為undefined evefn.splice( i, 1); // 從第i的位置刪除1位, } } } }
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。
相關(guān)文章
開源免費(fèi)天氣預(yù)報接口API及全國所有地區(qū)代碼(國家氣象局提供)
這篇文章主要介紹了開源免費(fèi)天氣預(yù)報接口API及全國所有地區(qū)代碼(國家氣象局提供)的相關(guān)資料,需要的朋友可以參考下2016-12-12JavaScript onclick與addEventListener使用的區(qū)別介紹
addEventListener()方法用于向指定元素添加事件句柄,使用 removeEventListener()方法來移除,onclick和addEventListener事件區(qū)別是:onclick事件會被覆蓋,而addEventListener可以先后運(yùn)行不會被覆蓋,addEventListener可以監(jiān)聽多個事件2022-09-09input type=file 選擇圖片并且實現(xiàn)預(yù)覽效果的實例
下面小編就為大家?guī)硪黄猧nput type=file 選擇圖片并且實現(xiàn)預(yù)覽效果的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10詳解JavaScript原始數(shù)據(jù)類型Symbol
以前提到 JavaScript 原始數(shù)據(jù)類型時,我們知道有Number,String,Null,Boolean,Undefined這幾種。ES6 引入了新的基本數(shù)據(jù)類型Symbol和BigInt。今天我們就來了解下Symbol類型。Symbol類型是為了解決屬性名沖突的問題,順帶還具備模擬私有屬性的功能。2021-05-05iframe實現(xiàn)與父頁面跨域隔離的JavaScript?代碼沙箱
這篇文章主要介紹了使用iframe實現(xiàn)與父頁面跨域隔離的JavaScript代碼沙箱,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05