天天看點

【JavaScript】attachEvent 與addEventListener差別

attachEvent 與addEventListener到底有什麼差別呢?總結如下:

一、适應的浏覽器版本不同

attachEvent方法适用于IE    addEventListener方法适用于FF

二、針對的事件不同

attachEvent中的事件帶on   而addEventListener中的事件不帶on

三、參數的個數不同

attachEvent方法兩個參數:第一個參數為事件名稱,第二個參數為接收事件處理的函數; addEventListener 有三個參數:第一個參數表示事件名稱(不含 on,如 "click");第二個參數表示要接收事件處理的函數;第三個參數是一個bool值,一般為false

第三個參數叫做useCapture,是一個boolean值,就是true or false,如果送出true的話就是瀏覽器會使用Capture方式,false的話是Bubbling,隻有在特定狀況下才會有影響,通常建議是false,而會有影響的情形是目标元素(target element)有祖先元素(ancestor element),而且也有同樣的事件對應函數,我想,看圖會比較清楚。

【JavaScript】attachEvent 與addEventListener差別

像這張圖所顯示的,我的範例有兩層div元素,而且都設定有click事件,一般來說,如果我在内層藍色的元素上click不隻會觸發藍色元素的click事件,還會同時觸發紅色元素的click事件,而useCapture這個參數就是在控制這時候兩個click事件的先後順序。如果是false,那就會使用bubbling,他是從内而外的流程,是以會先執行藍色元素的click事件再執行紅色元素的click事件,如果是true,那就是capture,和bubbling相反是由外而内,會先執行紅色元素的click事件才執行藍色元素的click事件。附上兩個範例,capture和bubbling,兩個檔案隻有差在此一參數不同,可以發現事件的發生順序不一樣了。

那如果不同層的元素使用的useCapture不同呢?就是會先從最外層元素往目标元素尋找設定為capture的事件,到達目标元素執行目标元素的事件後,再尋原路往外尋找設定為bubbling的事件。

四、執行事件的優先級不同

<div id="outDiv">

   <div id="middleDiv">

     <div id="inDiv">請在此點選滑鼠。</div>

   </div>

</div>

<div id="info"></div>

var outDiv = document.getElementById("outDiv");

var middleDiv = document.getElementById("middleDiv");

var inDiv = document.getElementById("inDiv");

var info = document.getElementById("info");

outDiv.addEventListener("click", function () { info.innerHTML += "outDiv" + "<br>"; }, false);

middleDiv.addEventListener("click", function () { info.innerHTML += "middleDiv" + "<br>"; }, false);

inDiv.addEventListener("click", function () { info.innerHTML += "inDiv" + "<br>"; }, false);

上述是我們測試的代碼,根據 info 的顯示來确定觸發的順序,有三個 addEventListener,而 useCapture 可選值為 true 和 false,是以 2*2*2,可以得出 8 段不同的程式。

全為 false 時,觸發順序為:inDiv、middleDiv、outDiv;

全為 true 時,觸發順序為:outDiv、middleDiv、inDiv;

outDiv 為 true,其他為 false 時,觸發順序為:outDiv、inDiv、middleDiv;

middleDiv 為 true,其他為 false 時,觸發順序為:middleDiv、inDiv、outDiv;

……

最終得出如下結論:

true 的觸發順序總是在 false 之前;

如果多個均為 true,則外層的觸發先于内層;

如果多個均為 false,則内層的觸發先于外層。

下面提供全部代碼,您可以更改其中的 true、false 值,來進行測試。注意,不适用于 IE

五、對this的引用不同

attachEvent綁定的函數,沒有綁定this引用

function doIt(){   

    alert(this);   

}  

然後我們在頁面中處理如下:

首先做一個按鈕:<button id="btn">按鈕</button>,然後為該按鈕綁定事件onclick如下:

<script language="javascript" type="text/javascript">   

document.getElementById("btn4").attachEvent("onclick",doIt);   

</script>  

經過這種處理之後,doIt方法中的this不代表button,但是使用

      document.getElementById("btn4").onclick = doIt時this指向的就是btn代表的button了,

     還有就是

      document.getElementById("btn4").addEventListener('click',doSomething,false);這樣也可以把this綁定進去

最後寫一個相容所有浏覽器的監聽事件方法如下:

//相容所有浏覽器的attachEvent方法

if(!window.attachEvent && window.addEventListener)

{

Window.prototype.attachEvent = HTMLDocument.prototype.attachEvent=

HTMLElement.prototype.attachEvent=function(en, func, cancelBubble)

var cb = cancelBubble ? true : false;

this.addEventListener(en.toLowerCase().substr(2), func, cb);

};

}

繼續閱讀