欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Javascript添加監(jiān)聽與刪除監(jiān)聽用法詳解

 更新時間:2014年12月19日 16:03:29   投稿:shichen2014  
這篇文章主要介紹了Javascript添加監(jiān)聽與刪除監(jiān)聽用法,較為詳細(xì)的分析了javascript原理與用法,并補充說明了事件監(jiān)聽的兼容性問題,非常具有實用價值,需要的朋友可以參考下

本文實例講述了Javascript添加監(jiān)聽與刪除監(jiān)聽的用法。分享給大家供大家參考。具體分析如下:

js中事件監(jiān)聽就是利用addEventListener來綁定一個事件,這個用法在jquery中非常常用并且簡單,但在原生js中比較復(fù)雜,這里整理了addEventListener事件各方法的測試與例子供大家參考學(xué)習(xí)。

在前兩天做播放器的時候添加監(jiān)聽后刪除監(jiān)聽遇到了一點麻煩,刪不掉,后來看了一下才發(fā)現(xiàn),參數(shù)需要完全對應(yīng),什么叫完全對應(yīng)呢,換句話說:

復(fù)制代碼 代碼如下:
$('.video')[0].addEventListener('timeupdate', currentTimeHandler, true);

比如這句,需要傳入三個參數(shù),這樣才能夠刪除,為什么一定要這樣,沒錯,蛋疼的地方就在這里:
在add和remove時,第三個參數(shù)確實可以不寫,但此時他們的默認(rèn)情況是不一樣的??!

通常情況下addEventListener是false…
1、 添加自定義事件監(jiān)聽

復(fù)制代碼 代碼如下:
var eventHandlesCounter=1;//統(tǒng)計添加事件監(jiān)聽的個數(shù),0作為預(yù)留位
    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)聽
復(fù)制代碼 代碼如下:
function delEvent(obj,evt,fn){
   if(!obj.__EventHandles || !obj.__EventHandles[evt] || !fn.__EventID){
      return false;
   }
   if(obj.__EventHandles[evt][fn.__EventID]==fn){
      delete obj.__EventHandles[evt][fn.__EventID];
   }
}

3. 對上述方法進行修正
復(fù)制代碼 代碼如下:
function addEvent(obj,evt,fn,useCapture){
    if(obj.addEventListener){//優(yōu)先使用W3C事件注冊
       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)化事件對象
復(fù)制代碼 代碼如下:
function fixEvent(evt){
   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ù)不是單獨執(zhí)行的,它必須有一個事件對象參數(shù),而且只有事件發(fā)生時它才被執(zhí)行!最好的方法是把它整合到addEvent函數(shù)的execEventHandles里面。

復(fù)制代碼 代碼如下:
addEvent.execEventHandles = function (evt) {//遍歷所有的事件處理函數(shù)并執(zhí)行
if (!this.__EventHandles) {return true;}
evt = fixEvent(evt || window.event);//在這里對其進行標(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ù)的第一個參數(shù)
//這樣在事件處理函數(shù)內(nèi)部就可以使用統(tǒng)一的方法訪問事件對象了 } } };

上面是高手寫了,下面整理幾個實際的監(jiān)聽事情的例子

復(fù)制代碼 代碼如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<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);進行動態(tài)的事件綁定,使用
復(fù)制代碼 代碼如下:

document.getElementById("1").detachEvent("onclick",test)
進行動態(tài)的時間的取消,這樣就實現(xiàn)了這個事件只能相應(yīng)一次,下次再點擊這個按鈕的時候就不會再產(chǎn)生什么效果。
下面再演示一個時時監(jiān)聽鍵盤事件,判斷輸入的是否是數(shù)字,如果不是數(shù)字直接動態(tài)提示,然后拒絕其輸入
復(fù)制代碼 代碼如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>test7.html</title>
 <script type="text/javascript">
  function test(event){
   //用戶每按下一個按鍵,就去判斷是不是數(shù)字
   if(event.keyCode<48 || event.keyCode > 57){
    window.alert("您輸入的不是一個數(shù)字");
    return false;
   }
  }
 </script>
  </head>
 
  <body>
    <input type="text" onkeypress="return test(event);" />請輸入數(shù)字
  </body>
</html>

這里的event就是一個事件對象,他能返回很多的信息,具體請參考相關(guān)文檔。
 
補充:事件監(jiān)聽方面的兼容

1. IE使用attachEvent/detachEvent方法來添加和刪除事件監(jiān)聽器;w3c使用addEventListener/removeEventListener方法。
2. IE對其事件使用onevent的命名方式,而w3c的是event的命名方式。
3. IE事件監(jiān)聽器內(nèi)使用的是一個全局的Event對象,而w3c是將event對象作為參數(shù)傳遞給監(jiān)聽器。
4. 為了避免觸發(fā)默認(rèn)的事件行為,IE的做法是要求程序員設(shè)置Event對象中的returnValue屬性值為false,而w3c的做法是執(zhí)行preventDefault方法。
5. IE沒有提供對事件捕獲階段的支持。
6. 要停止事件的傳遞,IE的做法是設(shè)置event對象的cancelBubble為true,而w3c的做法是設(shè)置執(zhí)行stopPropagation方法。
7. IE將事件監(jiān)聽器當(dāng)做一個獨立的函數(shù)來調(diào)用,而w3c中它是作為對象的方法來調(diào)用的,這表示在ie中事件監(jiān)聽器中的this關(guān)鍵字指向的不是事件發(fā)生對象而是一個沒用的全局對象(window對象)。
8. IE在使用事件監(jiān)聽器方面存在內(nèi)存泄露問題。在IE瀏覽器中,如果要為某個元素創(chuàng)建一個事件監(jiān)聽器,并且在監(jiān)聽器中使用該元素,則在用戶進入其他頁面之前,該監(jiān)聽器以及相關(guān)的DOM節(jié)點作占據(jù)的內(nèi)存空間不會被釋放。

希望本文所述對大家的javascript程序設(shè)計有所幫助。

相關(guān)文章

最新評論