看網上說的也不是太明白,我給從新整理下。 參閱: https://www.cnblogs.com/alvin...
冒泡和捕獲是指在元素上的事件被觸發的時候,js 傳遞事件的兩種方向,或者說過程。css
如,有這麼一個頁面 和 js 方法html
Less: 我用 less寫的,若是沒有 less 環境,能夠無視這段。
.level { padding: 50px 80px; } .level-template(@level: 1, @color: #fff){ background-color: darken( @color , 5% * @level); } #lv1{ .level-template(1)} #lv2{ .level-template(2)} #lv3{ .level-template(3)} #lv4{ .level-template(4)}
HTML
<div id="lv1" class="level"> <div id="lv2" class="level"> <div id="lv3" class="level"> <div id="lv4" class="level"> </div> </div> </div> </div>
JS
function $(id) { return document.getElementById(id); } window.onload = () => { $('lv1').addEventListener("click",()=>{console.log('lv1')},true); $('lv2').addEventListener("click",()=>{console.log('lv2')},true); $('lv3').addEventListener("click",()=>{console.log('lv3')},true); }; // 上面的 () => {} 爲 ES6 的匿名方法的定義方式 // 等同於 function () { console.log('lv1') }
上面的 js 作的事:
在頁面載入的時候,給三個 div 添加 click 監聽方法,本身被點擊的時候會在 console 中輸出本身的 id 值。less
頁面的結構是這樣的 lv1
包含 lv2
,lv2
又包含 lv3
,當點擊 lv3
的時候,其實也點擊了 lv2
和 lv1
,由於 lv3
在 lv2
內部,點擊 lv3
的時候,天然也點擊了 lv2
和 lv1
,也就是說,點擊 lv3
的時候,會觸發三個 click
事件。
至於這三個事件觸發的順序,就是所謂的 冒泡
和 捕獲
。spa
document
往事件觸發對象,從外向內捕獲事件對象;如上面的例子,在 lv3
被點擊的時候,js 會從文檔的最上層開始,由外向內尋找點擊事件的起源,也就是 lv3
。那麼這個由外向內的過程就是 lv1
--> lv2
--> lv3
,這三個 div 的 click 事件按照這個過程依次被觸發。
這個觸發的方向就是捕獲
的方向。code
在找到被點擊的 lv3 以後,事件向上傳遞,過程是 lv3
--> lv2
--> lv1
,此時依次觸發 lv3
、lv2
、lv1
的 click
事件,這個由內向外的觸發過程就稱爲冒泡
htm
element.addEventListener(event, function, useCapture)
這裏面,useCapture
是個布爾值,用於定義事件是在冒泡階段
觸發,仍是在捕獲階段
觸發,默認值是 false
,表明在冒泡時觸發。對象
此時你就會知道上面那個例子裏定義的 click 方法是在 捕獲階段
執行,那麼返回的結果就是blog
lv1 lv2 lv3
若是最上面的例子,onload
內容是這樣的事件
window.onload = () => { $('lv1').addEventListener("click",()=>{console.log('lv1')},false); $('lv2').addEventListener("click",()=>{console.log('lv2')},false); $('lv3').addEventListener("click",()=>{console.log('lv3')},false); };
那麼也就是說, click
事件在 冒泡階段
觸發,返回的結果就是ip
lv3 lv2 lv1
冒泡和捕獲的關係,只會出如今包含和被包含的結構中,兄弟關係是不會有這種關係的。冒泡和捕獲只是方向的不一樣而已。