Javascript添加監(jiān)聽(tīng)與刪除監(jiān)聽(tīng)用法詳解
本文實(shí)例講述了Javascript添加監(jiān)聽(tīng)與刪除監(jiān)聽(tīng)的用法。分享給大家供大家參考。具體分析如下:
js中事件監(jiān)聽(tīng)就是利用addEventListener來(lái)綁定一個(gè)事件,這個(gè)用法在jquery中非常常用并且簡(jiǎn)單,但在原生js中比較復(fù)雜,這里整理了addEventListener事件各方法的測(cè)試與例子供大家參考學(xué)習(xí)。
在前兩天做播放器的時(shí)候添加監(jiān)聽(tīng)后刪除監(jiān)聽(tīng)遇到了一點(diǎn)麻煩,刪不掉,后來(lái)看了一下才發(fā)現(xiàn),參數(shù)需要完全對(duì)應(yīng),什么叫完全對(duì)應(yīng)呢,換句話(huà)說(shuō):
比如這句,需要傳入三個(gè)參數(shù),這樣才能夠刪除,為什么一定要這樣,沒(méi)錯(cuò),蛋疼的地方就在這里:
在add和remove時(shí),第三個(gè)參數(shù)確實(shí)可以不寫(xiě),但此時(shí)他們的默認(rèn)情況是不一樣的??!
通常情況下addEventListener是false…
1、 添加自定義事件監(jiān)聽(tīng)
function addEvent(obj,evt,fn){
if(!fn.__EventID){ fn.__EventID=eventHandlesCounter++;}
if(!obj.__EventHandles){ obj.__EventHandles=[]; }
if(!obj.__EventHandles[evt]){
obj.__EventHandles[evt]=[];
if(obj["on"+evt] instanceof Function){
obj.__EventHandles[evt][0]=obj["on"+evt];
obj["on"+evt]=handleEvents;
}
}
obj.__EventHandles[evt][fn.__EventID]=fn;
function handleEvents(){
var fns = obj.__EventHandles[evt];
for (var i=0;i<fns.length;i++)
fns[i].call(this);
}
}
2、自定義刪除事件監(jiān)聽(tīng)
if(!obj.__EventHandles || !obj.__EventHandles[evt] || !fn.__EventID){
return false;
}
if(obj.__EventHandles[evt][fn.__EventID]==fn){
delete obj.__EventHandles[evt][fn.__EventID];
}
}
3. 對(duì)上述方法進(jìn)行修正
if(obj.addEventListener){//優(yōu)先使用W3C事件注冊(cè)
obj.addEventListener(evt,fn,!!useCapture);
}else{
if(!fn.__EventID){fn.__EventID = addEvent.__EventHandlesCounter++;}
if(!obj.__EventHandles){ obj.__EventHandles=[];}
if(!obj.__EventHandles[evt]){
obj.__EventHandles[evt]=[];
if(obj["on"+evt]){
(obj.__EventHandles[evtype][0]=obj["on"+evtype]).__EventID=0;
}
obj["on"+evtype]=addEvent.execEventHandles;
}
}
}
addEvent.__EventHandlesCounter=1;
addEvent.execEventHandles = function(evt){
if(!this.__EventHandles) {return true;}
evt = evt || window.event;
var fns = this.__EventHandles[evt.type];
for (var i=0;i<fns.length;i++){
if(fns[i] instanceof Function){
fns[i].call(this);
}
}
};
function delEvent(obj,evt,fn,useCapture){
if (obj.removeEventListener) {//先使用W3C的方法移除事件處理函數(shù)
obj.removeEventListener(evt,fn,!!useCapture);
}else {
if(obj.__EventHandles){
var fns = obj.__EventHandles[evt];
if(fns){delete fns[fn.__EventID];}
}
}
4、標(biāo)準(zhǔn)化事件對(duì)象
if(!evt.target){
evt.target = evt.srcElement;
evt.preventDefault=fixEvent.preventDefault;
evt.stopPropagation = fixEvent.stopPropagation;
if(evt.type == "mouseover"){
evt.relatedTarget = evt.fromElement;
}else if(evt.type == "mouseout"){
evt.relatedTarget = evt.toElement;
}
evt.charCode =(evt.type == "keypress")?evt.keyCode:0;
evt.eventPhase = 2;
evt.timeStamp = (new Date()).getTime();
}
return evt;
}
fixEvent.preventDefault=function(){ this.returnValue=false;}
fixEvent.stopPropagation=function(){this.cancelBubble = true;};
fixEvent函數(shù)不是單獨(dú)執(zhí)行的,它必須有一個(gè)事件對(duì)象參數(shù),而且只有事件發(fā)生時(shí)它才被執(zhí)行!最好的方法是把它整合到addEvent函數(shù)的execEventHandles里面。
if (!this.__EventHandles) {return true;}
evt = fixEvent(evt || window.event);//在這里對(duì)其進(jìn)行標(biāo)準(zhǔn)化操作
var fns = this.__EventHandles[evt.type];
for (var i=0;i< fns.length;i++) {
if (fns[i] instanceof Function) {
fns[i].call(this,evt);//并且將其作為事件處理函數(shù)的第一個(gè)參數(shù)
//這樣在事件處理函數(shù)內(nèi)部就可以使用統(tǒng)一的方法訪問(wèn)事件對(duì)象了 } } };
上面是高手寫(xiě)了,下面整理幾個(gè)實(shí)際的監(jiān)聽(tīng)事情的例子
<html>
<head>
<title>test6.html</title>
<script type="text/javascript">
function test(){
window.alert("您投了一次票");
document.getElementById("1").detachEvent("onclick",test);
}
</script>
</head>
<body>
<input type="button" value="投票" id="1"/>
<script type="text/javascript">
document.getElementById("1").attachEvent("onclick",test);
</script>
</body>
</html>
這里使用document.getElementById("1").attachEvent("onclick",test);進(jìn)行動(dòng)態(tài)的事件綁定,使用
document.getElementById("1").detachEvent("onclick",test)
下面再演示一個(gè)時(shí)時(shí)監(jiān)聽(tīng)鍵盤(pán)事件,判斷輸入的是否是數(shù)字,如果不是數(shù)字直接動(dòng)態(tài)提示,然后拒絕其輸入
<html>
<head>
<title>test7.html</title>
<script type="text/javascript">
function test(event){
//用戶(hù)每按下一個(gè)按鍵,就去判斷是不是數(shù)字
if(event.keyCode<48 || event.keyCode > 57){
window.alert("您輸入的不是一個(gè)數(shù)字");
return false;
}
}
</script>
</head>
<body>
<input type="text" onkeypress="return test(event);" />請(qǐng)輸入數(shù)字
</body>
</html>
這里的event就是一個(gè)事件對(duì)象,他能返回很多的信息,具體請(qǐng)參考相關(guān)文檔。
補(bǔ)充:事件監(jiān)聽(tīng)方面的兼容
1. IE使用attachEvent/detachEvent方法來(lái)添加和刪除事件監(jiān)聽(tīng)器;w3c使用addEventListener/removeEventListener方法。
2. IE對(duì)其事件使用onevent的命名方式,而w3c的是event的命名方式。
3. IE事件監(jiān)聽(tīng)器內(nèi)使用的是一個(gè)全局的Event對(duì)象,而w3c是將event對(duì)象作為參數(shù)傳遞給監(jiān)聽(tīng)器。
4. 為了避免觸發(fā)默認(rèn)的事件行為,IE的做法是要求程序員設(shè)置Event對(duì)象中的returnValue屬性值為false,而w3c的做法是執(zhí)行preventDefault方法。
5. IE沒(méi)有提供對(duì)事件捕獲階段的支持。
6. 要停止事件的傳遞,IE的做法是設(shè)置event對(duì)象的cancelBubble為true,而w3c的做法是設(shè)置執(zhí)行stopPropagation方法。
7. IE將事件監(jiān)聽(tīng)器當(dāng)做一個(gè)獨(dú)立的函數(shù)來(lái)調(diào)用,而w3c中它是作為對(duì)象的方法來(lái)調(diào)用的,這表示在ie中事件監(jiān)聽(tīng)器中的this關(guān)鍵字指向的不是事件發(fā)生對(duì)象而是一個(gè)沒(méi)用的全局對(duì)象(window對(duì)象)。
8. IE在使用事件監(jiān)聽(tīng)器方面存在內(nèi)存泄露問(wèn)題。在IE瀏覽器中,如果要為某個(gè)元素創(chuàng)建一個(gè)事件監(jiān)聽(tīng)器,并且在監(jiān)聽(tīng)器中使用該元素,則在用戶(hù)進(jìn)入其他頁(yè)面之前,該監(jiān)聽(tīng)器以及相關(guān)的DOM節(jié)點(diǎn)作占據(jù)的內(nèi)存空間不會(huì)被釋放。
希望本文所述對(duì)大家的javascript程序設(shè)計(jì)有所幫助。
- JavaScript監(jiān)聽(tīng)和禁用瀏覽器回車(chē)事件實(shí)例
- javascript監(jiān)聽(tīng)鼠標(biāo)滾輪事件淺析
- 在JavaScript中監(jiān)聽(tīng)I(yíng)ME鍵盤(pán)輸入事件
- 有道JavaScript監(jiān)聽(tīng)瀏覽器的問(wèn)題
- javascript在事件監(jiān)聽(tīng)方面的兼容性小結(jié)
- javascript過(guò)濾危險(xiǎn)腳本方法
- javascript下過(guò)濾數(shù)組重復(fù)值的代碼
- JavaScript監(jiān)聽(tīng)文本框回車(chē)事件并過(guò)濾文本框空格的方法
相關(guān)文章
JS實(shí)現(xiàn)移動(dòng)端實(shí)時(shí)監(jiān)聽(tīng)輸入框變化的實(shí)例代碼
這篇文章主要介紹了JS實(shí)現(xiàn)移動(dòng)端實(shí)時(shí)監(jiān)聽(tīng)輸入框變化的解決方案,需要的朋友可以參考下2017-04-04
JS字符串轉(zhuǎn)GBK編碼超精簡(jiǎn)實(shí)現(xiàn)詳解
JS中GBK編碼轉(zhuǎn)字符串是非常簡(jiǎn)單的,但反過(guò)來(lái),字符串轉(zhuǎn)GBK編碼卻沒(méi)這么簡(jiǎn)單。接下來(lái)本文就將帶大家一起康康JS如何實(shí)現(xiàn)字符串轉(zhuǎn)GBK編碼,需要的可以參考一下2022-08-08
js中常見(jiàn)的4種創(chuàng)建對(duì)象方式與優(yōu)缺點(diǎn)
不管是哪門(mén)語(yǔ)言,千變?nèi)f化不離其宗,深入理解其本質(zhì),方能應(yīng)用自如,下面這篇文章主要給大家介紹了關(guān)于js中常見(jiàn)的4種創(chuàng)建對(duì)象方式與優(yōu)缺點(diǎn),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01
JavaScript+css+HTML實(shí)現(xiàn)移動(dòng)端輪播圖(含源碼)
這篇文章主要介紹了JavaScript+css+HTML實(shí)現(xiàn)移動(dòng)端輪播圖并含源碼的分享,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-01-01
js字母大小寫(xiě)轉(zhuǎn)換實(shí)現(xiàn)方法總結(jié)
本文是對(duì)js中字母大小寫(xiě)轉(zhuǎn)換的實(shí)現(xiàn)方法進(jìn)行了總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-11-11
javascript jscroll模擬html元素滾動(dòng)條
這里是自己在工作不太忙的時(shí)候?qū)懗鰜?lái)了一個(gè)用戶(hù)可以自定義的滾動(dòng)條jscroll,以下簡(jiǎn)稱(chēng)jscroll。jscroll默認(rèn)只提供一種滾動(dòng)條樣式,部分樣式來(lái)自google webstore ,其中有部分css3樣式主要用于實(shí)現(xiàn)圓角,陰影效果2012-12-12
js中的數(shù)組轉(zhuǎn)樹(shù)型結(jié)構(gòu)方式
這篇文章主要介紹了js中的數(shù)組轉(zhuǎn)樹(shù)型結(jié)構(gòu)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06

