javascript中傳統(tǒng)事件與現(xiàn)代事件
大家都知道,IE中的現(xiàn)代事件綁定(attachEvent)與W3C標(biāo)準(zhǔn)的(addEventListener)相比存在很多問題,
例如:內(nèi)存泄漏,重復(fù)添加事件并觸發(fā)的時(shí)候是倒敘執(zhí)行等。
下面是用傳統(tǒng)事件的方法來處理封裝事件的綁定:
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ǔ)存類型與函數(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]){
// 類型數(shù)據(jù)儲(chǔ)存挨個(gè)函數(shù)
obj.events[type] = [];
// 該類型的第一次事件類型及函數(shù)儲(chǔ)存到該類型數(shù)組中的第一位
obj.events[type][0] = fn;
} else {
var eventfn = obj.events[type];
// 循環(huán)遍歷該類型對(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)該類型已經(jīng)存在了,將為該事件進(jìn)行累計(jì)時(shí)間類型函數(shù)存儲(chǔ),最后循環(huán)執(zhí)行
eventfn[addEvent.ID++] = fn;
}
}
// 事件函數(shù) 類型數(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í)行類型儲(chǔ)存的多個(gè)函數(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ù)放置在該對(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ì)象下該類型的事件函數(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)訪問的時(shí)候值
為undefined
evefn.splice( i, 1); // 從第i的位置刪除1位,
}
}
}
}
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。
相關(guān)文章
開源免費(fèi)天氣預(yù)報(bào)接口API及全國所有地區(qū)代碼(國家氣象局提供)
這篇文章主要介紹了開源免費(fèi)天氣預(yù)報(bào)接口API及全國所有地區(qū)代碼(國家氣象局提供)的相關(guān)資料,需要的朋友可以參考下2016-12-12
JCrop+ajaxUpload 圖像切割上傳的實(shí)例代碼
這篇文章主要介紹了JCrop+ajaxUpload 圖像切割上傳的實(shí)例代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07
JavaScript onclick與addEventListener使用的區(qū)別介紹
addEventListener()方法用于向指定元素添加事件句柄,使用 removeEventListener()方法來移除,onclick和addEventListener事件區(qū)別是:onclick事件會(huì)被覆蓋,而addEventListener可以先后運(yùn)行不會(huì)被覆蓋,addEventListener可以監(jiān)聽多個(gè)事件2022-09-09
微信小程序動(dòng)態(tài)添加和刪除組件的現(xiàn)實(shí)
這篇文章主要介紹了微信小程序動(dòng)態(tài)添加和刪除組件的現(xiàn)實(shí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
input type=file 選擇圖片并且實(shí)現(xiàn)預(yù)覽效果的實(shí)例
下面小編就為大家?guī)硪黄猧nput type=file 選擇圖片并且實(shí)現(xiàn)預(yù)覽效果的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
詳解JavaScript原始數(shù)據(jù)類型Symbol
以前提到 JavaScript 原始數(shù)據(jù)類型時(shí),我們知道有Number,String,Null,Boolean,Undefined這幾種。ES6 引入了新的基本數(shù)據(jù)類型Symbol和BigInt。今天我們就來了解下Symbol類型。Symbol類型是為了解決屬性名沖突的問題,順帶還具備模擬私有屬性的功能。2021-05-05
iframe實(shí)現(xiàn)與父頁面跨域隔離的JavaScript?代碼沙箱
這篇文章主要介紹了使用iframe實(shí)現(xiàn)與父頁面跨域隔離的JavaScript代碼沙箱,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05

