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