11.JS-事件流-冒泡、捕獲
阿新 • • 發佈:2018-12-12
事件流:
頁面接受事件的順序
DOM事件流:
當事件發生時,事件會在該元素節點和根節點之間的路徑進行傳播,傳播過程中所遇到的節點都會接受該事件
冒泡:從最具體元素傳播最不具體的元素
事件發生的元素節點傳播到根節點
捕獲:從最不具體的元素傳播到最具體的元素
根節點傳播到事件發生的具體節點
注意:IE中只有冒泡階段,非IE中既有冒泡也有捕獲
阻止事件冒泡:
event.stopPropagation()
事件傳遞定義了元素事件觸發的順序。 如果你將 <p> 元素插入到 <div> 元素中,使用者點選 <p> 元素, 哪個元素的 "click" 事件先被觸發呢?
在 冒泡 中,內部元素的事件會先被觸發,然後再觸發外部元素,即: <p> 元素的點選事件先觸發,然後會觸發 <div> 元素的點選事件。
在 捕獲 中,外部元素的事件會先被觸發,然後才會觸發內部元素的事件,即: <div> 元素的點選事件先觸發 ,然後再觸發 <p> 元素的點選事件。
比如:我設定了3個div,層層巢狀
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <style type="text/css"> #box1{ width: 1000px; height: 500px; margin: 0 auto; border: 1px solid #233; } #box2{ width: 700px; height:400px; border: 1px solid #233; margin: 0 auto; } #box3{ width:500px; height: 300px; margin: 0 auto; border: 1px solid #233; } </style> <body> <div id="box1"> box1 <div id="box2"> box2 <div id="box3">box3</div> </div> </div> </body> </html>
然後為它們都註冊一個點選事件
var box1 = document.getElementById('box1'); var box2 = document.getElementById('box2'); var box3 = document.getElementById('box3'); function addEvent(obj,type,fn){ if(obj.addEventListener){ obj.addEventListener(type,fn,false); }else { obj.attachEvent("on"+type,fn); } } addEvent(box1,'click',function(event){alert('我是box1')}); addEvent(box2,'click',function(event){alert('我是box2')}); addEvent(box3,'click',function(event){ alert('我是box3') //阻止事件冒泡 //event.stopPropagation(); });
事件流順序預設為false,即冒泡。
這個時候當你點選box3時,會彈出'我是box3'的視窗,緊接著依次彈出'我是box2'和'我是box1'的視窗。
想要阻止這種行為出現,可以在box3的註冊事件函式內新增event.stopPropagation();,阻止事件冒泡
若將事件流順序改為true,即捕獲。
當點選box3時,彈出視窗的順序會和冒泡的相反。
最後,再提醒一次,想要看到捕獲階段的效果,請在非IE瀏覽器上執行,因為IE瀏覽器只有冒泡階段。