JavaScript 事件——「事件流和事件處理程序」的注意要點

事件流

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

事件冒泡

即事件開始時由最具體的元素接收,而後逐級向上傳播到較爲不具體的節點。如:瀏覽器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>Click</div>
</body>
</html>

當點擊了頁面中的div元素,那麼這個click事件會按照以下順序傳播:函數

  1. div元素this

  2. body元素code

  3. html元素htm

  4. document對象對象

事件捕獲

事件捕獲的思想是最具體的節點應該最後接收到事件。事件捕獲的用意在於事件到達目標以前捕獲它。事件

當點擊了頁面中的div元素,那麼這個click事件則會按照以下順序傳播:ip

  1. document對象作用域

  2. html標籤

  3. body標籤

  4. div標籤

雖然規範要求事件應該從document對象開始傳播,但瀏覽器通常都是從window對象開始捕獲事件的。由於老版本瀏覽器不支持,因此通常都使用事件冒泡。

DOM事件流

「DOM2級事件」規定的事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。

在DOM事件流中,實際的目標在捕獲階段不會接收事件。就是說在捕獲階段,事件從document到html再到body後就中止了。下一個階段是「處於目標」階段,因而事件在div中發生,並在事件處理中被當作是冒泡階段的一部分。而後,冒泡階段發生。IE8及更早的版本不支持DOM事件流,瀏覽器在捕獲階段觸發事件對象上的事件,結果就是有兩個機會在目標對象上面操做事件。

事件處理程序

事件就是用戶或瀏覽器自身執行的某種動做;事件處理程序(或事件偵聽器)就是響應某個事件的函數。事件處理程序的名字以「on」開頭,如onload、onclick等。

HTML事件處理程序

若要在按鈕被單擊時執行一些js代碼,能夠這樣編寫:

<div onclick="alert('Clicked')">Click</div>

注意:不能在其中使用未經轉義的HTML語法字符。

也能夠調用在頁面中其餘地方定義的腳本:

<script>
    function showMessage () {
        document.write("fdas");
    }
</script>
<input type="button" value="Click Me" onclick="showMessage()" />

事件處理程序中的代碼在執行時,有權訪問全局做用域中的任何代碼。

這樣使用會建立一個封裝着的元素屬性值的函數。這個函數有一個局部變量event,也就是事件對象:

<input type="button" value="Click Me" onclick="alert(event.type)" />

其中,this值等於事件的目標元素,如:

<input type="button" value="Click Me" onclick="alert(this.value)" />

HTML事件處理程序存在衆多問題,因此應該使用js指定的事件處理程序

DOM0級事件處理程序

要使用js指定事件處理程序,首先必須取得一個要操做的對象的引用。

每一個元素都有本身的事件處理程序屬性,這些屬性一般所有小寫,如onclick。如:

<input type="button" value="Click Me" id="btn" />
<script>
document.querySelector("#btn").onclick = function() {
    console.log("hello");
}
</script>

使用DOM0級方法指定的事件處理程序被認爲是元素的方法。所以,這時候的事件處理程序是在元素的做用域中運行的;也就是this引用當前元素:

<input type="button" value="Click Me" id="btn" />
<script>
document.querySelector("#btn").onclick = function() {
    console.log(this.type);
}
</script>

以上述這種方式添加的事件處理程序會在事件流的冒泡階段被處理。

刪除經過DOM0級方法指定的事件處理程序:

btn.onclick = null;

DOM2級事件處理程序

addEventListener()

該方法接收三個參數:要處理的事件名、事件處理程序函數和布爾值;布爾值若是是true,表示在捕獲階段調用事件處理程序;若是是false,表示在冒泡階段調用事件處理程序。如:

var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
    console.log(this.id);
})

還能夠爲該按鈕添加多個事件處理程序,如:

var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
    console.log(this.id);
})
btn.addEventListener("click", function () {
    console.log(this.value);
})

removeEventListener()

var btn = document.getElementById("btn");
function info () {
    console.log(this.value);
}
btn.addEventListener("click", info);
btn.addEventListener("click", function () {
    console.log(this.id);
});
btn.addEventListener("click", function valueAndId () {
    console.log(this.value + " " + this.id);
});
btn.removeEventListener("click", info); //有效
btn.removeEventListener("click", function () {
    console.log(this.id);
}); //無效
btn.removeEventListener("click", valueAndId); //報錯無效

大多數狀況下,都是將事件處理程序添加到事件流的冒泡階段,這樣就能夠最大限度地兼容各類瀏覽器。

相關文章
相關標籤/搜索