說說 JavaScript 中的冒泡與捕獲過程

W3C 規範中定義了3個事件階段,依次是捕獲階段 、 目標階段 、 冒泡階段。先捕獲,後冒泡,捕獲從上到下,就像石沉大海;而冒泡從下到上就像氣泡冒出水面。

先看個示例:

html 頁面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>冒泡與捕獲</title>

</head>
<body style="border: blueviolet 3px solid">
<table style="border: saddlebrown 3px solid">
    <tbody>
    <tr>
        <td>美杉</td>
        <td>祿銘</td>
    </tr>
    <tr id="secondTr">
        <td id="firstTd" style="border: olivedrab 3px solid">彥芸</td>
        <td>陽騫</td>
    </tr>
    </tbody>
</table>
<script type="text/javascript" src="captureAndBubble2.js"></script>
</body>
</html>

js :

/*
 * 冒泡與捕獲
 * @author Deniro Lee
 */

let html = document.documentElement;
let body = document.body;
let table = body.querySelector('table');
let tbody = body.querySelector('tbody');
let secondTr = body.querySelector('#secondTr');
let firstTd = body.querySelector('#firstTd');

/**
 * 冒泡回調
 * @param event
 */
function bubbleCallback(event) {
    let target = event.currentTarget;
    console.log('bubble -> ' + target.tagName);
}

/**
 * 捕獲回調
 * @param event
 */
function captureCallback(event) {
    let target = event.currentTarget;
    console.log('capture -> ' + target.tagName);
}



html.addEventListener('click', captureCallback, true);
body.addEventListener('click', captureCallback, true);
table.addEventListener('click', captureCallback, true);
tbody.addEventListener('click', captureCallback, true);
secondTr.addEventListener('click', captureCallback, true);
firstTd.addEventListener('click', captureCallback, true);

html.addEventListener('click', bubbleCallback, false);
body.addEventListener('click', bubbleCallback, false);
table.addEventListener('click', bubbleCallback, false);
tbody.addEventListener('click', bubbleCallback, false);
secondTr.addEventListener('click', bubbleCallback, false);
firstTd.addEventListener('click', bubbleCallback, false);

在瀏覽器中運行以上頁面,點擊“彥芸”後,在 Console 中會看到冒泡與捕獲的過程運行結果:

點擊事件對象會按照圖 1 的傳播路徑依次完成捕獲、目標與冒泡階段。如果某個階段不支持或事件對象的傳播被終止,那麼該階段就會被跳過。

代碼中使用了addEventListener() 方法來跟蹤捕獲與冒泡階段事件。該方法的語法爲:

element.addEventListener(event, function, useCapture)
參數 描述
event 必須。字符串,指定事件名。注意: 不要使用 “on” 前綴。 例如,使用 “click” ,而不是使用 “onclick”。
function 必須。指定要事件觸發時執行的函數。 當事件對象會作爲第一個參數傳入函數。 事件對象的類型取決於特定的事件。例如, “click” 事件屬於 MouseEvent(鼠標事件) 對象。
useCapture 可選。布爾值,指定事件是否在捕獲或冒泡階段執行。可能值: true - 事件句柄會在捕獲階段執行; false- 默認值,事件句柄會在冒泡階段執行。

之前定義的腳本,我們使用 addEventListener() 方法先綁定捕獲方法,後綁定冒泡方法;如果我們交換下順序,先綁定冒泡然後再捕獲會怎樣?

html.addEventListener('click', bubbleCallback, false);
body.addEventListener('click', bubbleCallback, false);
table.addEventListener('click', bubbleCallback, false);
tbody.addEventListener('click', bubbleCallback, false);
secondTr.addEventListener('click', bubbleCallback, false);
firstTd.addEventListener('click', bubbleCallback, false);

html.addEventListener('click', captureCallback, true);
body.addEventListener('click', captureCallback, true);
table.addEventListener('click', captureCallback, true);
tbody.addEventListener('click', captureCallback, true);
secondTr.addEventListener('click', captureCallback, true);
firstTd.addEventListener('click', captureCallback, true);

運行結果:

可以發現目標元素的冒泡事件先於捕獲事件執行,其它元素順序不變。也就是說,綁定順序隻影響到目標元素的事件發生順序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章