在JS中,綁定的事件預設的執行時間是在冒泡階段執行,而不是在捕捉階段。這也是為什麼當父類別和子類別都綁定了某個事件,會先呼叫子類別綁定的事件,然後再呼叫父類別的事件。直接看下面實例
<!Doctype html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> *{margin:0;padding: 0;} </style> </head> <body> <p id="id1" style="height:400px; background-color:blue; border:1px solid #000;"> <p id="id2" style="height:200px; background-color:yellow; border:1px solid #000;"> <p id="id3" style="height:50px; background-color:red; border:1px solid #000;"></p> </p> </p> </body> <script type="text/javascript"> var obj1=document.getElementById('id1'); obj1.addEventListener('click',function(){ alert('id1'); },false); var obj2=document.getElementById('id2'); obj2.addEventListener('click',function(){ alert('id2'); },true); var obj3=document.getElementById('id3'); obj3.addEventListener('click',function(){ alert('id3'); },true); /*如果第三个参数为true,则事件在捕获阶段执行,如果第三个参数为false,则事件在冒泡阶段执行*/ </script> </html>
當點擊id3元素時候,執行結果是:id2,id3,id1
解析:因為obj2綁定的方法在,捕獲階段執行,obj1與obj3綁定的事件在冒泡階段執行。
JS在預設取得事件後,就開始從根元素開始捕捉所有該事件的監聽對象,然後在冒泡階段逐一執行。我們可以透過綁定事件時,指定事件執行時在冒泡階段還是捕獲階段。
obj.addEventListener(event,function(){},bool)
bool:false,代表冒泡階段執行
bool:true,代表捕獲階段執行
#w3c的方法是e.stopPropagation(),IE則是使用e.cancelBubble = true;
阻止預設行為
#w3c的方法是e.preventDefault(),IE就是使用e .returnValue = false;
即在上訴JS程式碼改為以下內容:
<script type="text/javascript">
var obj1=document.getElementById('id1');
obj1.addEventListener('click',function(e){curClick('id1');stopPropagation(e)},false);
var obj2=document.getElementById('id2');
obj2.addEventListener('click',function(e){curClick('id2');stopPropagation(e)},true);
var obj3=document.getElementById('id3');
obj3.addEventListener('click',function(e){curClick('id3');stopPropagation(e)},true);
function curClick(id){
alert(id);
}
function stopPropagation(e){
var e = window.event || event;
if(e.stopPropagation) { //W3C阻止冒泡方法
e.stopPropagation();
} else {
e.cancelBubble = true; //IE阻止冒泡方法
}
}
</script>
當點選id3:執行結果:id2
當點選id2:執行結果:id2
當點擊id1:執行結果:id1
透過這個範例發現,原來阻止了事件冒泡,也阻止了事件繼續向下級捕獲。 測試使用瀏覽器是:Google Chrome
版本47.0.2526.106 m