1. 程式人生 > >JavaScript事件模型

JavaScript事件模型

事件模型是JS裡十分重要的一個部分,這兩天查詢了一些相關資料,用自己的文字記錄一下。本文不討論IE。

事件模型 DOM事件模型

最簡單且相容所有瀏覽器的事件模型,有兩種方式。預設發生在冒泡階段。

HTML中直接繫結(不推薦)

<button id="button" onclick="click()">ClickMe</button>

JS指定屬性值

var button = document.getElementById("button")
button.onclick = function() {
    //...
}

DOM 2級模型 屬於W3C標準模型,先事件捕獲,到達目標後再進行冒泡。相容現代瀏覽器。

//DOM 2級事件第三個引數是一個布林值(預設為false),true表示捕獲階段呼叫事件處理程式,false表示冒泡階段呼叫事件處理程式。
var button = document.getElementById("button")
button.addEventListener('click', function() {
    //...
}, false)

事件物件 觸發DOM上的事件後,會產生一個事件物件event,作為引數傳給監聽函式。所有的事件都是這個事件物件的示例。

事件物件常用屬性 type 被觸發的事件的型別 target 事件的目標 currentTarget 註冊這個事件監聽的物件 事件物件常用方法 preventDefault() 取消事件的預設行為 stopPropagation() 阻止事件繼續傳播(冒泡和捕獲),不包括在當前節點上其他的事件監聽函式。 stopImmediatePropagation() 阻止所有事件繼續傳播,包括在當前節點上其他的事件監聽函式。

<body>
	<div id="pop-up-window"></div>
</body>

<script>
	    var body = document.querySelector('body')
        var popUpWindow = document.getElementById('pop-up-window')
        
        body.addEventListener('click', function(e) {
            popUpWindow.style.display = 'none'
        }, false)
        popUpWindow.addEventListener('click', function(e) {
            e.stopPropagation() //在彈窗內部點選時阻止事件傳播,因此不會觸發body的click事件
        }, false)
</script>

事件委託 藉助事件冒泡和事件物件,可以實現事件委託(又叫事件代理)。

先思考如何給下面的按鈕都繫結一個click事件,點選後輸出按鈕的id

    <div id="contiainer">
        <button id="button1">button1</button>
        <button id="button2">button2</button>
        <button id="button3">button3</button>
        <!-- ... -->
        <button id="button10">button10</button>
    </div>

或許你或你以前會這麼寫

        for (var i = 1; i <= 10; i++) {
            document.getElementById("button" + i).addEventListener('click', function(e) {
                console.log(e.target.id)
            }, false)
        }

每個函式都是物件,都會佔用記憶體,現在建立了10個監聽事件,影響了頁面效能。我們利用事件委託(又叫事件代理)可以解決這個問題。事件委託藉助事件冒泡和事件物件,只需要建立一個監聽器,就可以管理一個型別的所有事件。只需要在DOM樹儘量最高的層次建立一個監聽。

document.getElementById('container').addEventListener('click', function(e) {
           if (e.target.tagName.toLowerCase() === 'button') console.log(e.target.id)
       }, false)