天天看點

JS 什麼是 冒泡 和 捕獲 capture pop

JS 冒泡和捕獲是怎麼回事 capture pop

看網上說的也不是太明白,我給重新整理下。

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

前言:

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

JS 什麼是 冒泡 和 捕獲 capture pop
scss: 我用 scss 寫的,如果沒有 scss 環境,可以無視這段。
.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)}      
HTML
<div id="lv1" class="level">
    <div id="lv2" class="level">
        <div id="lv3" class="level">
        
        </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 值。

頁面的結構是這樣的 ​

​lv1​

​​ 包含​

​lv2​

​​,​

​lv2​

​​ 又包含 ​

​lv3​

​​,當點選 ​

​lv3​

​​ 的時候,其實也點選了​

​lv2​

​​ 和 ​

​lv1​

​​,因為 ​

​lv3​

​​ 在 ​

​lv2​

​​ 内部,點選 ​

​lv3​

​​ 的時候,自然也點選了 ​

​lv2​

​​ 和 ​

​lv1​

​​,也就是說,點選 ​

​lv3​

​​ 的時候,會觸發三個 ​

​click​

​​ 事件。

至于這三個事件觸發的順序,就是所謂的 ​​

​冒泡​

​​ 和 ​

​捕獲​

​。

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

  1. 捕獲階段:先由文檔的根節點​

    ​document​

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

1. 捕獲階段

如上面的例子,在 ​

​lv3​

​​ 被點選的時候,js 會從文檔的最上層開始,由外向内尋找點選事件的起源,也就是 ​

​lv3​

​​。那麼這個由外向内的過程就是 ​

​lv1​

​​ --> ​

​lv2​

​​ --> ​

​lv3​

​​,這三個 div 的 click 事件按照這個過程依次被觸發。

這個觸發的方向就是​​

​捕獲​

​的方向。

2. 冒泡階段

在找到被點選的 lv3 之後,事件向上傳遞,過程是 ​

​lv3​

​​ --> ​

​lv2​

​​ --> ​

​lv1​

​​,此時依次觸發 ​

​lv3​

​​、​

​lv2​

​​、​

​lv1​

​​ 的 ​

​click​

​​ 事件,這個由内向外的觸發過程就稱為​

​冒泡​

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

element.addEventListener(event, function, useCapture)      

這裡面,​

​useCapture​

​​ 是個布爾值,用于定義事件是在​

​冒泡階段​

​​觸發,還是在​

​捕獲階段​

​​觸發,預設值是 ​

​false​

​,代表在冒泡時觸發。

此時你就會知道上面那個例子裡定義的 click 方法是在 ​

​捕獲階段​

​ 執行,那麼傳回的結果就是

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​

​​ 事件在 ​

​冒泡階段​

​觸發,傳回的結果就是

lv3
lv2
lv1      

vue 中對事件傳遞方向的控制

總結