Javascript 事件機制

事件模型

DOM0級模型

在該模型中,事件不會傳播,沒有事件流的概念。這種模型兼容所有的瀏覽器。事件綁定監聽函數有兩種方式:

<!-- html 內聯直接綁定 -->
<input type="button" onclick="fun()">
//通過js指定屬性值
var btn = document.getElementById('.btn');
btn.onclick = fun;
//移除監聽函數
btn.onclick = null;

IE事件模型

IE事件模型共有兩個過程:

- 事件處理階段,事件到達目標元素,觸發目標元素的監聽函數
- 事件冒泡階段,事件從目標元素冒泡到document, 依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
//添加監聽
attachEvent(eventType, handler)
//移除監聽
detachEvent(eventType, handler)
/*
* eventType指定事件類型(注意加on)
* handler是事件處理函數
**/

DOM2級模型

屬于W3C標準模型,現代瀏覽器(除IE6-8之外的瀏覽器)都支持該模型。在該事件模型中,一次事件共有三個過程:

  • 事件捕獲階段。事件從document一直向下傳播到目標元素,依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
  • 事件處理階段。事件到達目標元素,觸發目標元素的監聽函數。
  • 事件冒泡階段。事件從目標元素冒泡到document, 依次檢查經過的節點是否綁定了事件監聽函數,如果有則執行。
//綁定事件監聽
addEventListener(eventType, handler, useCapture)
//移除事件監聽
removeEventListener(eventType, handler, useCapture)
/**
* eventType指定事件類型(不要加on)
* handler是事件處理函數
* useCapture是一個boolean用于指定是否在捕獲階段進行處理,一般設置為false與IE瀏覽器保持一致。
*/

事件對象

DOM事件模型中的事件對象屬性:

  • type用于獲取事件類型
  • target獲取事件目標
  • stopPropagation()阻止事件冒泡
  • preventDefault()阻止事件默認行為

IE事件模型中的事件對象常用屬性:

  • type用于獲取事件類型
  • srcElement獲取事件目標
  • cancelBubble阻止事件冒泡
  • returnValue阻止事件默認行為

跨瀏覽器事件處理


var eventUtils={
     // 添加句柄
     addHandler:function(element,type,handler){
       if(element.addEventListener){
         element.addEventListener(type,handler,false);
       }else if(element.attachEvent){
         element.attachEvent('on'+type,handler);
       }else{
         element['on'+type]=handler;
       }
     },
     // 刪除句柄
     removeHandler:function(element,type,handler){
       if(element.removeEventListener){
         element.removeEventListener(type,handler,false);
       }else if(element.detachEvent){
         element.detachEvent('on'+type,handler);
       }else{
         element['on'+type]=null;
       }
     },
    //獲取事件對象
    //IE模型中event是一個全局唯一的對象綁定在window對象上
    getEvent:function(event){
       return event?event:window.event;
    },
    //獲取類型
    getType:function(event){
     return event.type;
    },
    getElement:function(event){
     return event.target || event.srcElement;
    },
    //阻止默認事件
    preventDefault:function(event){
     if(event.preventDefault){
      event.preventDefault();
     }else{
      event.returnValue=false;
     }
    },
    //阻止冒泡
   stopPropagation:function(event){
   if(event.stopPropagation){
     event.stopPropagation();
   }else{
     event.cancelBubble=true;
    }
   }
  }

事件代理

事件在冒泡過程中會上傳到父節點,因此可以把子節點的監聽函數定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件,這種方式被稱為事件代理。

<div id="box">
    <input type="button" value="按鈕" id="btn">
    <input type="button" value="按鈕2" id="btn2">
    <input type="button" value="按鈕3" id="btn3">
</div>
var box = document.getElementById('box');

box.addEventListener('click', function(event) {
  if (event.target.tagName.toLowerCase() === 'input') {
    // some code
  }
});

自定義事件

以創建以個三擊事件為例

//創建一個事件
var event = new Event('threeclick', {"bubbles":true, "cancelable":false});
//為事件注冊監聽函數
target.addEventListener('threeclick', hello, false);
//觸發函數
target.dispatchEvent(event);
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容