DOM標準事件的三個階段:冒泡、捕獲 dom事件三個階段
本文主要解決兩個問題:
-
什麼是事件流
-
DOM事件流的三個階段
起因
溫故了一下我的《JavaScript高階程式設計》的時候,翻到DOM事件那一章,(說實話,現在無論是什麼框架你都離不開操作DOM啊,畢竟這是你展示的最基本元素,就像人的細胞)。想起了dom事件流原理,好多人不明白,只知道click mouseout等實用場景,真要理解和更進一步的前端是要必須:理論+實踐 並行的。
當然,DOM事件所囊括的知識較為龐雜,所以本文專注與自己學習時所碰到的難點,DOM事件流。
流
流的概念,在現今的JavaScript中隨處可見。比如說React中的單向資料流,Node中的流,又或是今天本文所講的DOM事件流。都是流的一種生動體現。至於流的具體概念,我們採用下文的解釋:
用術語說流是對輸入輸出裝置的抽象。以程式的角度說,流是具有方向的資料。
事件流之事件冒泡與事件捕獲
在瀏覽器發展的過程中,開發團隊遇到了一個問題。那就是頁面中的哪一部分擁有特定的事件?
可以想象畫在一張紙上的一組同心圓,如果你把手指放在圓心上,那麼你的手指指向的其實不是一個圓,而是紙上所有的圓。放到實際頁面中就是,你點選一個按鈕,事實上你還同時點選了按鈕所有的父元素。
開發團隊的問題就在於,當點選按鈕時,是按鈕最外層的父元素先收到事件並執行,還是具體元素先收到事件並執行?所以這兒引入了事件流的概念。
事件流所描述的就是從頁面中接受事件的順序。
因為有兩種觀點,所以事件流也有兩種,分別是事件冒泡和事件捕獲。現行的主流是事件冒泡。
事件冒泡
事件冒泡即事件開始時,由最具體的元素接收(也就是事件發生所在的節點),然後逐級傳播到較為不具體的節點。舉個栗子,就很容易明白了。
然後,我們給 button
和它的父元素,加入點選事件。
var button = document.getElementById('clickMe');
button.onclick = function() {
console.log('1. You click Button');
};
document.body.onclick = function() {
console.log('2. You click body');
};
document.onclick = function() {
console.log('3. You click document');
};
window.onclick = function() {
console.log('4. You click window');
};
效果如圖所示:
在程式碼所示的頁面中,如果點選了button,那麼這個點選事件會按如下的順序傳播(Chrome瀏覽器):
-
button
-
body
-
document
-
window
也就是說,click事件首先在 <button>
元素上發生,然後逐級向上傳播。這就是事件冒泡。
事件捕獲
事件捕獲的概念,與事件冒泡正好相反。它認為當某個事件發生時,父元素應該更早接收到事件,具體元素則最後接收到事件。比如說剛才的demo,如果是事件捕獲的話,事件發生順序會是這樣的:
-
window
-
document
-
body
-
button
當然,由於時代更迭,事件冒泡方式更勝一籌。所以放心的使用事件冒泡,有特殊需要再使用事件捕獲即可。
DOM事件流
DOM事件流包括三個階段。
-
事件捕獲階段
-
處於目標階段
-
事件冒泡階段
如圖所示(圖片源於網路,若侵權請告知):
1. 事件捕獲階段
也就是說,當事件發生時,首先發生的是事件捕獲,為父元素截獲事件提供了機會。
例如,我把上面的Demo中,window點選事件更改為使用事件捕獲模式。(addEventListener最後一個引數, 為true則代表使用事件捕獲模式 ,false則表示使用事件冒泡模式。不理解的可以去學習一下addEventListener函式的使用)
window.addEventListener('click', function() {
console.log('4. You click window');
}, true);
此時,點選button的效果是這樣的。
可以看到,點選事件先被父元素截獲了,且該函式只在事件捕獲階段起作用。
處於目標與事件冒泡階段
事件到了具體元素時,在具體元素上發生,並且被看成冒泡階段的一部分。隨後,冒泡階段發生,事件開始冒泡。
阻止事件冒泡
事件冒泡過程,是可以被阻止的。防止事件冒泡而帶來不必要的錯誤和困擾。
這個方法就是:stopPropagation()
我們對 button
的click事件做一些改造。
點選後,效果如下圖:
不難看出,事件在到達具體元素後,停止了冒泡。但不影響父元素的事件捕獲。
總結與感想
事件流:描述的就是從頁面中接受事件的順序。分有事件冒泡與事件捕獲兩種。DOM事件流的三個階段:
-
事件捕獲階段
-
處於目標階段
-
事件冒泡階段
在學習DOM事件的過程中,瞭解了DOM事件的三個階段,也知道事件冒泡是幹啥用的,又如何阻止。配合前期所學的二叉樹的相關知識,受益匪淺。