JS 冒泡和捕獲是怎麼回事

JS 冒泡和捕獲是怎麼回事

看網上說的也不是太明白,我給從新整理下。 參閱: https://www.cnblogs.com/alvin...

冒泡和捕獲是指在元素上的事件被觸發的時候,js 傳遞事件的兩種方向,或者說過程。css


前言:

如,有這麼一個頁面 和 js 方法html

clipboard.png

Less: 我用 less寫的,若是沒有 less 環境,能夠無視這段。
.level {
  padding: 50px 80px;
}

.level-template(@level: 1, @color: #fff){
  background-color: darken( @color , 5% * @level);
}

#lv1{ .level-template(1)}
#lv2{ .level-template(2)}
#lv3{ .level-template(3)}
#lv4{ .level-template(4)}
HTML
<div id="lv1" class="level">
    <div id="lv2" class="level">
        <div id="lv3" class="level">
            <div id="lv4" class="level">

            </div>
        </div>
    </div>
</div>
JS
function $(id) {
    return document.getElementById(id);
}

window.onload = () => {
    $('lv1').addEventListener("click",()=>{console.log('lv1')},true);
    $('lv2').addEventListener("click",()=>{console.log('lv2')},true);
    $('lv3').addEventListener("click",()=>{console.log('lv3')},true);
};
// 上面的 () => {} 爲 ES6 的匿名方法的定義方式
// 等同於
function () {
    console.log('lv1')
}

上面的 js 作的事:
在頁面載入的時候,給三個 div 添加 click 監聽方法,本身被點擊的時候會在 console 中輸出本身的 id 值。less

頁面的結構是這樣的 lv1 包含 lv2lv2 又包含 lv3,當點擊 lv3 的時候,其實也點擊了 lv2lv1,由於 lv3lv2 內部,點擊 lv3 的時候,天然也點擊了 lv2lv1,也就是說,點擊 lv3 的時候,會觸發三個 click 事件。
至於這三個事件觸發的順序,就是所謂的 冒泡捕獲spa


事件觸發通過的三個階段:

  1. 捕獲階段:先由文檔的根節點 document 往事件觸發對象,從外向內捕獲事件對象;
  2. 定位目標:尋找到目標事件位置(事發地),觸發事件;
  3. 冒泡階段:再從目標事件位置往文檔的根節點方向回溯,從內向外冒泡事件對象。

1. 捕獲階段

如上面的例子,在 lv3 被點擊的時候,js 會從文檔的最上層開始,由外向內尋找點擊事件的起源,也就是 lv3。那麼這個由外向內的過程就是 lv1 --> lv2 --> lv3,這三個 div 的 click 事件按照這個過程依次被觸發。
這個觸發的方向就是捕獲的方向。code

2. 冒泡階段

在找到被點擊的 lv3 以後,事件向上傳遞,過程是 lv3 --> lv2 --> lv1,此時依次觸發 lv3lv2lv1click 事件,這個由內向外的觸發過程就稱爲冒泡htm


再回看一下最經常使用的事件綁定方法的格式:

element.addEventListener(event, function, useCapture)

這裏面,useCapture 是個布爾值,用於定義事件是在冒泡階段觸發,仍是在捕獲階段觸發,默認值是 false,表明在冒泡時觸發。對象


此時你就會知道上面那個例子裏定義的 click 方法是在 捕獲階段 執行,那麼返回的結果就是blog

lv1
lv2
lv3

若是最上面的例子,onload 內容是這樣的事件

window.onload = () => {
        $('lv1').addEventListener("click",()=>{console.log('lv1')},false);
        $('lv2').addEventListener("click",()=>{console.log('lv2')},false);
        $('lv3').addEventListener("click",()=>{console.log('lv3')},false);
    };

那麼也就是說, click 事件在 冒泡階段觸發,返回的結果就是ip

lv3
lv2
lv1

總結

冒泡和捕獲的關係,只會出如今包含和被包含的結構中,兄弟關係是不會有這種關係的。冒泡和捕獲只是方向的不一樣而已。

相關文章
相關標籤/搜索