天天看點

W3C标準冒泡、捕獲機制

(一) 捕獲和冒泡如何互相影響

我們來做幾個任務吧!

有一個前提,#parent為标簽,#child為子标簽,他們是嵌套關系支線任務1

//捕獲模式
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent');
}, true);

//捕獲模式
document.getElementById('child').addEventListener('click', function(e) {
    console.log('child');
}, true);
           
結果:
1. parent
2. child
           
W3C标準冒泡、捕獲機制

支線任務2

//捕獲模式
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent');
}, true);

//冒泡模式
document.getElementById('child').addEventListener('click', function(e) {
    console.log('child');
}, false);
           
結果:
1. parent
2. child
           
W3C标準冒泡、捕獲機制

支線任務3

//冒泡模式
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent');
}, false);

//捕獲模式
document.getElementById('child').addEventListener('click', function(e) {
    console.log('child');
}, true);
           
結果:
1. child
2. parent
           
W3C标準冒泡、捕獲機制

支線任務4

//冒泡模式
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent');
}, false);

//冒泡模式
document.getElementById('child').addEventListener('click', function(e) {
    console.log('child');
}, false);
           
結果:
1. child
2. parent
           
W3C标準冒泡、捕獲機制

規律

W3C标準冒泡、捕獲機制
    • 從上面的結果得出,父容器的機制确定,子容器的機制不定,結果是确定的,說明父容器影響傳遞;
    • 支線任務1-4是點選在子容器上,以子容器作為研究對象;
      1. 如果父容器為捕獲(true)機制,先觸發本身事件,再到子容器;
      2. 如果父容器為冒泡(false)機制,先觸發子容器事件,再到本身;結論1
  • 在嵌套容器上點選時,點選對象是最外層容器;
  • 捕獲機制:本身作為第一個執行參考對象,從本身開始向下傳遞;
  • 冒泡機制:從最底層開始向上傳遞,直至到達本身(二)stopPropagation方法,阻止了什麼?

前提:如果有stopPropagation方法,均放在console方法後面;

有一個假設:

  1. 因為stopPropagation是在console後面執行,是以無論何種情況至少出現一個結果;
  2. 有4種政策(true + stopPropagation)、(false + stopPropagation)、(true)、(false),也就是說父容器和子容器的排序有16種;
  3. 因為假設1,是以結果應該(不确定)有4個分别是(parent、child)、(child、parent)、(parent)、(child);

我們帶着這些假設來做任務。

支線任務5

//捕獲模式
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent')
    e.stopPropagation();
}, true);

//捕獲模式
document.getElementById('child').addEventListener('click', function(e) {
    console.log('child')
}, true);
           
結果:
1. parent
           

這個結果說明,stopPropagation方法會阻止傳遞,無法傳達到子節點上。

是以stopPropagation不是傳聞的阻止冒泡方法,而是阻止傳遞的方法;支線任務6

支線任務6

//冒泡模式
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent')
    e.stopPropagation();
}, false);

//捕獲模式
document.getElementById('child').addEventListener('click', function(e) {
    console.log('child')
}, true);
           
結果:
1. child
2. parent
           
按照上面的知識儲備,再次論證了結論1

支線任務7

//冒泡模式
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent');
}, false);

//捕獲模式
document.getElementById('child').addEventListener('click', function(e) {
    e.stopPropagation();
    console.log('child');
}, true);
           
結果:
1. child
           
子容器觸發了e.stopPropagation(),導緻冒泡鍊斷裂,不再向上冒泡,是以#parent沒有被觸發!

支線任務8

//捕獲
document.getElementById('parent').addEventListener('click', function(e) {
    console.log('parent');
}, true);

//冒泡
document.getElementById('child').addEventListener('click', function(e) {
    console.log('child');
    e.stopPropagation();
}, false);
           
結果:
1. parent
2. child
           

因為得到了假設2的所有結果,是以不再列舉了,來總結一下!

W3C标準冒泡、捕獲機制

這裡進行了[parent,child]、[child,parent]、[parent]、[child] 4種結果,但沒有枚舉,其餘12種排序自己撸一遍,可以更深入了解事件機制背後的原理!

總結

    1. 通過click事件可以推論,事件的觸發均從最外層觸發(document、html);
    2. 事件的執行是先通過機制再通過回調執行;
    3. 冒泡機制:從最底層開始向上傳遞,直至到達本身;
    4. stopPropagation方法不是大家說的阻止冒泡,而是阻止傳遞(捕獲 + 冒泡);

轉自:https://zhuanlan.zhihu.com/p/24159132