事件冒泡與事件捕獲
事件冒泡和事件捕獲分別由微軟和網景公司提出,這兩個概念都是爲了解決頁面中事件流(事件發生順序)的問題。
如下:假設三層div都有事件監聽,這時我們點擊的小的藍方框,事件執行的順序是怎麼樣的呢
<div id="s1" style="height: 400px;width: 400px;border: 1px solid red">紅
<div id="s2" style="height: 200px;width: 200px;border: 1px solid yellow">
黃
<div id="s3" style="height: 100px;width: 100px;border: 1px solid blue">藍</div>
</div>
</div>
事件冒泡
微軟提出了名爲事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻爲把一顆石頭投入水中,泡泡會一直從水底冒出水面。也就是說,事件會從最內層的元素開始發生,一直向上傳播,直到document對象。
因此在事件冒泡的概念下在div元素上發生click事件的順序應該是div -> body -> html -> document
事件捕獲
網景提出另一種事件流名爲事件捕獲(event capturing)。與事件冒泡相反,事件會從最外層開始發生,直到最具體的元素。
因此在事件捕獲的概念下在div元素上發生click事件的順序應該是document -> html -> body -> div -> div
w3c 採用折中的方式,制定了統一的標準——先捕獲再冒泡。
addEventListener第三個參數默認值是false,表示在事件冒泡階段調用事件處理函數;如果參數爲true,則表示在事件捕獲階段調用處理函數。
測試事件冒泡-點擊藍色
s1 = document.getElementById('s1')
s2 = document.getElementById('s2')
s3 = document.getElementById('s3')
s1.addEventListener("click",function(e){
console.log("紅 冒泡事件");//從底層往上
},false);//第三個參數默認值是false,表示在事件冒泡階段調用事件處理函數;如果參數爲true,則表示在事件捕獲階段調用處理函數。
s2.addEventListener("click",function(e){
console.log("黃 冒泡事件");
},false);
s3.addEventListener("click",function(e){
console.log("藍 冒泡事件");
},false);
測試事件捕獲-點擊藍色
s1.addEventListener("click",function(e){
console.log("紅 捕獲事件");
},true);
s2.addEventListener("click",function(e){
console.log("黃 捕獲事件");
},true);
s3.addEventListener("click",function(e){
console.log("藍 捕獲事件");
},true);
事件捕獲與事件冒泡同時存在
- 這裏記被點擊的DOM節點爲target節點
- 對於非target節點則先執行捕獲在執行冒泡
- 對於target節點則是先執行先註冊的事件,無論冒泡還是捕獲
s1.addEventListener("click",function(e){
console.log("紅 冒泡事件");
},false);
s2.addEventListener("click",function(e){
console.log("黃 冒泡事件");
},false);
s3.addEventListener("click",function(e){
console.log("藍 冒泡事件");
},false);
s1.addEventListener("click",function(e){
console.log("紅 捕獲事件");
},true);
s2.addEventListener("click",function(e){
console.log("黃 捕獲事件");
},true);
s3.addEventListener("click",function(e){
console.log("藍 捕獲事件");
},true);