JS的事件冒泡和事件捕獲
阿新 • • 發佈:2020-08-03
DOM事件流三個階段
1.事件捕獲:當滑鼠觸發DOM事件時,瀏覽器會從根節點由外到內進行事件傳播。即觸發子元素的事件,父元素會通過事件捕獲的方式優先觸發父元素的事件。
2.目標階段:正在處理事件。
3.事件冒泡:與事件捕獲相反,瀏覽器會從子節點由內到外進行事件傳播。
DOM事件流處理順序:先捕獲,再冒泡。
具體區別
通常在addEventListener方法的第三個引數中設定true則為事件捕獲,false則為事件冒泡,預設為false。
html程式碼:
<div id="div1"> <div id="div2"> </div> </div>
css程式碼:
<style> #div1 { width: 500px; height: 500px; border: 1px solid #ffffff; background: blanchedalmond; } #div2 { width: 200px; height: 200px; border: 1px solid #ffffff; background: blue; } </style>
js程式碼:
<script> letdiv1=document.getElementById("div1"); letdiv2=document.getElementById("div2"); div1.addEventListener('click',function(){ console.log('div1--捕獲'); },true); div2.addEventListener('click',function(){ console.log('div2--捕獲'); },true); div1.addEventListener('click',function(){ console.log('div1--冒泡'); }); div2.addEventListener('click',function(){ console.log('div2--冒泡'); }); </script>點選div2打印出的結果:
由此可證上述結論即:捕獲先於冒泡;對於捕獲而言,外層先於內層(div1先於div2列印);對於冒泡而言,內層先於外層(div2先於div1列印)。
而我們期望的其實是對於冒泡事件,希望點選div2時僅僅只打印出div2--冒泡,修改js為:
<script> let div1 = document.getElementById("div1"); let div2 = document.getElementById("div2"); div1.addEventListener('click', function (e) { console.log('div1--冒泡'); }); div2.addEventListener('click', function (e) { console.log('div2--冒泡'); e.stopPropagation(); }); </script>
此時點選div2列印的結果:
相容問題
IE瀏覽器9以下不支援e.stopPropagation();來取消冒泡事件,在IE瀏覽器10版本以上中已經解決該問題:
為了更好的相容各個瀏覽器版本,對e.stopPropagation()事件進行一個判斷:
<script> let div1 = document.getElementById("div1"); let div2 = document.getElementById("div2"); div1.addEventListener('click', function (e) { console.log('div1--冒泡'); }); div2.addEventListener('click', function (e) { console.log('div2--冒泡'); stopBubble(); }); function stopBubble (e) { if (e && e.stopPropagation) { e.stopPropagation(); } else { window.event.cancelBubble = true; } } </script>