跨瀏覽器的javascript事件和對象的封裝

跨瀏覽器的事件處理程序

DOM0級處理事件

將一個函數賦值給一個事件處理程序屬性javascript

事件流: 冒泡階段java

使用:瀏覽器

一、爲元素增長事件:bash

let btn = document.getElementById("myBtn");
btn.onclick = function(){
  alert(this.id);
}
複製代碼

二、刪除事件:函數

let btn = document.getElementById("myBtn");
btn.onclick = null;
複製代碼

DOM2級事件處理程序

兩個方法: addEventListener()removeEventListener()ui

三個參數: 處理事件名,事件處理程序,布爾值。(最後的布爾值爲true,表示在捕獲階段調用事件處理程序;爲false,表示在冒泡調用事件處理程序)this

使用:spa

一、爲元素增長事件:設計

let btn = document.getElementById("myBtn");
let handler = function(){
    alert(this.id);
}
btn.addEventListener('click',handler,false);
複製代碼

二、刪除事件:code

btn.removeEventListener('click',handler,false);
複製代碼

注意:

1),addEventListener()添加的匿名函數將沒法移除;

2),大多數狀況下,都是將事件處理程序添加到事件流的冒泡階段(即第三個參數爲false);

3),若是添加了多個事件處理程序,會按照添加它們的順序觸發。

IE事件處理程序

兩個方法: attachEvent(),detachEvent()

兩個參數: 事件處理程序名稱,事件處理程序函數

事件流: 冒泡階段

使用:

一、爲元素增長事件:

let btn = document.getElementById("myBtn");
let handler = function(){
    alert(this.id);
}
btn.attachEvent('onclick',handler)
複製代碼

二、刪除事件:

btn.detachEvent('onclick',handler);
複製代碼

注意: 與DOM方法不一樣的是,這些事件處理程序不是以添加它們的順序執行,而是以相反的順序被觸發。

跨瀏覽器的事件處理程序

爲了以跨瀏覽器的方式處理事件,保證處理事件的代碼能在大多數瀏覽器下一致運行,建立本身的對象,包含上面兩個方法。

let EventUnit = {
  addHandle: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;
    }
  }
};
複製代碼

用法:

let btn = document.getElementById('myBtn');
let handler = function(){
  alert(this.id);
};
EventUnit.addHandle(btn,'click',handler);
EventUnit.removeHandler(btn,'click',handler);
複製代碼

事件對象

在觸發DOM上的某個事件時,會產生一個事件對象,這個對象包含着全部與事件有關的信息。

DOM中的事件對象(DOM0級和DOM2級)

  • 兼容DOM的瀏覽器會將一個event對象傳入到事件處理程序

    let btn = document.getElementById("myBtn");
    btn.onclick = function(event){
      alert(event.type);//'click'
    };
    btn.addEventListener('click',function(event){
      alert(event.type);//'click'
    }.false);
    複製代碼
  • event對象包含與建立它的特定事件有關的屬性和方法

    屬性/方法 用法
    bubbles(Boolean) 代表事件是否冒泡
    cancelabel(Boolean) 代表是否能夠取消事件的默認行爲
    currentTarget(Element) 其事件處理程序當前正在處理事件的那個元素
    defaultPrevented(Boolean) 爲true表示已經調用preventDefault()
    detail(Integer) 與事件相關的細節信息
    eventPhase(Integer) 調用事件處理程序的階段:1表示捕獲階段,2表示「處於目標」,3表示冒泡階段
    preventDefault()(Function) 取消事件的默認行爲。若是cancelabel是true則可使用這個方法
    stopImmediatePropagation()(Function) 取消事件的進一步捕獲或冒泡,同時阻止任何事件處理程序被調用
    stopPropagation()(Function) 取消事件的進一步捕獲或冒泡。若是bubbles爲true,則可使用這個方法
    target(Element) 事件的目標
    trusted(Boolean) 爲true表示事件是瀏覽器生成,爲false表示事件是由開發人員經過javascript建立的
    type(String) 被觸發的事件類型
    view(AbstractView) 與事件關聯的抽象視圖。等同於發生事件的window對象
  • 比較經常使用的屬性和方法

    1)、事件處理內部,對象this始終等於currentTarget的值,而target則只包含事件的實際目標。

    2)、經過檢測event.type屬性,可讓函數肯定發生了什麼事件,並執行相應的操做。(如:click,mouseover,mouseout)

    3)、阻止特定事件的默認行爲,能夠用preventDefault方法。但須要注意的是,只有cancelabel屬性設置爲true的事件,纔可使用preventDefault()來取消其默認行爲。

    4)、stopPropagation()方法用於當即中止事件在DOM層次中的傳播,即取消進一步的事件捕獲或冒泡。(如:直接添加到一個按鈕的事件處理程序能夠調用stopPargation(),從而避免觸發註冊在document.body上面的事件處理程序)

備註: 只有在事件處理程序執行期間,event對象纔會存在;一旦事件處理程序執行完成,event對象就會被銷燬。

IE中的事件對象

  • 有如下兩種狀況:

    第一種:在使用DOM0級方法添加事件處理程序時,event對象做爲window對象的一個屬性存在。

    let btn = document.getElementById("myBtn");
    btn.onclick = function(){
      let  event = window.event;
      alert(event.type);//'click'
    };
    複製代碼

    第二種:若是事件處理程序是使用attachEvent()添加的,那麼就會有一個event對象做爲參數被傳入事件處理程序函數中。在使用attachEvent()的狀況下,也能夠經過window對象來訪問event對象

    let btn = document.getElementById('myBtn');
    btn.attachEvent("onclick",function(event){
      alert(event.type);//"click
    });
    複製代碼
  • IE的event對象一樣也包含與建立它的事件相關的屬性和方法

    屬性/方法 用法
    canceBubble(Boolean) 默認爲false,但將其設置爲true就能夠取消事件冒泡(與DOM中的stopPropagation()方法相同)
    returnValue(Boolean) 默認爲true,但將其設置爲false就能夠取消事件的默認行爲(與DOM中的preventDefault()方法相同)
    srcElement(Element) 事件的目標(與DOM中的traget屬性相同)
    type(String) 被觸發的事件的類型

跨瀏覽器的事件和對象的封裝

把上面的EventUnit封裝在js文件中,對該文件進行引用,就可使用裏面的方法進行瀏覽器的兼容

let EventUnit = {
  addHandle: 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;
  },
  getTarget: 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.canceBubble = true;
    }
  }
};
複製代碼

參考: 《Javascript高級程序設計》第3版的第13章:事件

相關文章
相關標籤/搜索