(一) 捕獲和冒泡如何互相影響
我們來做幾個任務吧!
有一個前提,#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
支線任務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
支線任務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
支線任務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
規律
- 從上面的結果得出,父容器的機制确定,子容器的機制不定,結果是确定的,說明父容器影響傳遞;
- 支線任務1-4是點選在子容器上,以子容器作為研究對象;
- 如果父容器為捕獲(true)機制,先觸發本身事件,再到子容器;
- 如果父容器為冒泡(false)機制,先觸發子容器事件,再到本身;結論1
- 在嵌套容器上點選時,點選對象是最外層容器;
- 捕獲機制:本身作為第一個執行參考對象,從本身開始向下傳遞;
- 冒泡機制:從最底層開始向上傳遞,直至到達本身(二)stopPropagation方法,阻止了什麼?
前提:如果有stopPropagation方法,均放在console方法後面;
有一個假設:
- 因為stopPropagation是在console後面執行,是以無論何種情況至少出現一個結果;
- 有4種政策(true + stopPropagation)、(false + stopPropagation)、(true)、(false),也就是說父容器和子容器的排序有16種;
- 因為假設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的所有結果,是以不再列舉了,來總結一下!
這裡進行了[parent,child]、[child,parent]、[parent]、[child] 4種結果,但沒有枚舉,其餘12種排序自己撸一遍,可以更深入了解事件機制背後的原理!
總結
- 通過click事件可以推論,事件的觸發均從最外層觸發(document、html);
- 事件的執行是先通過機制再通過回調執行;
- 冒泡機制:從最底層開始向上傳遞,直至到達本身;
- stopPropagation方法不是大家說的阻止冒泡,而是阻止傳遞(捕獲 + 冒泡);
轉自:https://zhuanlan.zhihu.com/p/24159132