Javascript事件處理程式的5種方式(相容寫法)

kriswuwenxiang發表於2018-01-25

引言

什麼是事件?

JavaScript 使我們有能力建立動態頁面,事件是可以被 JavaScript 偵測到的行為。網頁中的每個元素都可以產生某些可以觸發 JavaScript 函式的事件。比方說,我們可以在使用者點選某按鈕時產生一個 onClick 事件來觸發某個函式。JavaScript 事件參考手冊

注意: 事件通常與函式配合使用,當事件發生時函式才會執行。

什麼是事件流?

事件流 描述的是從頁面中接受事件的順序。IE的事件流是 事件冒泡流 ,而Netscape的事件流是 事件捕獲流

  1. 事件冒泡,即事件最開始由最具體的元素(文件中巢狀層次最深的那個節點)接收,然後逐級向上轉播至最不 具體的節點(文件)。
  2. 事件捕獲,即事件最開始由不太具體的節點接收,而最具體的節點最後接收到事件。

一、HTML事件處理程式

即在HTML程式碼中新增事件處理程式,如下面程式碼:

<html>
<body>
  <input type="button" value="按鈕" onclick="clickEvent()">
  <script>
    function clickEvent() { alert("HTML事件處理程式"); }
  </script>
</body>
</html>
複製程式碼

缺點: HTML和JavaScript程式碼緊密耦合,如果要更換事件處理程式,就必須改動HTML程式碼和JavaScript程式碼。

二、DOM0級事件處理程式

即在Javascript程式碼中對指定物件新增事件處理程式,如下面程式碼:

<html>
<body>
  <input type="button" value="按鈕">
  <script>
    var btn = document.querySelector("input");
    btn.onclick = function() { alert("DOM0級事件處理程式"); }
  </script>
</body>
</html>
複製程式碼

缺點

  • 不能給一個元素同時新增兩個事件。
  • 不能控制元素的事件流(捕獲或冒泡)。

三、DOM2級事件處理程式

即在Javascript程式碼中對指定物件新增事件處理程式,如下面程式碼:

<html>
<body>
  <input type="button" value="按鈕">
  <script>
    var btn = document.querySelector("input");
    btn.addEventListener("click", clickEvent, false);
    function clickEvent() { alert("DOM2級事件處理程式"); }
  </script>
</body>
</html>
複製程式碼

DOM2級事件定義了兩個方法: 用於處理新增和刪除事件處理程式的操作:

  • addEventListener() —— 新增事件偵聽器
  • removeEventListener() —— 刪除事件偵聽器

它們都接收三個引數:

  1. 監聽事件型別(事件名) —— 使用 "click" ,不要使用 "on" 字首。
  2. 事件觸發時執行的函式。
  3. 表示事件流方式的布林值:false事件控制程式碼在冒泡階段執行(預設);true事件控制程式碼在捕獲階段執行。

注意: DOM2級事件是 W3C DOM 規範中提供的註冊事件監聽器的方法。

注意: Internet Explorer 8 及更早IE版本不支援 addEventListener() 方法,Opera 7.0 及 Opera 更早版本也不支援。

四、IE事件處理程式

  • attachEvent() —— 新增事件
  • detachEvent() —— 刪除事件

它們都接收兩個引數:

  1. 事件名伴隨on —— 使用 "onclick" ,這裡不是事件,而是事件處理程式的名稱,所以有 "on" 字首。
  2. 事件觸發時執行的函式。

注意: 這裡沒有和DOM2級事件處理程式中類似的第三個引數,是因為IE8及更早版本只支援冒泡事件流。

DOM2級事件處理程式和IE事件處理程式 不同點

  1. IE事件處理程式中attachEvent()的事件處理程式的作用域和DOM0與DOM2不同,她的作用域是在全域性作用域中,不同於DOM0和DOM2中this指向元素,IE中的this指向window。
  2. 可以使用attachEvent()來給同一個元素新增多個事件處理程式。但是與DOM2不同,事件觸發的順序不是新增的順序而是新增順序的相反順序。

五、跨瀏覽器的事件處理程式

  • DOM中的事件物件

(1)、type —— 事件型別

(2)、target —— 事件目標

(3)、stopPropagation() —— 阻止事件冒泡

(4)、preventDefault() —— 阻止事件的預設行為

  • IE中的事件物件

(1)、type —— 事件型別

(2)、srcElement —— 事件目標

(3)、cancelBubble=true —— 阻止事件冒泡

(4)、returnValue=false —— 阻止事件的預設行為

為了處理不同瀏覽器對事件處理程式的不同支援,這裡封裝一個相容方法,供有興趣的同學參考:

var eventUtil={
  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;
    }
  },
  getEvent:function(event){// 獲取事件
    return event?event:window.event;
  },
  getType:function(event){//獲取事件型別
    return event.type;
  },
  getElement:function(event){// 獲取事件目標 
    return event.target || event.srcElement;
  },
  stopPropagation:function(event){// 阻止事件冒泡
    if(event.stopPropagation){
      event.stopPropagation();
    }else{
      event.cancelBubble=true;
    }
  },
  preventDefault:function(event){// 阻止事件的預設行為
    if(event.preventDefault){
      event.preventDefault();
    }else{
      event.returnValue=false;
    }
  }
}
複製程式碼

相關文章