面試整理之DOM事件階段

本文主要解決的問題:html

  1. 事件流git

  2. DOM事件流的三個階段程序員

先理解流的概念github

在現今的JavaScript中隨處可見。好比說React中的單向數據流,Node中的流,又或是今天本文所講的DOM事件流。都是流的一種生動體現。用術語說流是對輸入輸出設備的抽象。以程序的角度說,流是具備方向的數據。編程

事件流分事件冒泡與事件捕獲瀏覽器

在瀏覽器發展的過程當中,開發團隊遇到了一個問題。那就是頁面中的哪一部分擁有特定的事件?架構

能夠想象畫在一張紙上的一組同心圓,若是你把手指放在圓心上,那麼你的手指指向的其實不是一個圓,而是紙上全部的圓。放到實際頁面中就是,你點擊一個按鈕,事實上你還同時點擊了按鈕全部的父元素。
開發團隊的問題就在於,當點擊按鈕時,是按鈕最外層的父元素先收到事件並執行,仍是具體元素先收到事件並執行?因此這兒引入了事件流的概念。
函數

通俗說,事件流所描述的就是從頁面中接受事件的順序。學習

由於有兩種觀點,因此事件流也有兩種,分別是事件冒泡和事件捕獲。現主流是事件冒泡。網站

 

事件冒泡

事件冒泡即事件開始時,由最具體的元素接收(也就是事件發生所在的節點),而後逐級傳播到較爲不具體的節點。

下面寫個例子:

複製代碼

 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4   <meta charset="UTF-8"> 5   <title>Event Bubbling</title> 6 </head> 7 <body> 8   <button id="clickMe">Click Me</button> 9 </body>10 </html>

複製代碼

而後,咱們給button和它的父元素,加入點擊事件。

複製代碼

 1 var button = document.getElementById('clickMe'); 2  3 button.onclick = function() { 4   console.log('1. You click Button'); 5 }; 6 document.body.onclick = function() { 7   console.log('2. You click body'); 8 }; 9 document.onclick = function() {10   console.log('3. You click document');11 };12 window.onclick = function() {13   console.log('4. You click window');14 };

複製代碼

在Chrome瀏覽器運行:

若是點擊了button,那麼這個點擊事件會按以下的順序傳播

  1. button

  2. body

  3. document

  4. window

也就是說,click事件首先在<button>元素上發生,而後逐級向上傳播。

 

事件捕獲

事件捕獲的概念,與事件冒泡正好相反。它認爲當某個事件發生時,父元素應該更早接收到事件,具體元素則最後接收到事件。好比說剛纔的demo,若是是事件捕獲的話,事件發生順序會是這樣的:

  1. window

  2. document

  3. body

  4. button

事件階段(Event Phases)

當一個DOM事件觸發時,它不是在觸發的對象上只觸發一次的,而是經歷三個階段。分別爲

1:一開始從文檔的根節點流向目標對象(捕獲階段)

2:而後在目標對向上被觸發(目標階段)

3:以後再回溯到文檔的根節點(冒泡階段).

1. 事件捕獲階段

事件的第一個階段是捕獲階段。事件從文檔的根節點出發,隨着DOM樹的結構向事件的目標節點流去。途中通過各個層次的DOM節點,並在各節點上觸發捕獲事件,直到到達事件的目標節點。捕獲階段的主要任務是創建傳播路徑,在冒泡階段,事件會經過這個路徑回溯到文檔跟節點。當事件發生時,首先發生的是事件捕獲,爲父元素截獲事件提供了機會。
例如,我把上面的Demo中,window點擊事件更改成使用事件捕獲模式。(addEventListener最後一個參數,true則表明使用事件捕獲模式,false則表示使用事件冒泡模式。不理解的能夠去學習一下addEventListener函數的使用)

1 window.addEventListener('click', function() {2   console.log('4. You click window');3 }, true);

此時,點擊button的效果是這樣的。

能夠看到,點擊事件先被父元素截獲了,且該函數只在事件捕獲階段起做用。

 

處於目標與事件冒泡階段

事件到了具體元素時,在具體元素上發生,而且被當作冒泡階段的一部分。
隨後,冒泡階段發生,事件開始冒泡。

 

阻止事件冒泡

事件冒泡過程,是能夠被阻止的。防止事件冒泡而帶來沒必要要的錯誤和困擾。
這個方法就是:stopPropagation()
咱們對button的click事件作一些改造。

1 button.addEventListener('click', function(event) {2   // event爲事件對象3   console.log('1. You click Button');4   event.stopPropagation();5   console.log('Stop Propagation!');6 }, false);

 點擊後,效果以下圖:

不難看出,事件在到達具體元素後,中止了冒泡。但不影響父元素的事件捕獲。

 

總結

事件流:描述的就是從頁面中接受事件的順序。

分有事件冒泡與事件捕獲兩種。


DOM事件流的三個階段:

  1. 事件捕獲階段

  2. 處於目標階段

  3. 事件冒泡階段

 

參考資料:《JavaScript高級程序設計》第三版

https://github.com/LYZ0106/

問啊APP,程序員答題神器,解決你全部的技術難題,   (上問啊APP 瞭解更多) http://t.cn/R4vE2d7 下載註冊送5元 快去下載註冊吧! 



問啊-定製化IT教育平臺,牛人一對一服務,有問必答,開發編程社交頭條 官方網站:www.wenaaa.com 下載問啊APP,參與官方懸賞,賺百元現金。

QQ羣290551701 彙集不少互聯網精英,技術總監,架構師,項目經理!開源技術研究,歡迎業內人士,大牛及新手有志於從事IT行業人員進入!

http://cxy.liuzhihengseo.com/491.html

相關文章
相關標籤/搜索