1. 程式人生 > >理解DOM事件流的三個階段

理解DOM事件流的三個階段

起因

在學習前端的大半年來,對DOM事件瞭解甚少。一般也只是用用onclick來繫結個點選事件。在寒假深入學習JavaScript時,愈發覺得自己對DOM事件瞭解不夠,遂開啟我的《JavaScript高階程式設計》,翻到DOM事件那一章,開始第二次學習之旅。
當然,DOM事件所囊括的知識較為龐雜,所以本文專注與自己學習時所碰到的難點,DOM事件流。

流的概念,在現今的JavaScript中隨處可見。比如說React中的單向資料流,Node中的流,又或是今天本文所講的DOM事件流。都是流的一種生動體現。
至於流的具體概念,我們採用下文的解釋:

用術語說流是對輸入輸出裝置的抽象。以程式的角度說,流是具有方向的資料。

通通連起來——無處不在的流 淘寶FED–愈之

事件流之事件冒泡與事件捕獲

在瀏覽器發展的過程中,開發團隊遇到了一個問題。那就是頁面中的哪一部分擁有特定的事件?
可以想象畫在一張紙上的一組同心圓,如果你把手指放在圓心上,那麼你的手指指向的其實不是一個圓,而是紙上所有的圓。放到實際頁面中就是,你點選一個按鈕,事實上你還同時點選了按鈕所有的父元素。
開發團隊的問題就在於,當點選按鈕時,是按鈕最外層的父元素先收到事件並執行,還是具體元素先收到事件並執行?所以這兒引入了事件流的概念。

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

因為有兩種觀點,所以事件流也有兩種,分別是事件冒泡和事件捕獲。現行的主流是事件冒泡。

事件冒泡

事件冒泡即事件開始時,由最具體的元素接收(也就是事件發生所在的節點),然後逐級傳播到較為不具體的節點。
舉個栗子,就很容易明白了。

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

然後,我們給button和它的父元素,加入點選事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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瀏覽器):

  1. button
  2. body
  3. document
  4. window

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

事件捕獲

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

  1. window
  2. document
  3. body
  4. button


當然,由於時代更迭,事件冒泡方式更勝一籌。所以放心的使用事件冒泡,有特殊需要再使用事件捕獲即可。

DOM事件流

DOM事件流包括三個階段。

  1. 事件捕獲階段
  2. 處於目標階段
  3. 事件冒泡階段

如圖所示(圖片源於網路,若侵權請告知):

1. 事件捕獲階段

也就是說,當事件發生時,首先發生的是事件捕獲,為父元素截獲事件提供了機會。
例如,我把上面的Demo中,window點選事件更改為使用事件捕獲模式。(addEventListener最後一個引數,為true則代表使用事件捕獲模式,false則表示使用事件冒泡模式。不理解的可以去學習一下addEventListener函式的使用)

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

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

可以看到,點選事件先被父元素截獲了,且該函式只在事件捕獲階段起作用。

處於目標與事件冒泡階段

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

阻止事件冒泡

事件冒泡過程,是可以被阻止的。防止事件冒泡而帶來不必要的錯誤和困擾。
這個方法就是:stopPropagation()

stopPropagation() 方法
終止事件在傳播過程的捕獲、目標處理或起泡階段進一步傳播。呼叫該方法後,該節點上處理該事件的處理程式將被呼叫,事件不再被分派到其他節點。

我們對button的click事件做一些改造。

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

點選後,效果如下圖:

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

總結與感想

事件流:描述的就是從頁面中接受事件的順序。分有事件冒泡與事件捕獲兩種。
DOM事件流的三個階段:

  1. 事件捕獲階段
  2. 處於目標階段
  3. 事件冒泡階段

源引:

http://lxxyx.win/2016/02/17/%E5%AF%92%E5%81%87%E5%89%8D%E7%AB%AF%E5%AD%A6%E4%B9%A0(10)%E2%80%94%E2%80%94%E7%90%86%E8%A7%A3DOM%E4%BA%8B%E4%BB%B6%E6%B5%81%E7%9A%84%E4%B8%89%E4%B8%AA%E9%98%B6%E6%AE%B5/

相關推薦

理解DOM事件階段

起因 在學習前端的大半年來,對DOM事件瞭解甚少。一般也只是用用onclick來繫結個點選事件。在寒假深入學習JavaScript時,愈發覺得自己對DOM事件瞭解不夠,遂開啟我的《JavaScript高階程式設計》,翻到DOM事件那一章,開始第二次學習之旅。 當然,

DOM標準事件階段:冒泡、捕獲 dom事件階段

本文主要解決兩個問題: 什麼是事件流 DOM事件流的三個階段 起因 溫故了一下我的《JavaScript高階程式設計》的時候,翻到DOM事件那一章,(說實話,現在無論是什麼框架你都離不開操作DOM啊,畢竟這是你展示的最基本元素,就像人的細胞)。想起了dom事

事件階段

(1)捕獲:當我們在 DOM 樹的某個節點發生了一些操作(例如單擊、滑鼠移動上去),就會有一個事件發射過去。這個事件從 Window 發出,不斷經過下級節點直到觸發的目標節點。在到達目標節點之前的過程,就是捕獲階段(Capture Phase)。(所有經過的節點,都會觸發這個事件。捕獲階段的任務就是建立這個

JS事件階段以及冒泡和事件物件event

js事件的三個階段分別為:捕獲、目標、冒泡      1.捕獲:事件由頁面元素接收,逐級向下,到具體的元素   2.目標:具體的元素本身   3.冒泡:跟捕獲相反,具體元素本身,逐級向上,到頁面元素   事件捕獲:當使用事件捕獲時,父級元素先觸發,子元素後觸發   事件冒泡:

事件階段:捕獲階段 目標階段 冒泡階段

js有好多的知識需要不斷積累,但是不能淺嘗,應該深究其內因,並運用在日常開發過程中。 捕獲階段: 事件從根節點流向目標節點,途中流經各個DOM節點,在各個節點上觸發捕獲事件,直到達到目標節點。 那麼捕獲階段有什麼用嗎?完全可以沒有捕獲階段也可以啊? 捕獲階段的主要任務是建立傳播路經,在冒泡階段根據這

理解DOM事件

DOM事件標準定義了兩種事件流,這兩種事件流有著顯著的不同並且可能對你的應用有著相當大的影響。這兩種事件流分別是捕獲和冒泡。和許多Web技術一樣,在它們成為標準之前,Netscape和微軟各自不同地實現了它們。Netscape選擇實現了捕獲事件流,微軟則實現了冒泡事件流。幸運

關於dom 事件冒泡、捕獲 dom事件階段

本文主要解決兩個問題: 什麼是事件流 DOM事件流的三個階段 起因 溫故了一下我的《JavaScript高階程式設計》的時候,翻到DOM事件那一章,(說實話,現在無論是什麼框架你都離不開操作DOM啊,畢竟這是你展示的最基本元素,就像人的細胞)。想起了dom事

什麽是事件代理?DOM2.0標準事件模型的階段

logs 效果 function 如果 param 必須 操作dom 彈出 認識 體驗更優排版請移步原文:http://vblog.win/blogs/programming/js-event-delegation.html 事件代理,又稱事件委托(Delegati

深入理解DOM事件機制系列第篇——事件物件

前面的話   在觸發DOM上的某個事件時,會產生一個事件物件event,這個物件中包含著所有與事件有關的資訊。所有瀏覽器都支援event物件,但支援方式不同。本文將詳細介紹事件物件 獲取事件物件   【1】一般地,event物件是事件程式的第一個引數   [注意

理解JS捕獲、目標、冒泡階段

<!DOCTYPE html> <html> <head> <title>demo</title> </head> <body> <a id="A">元素A</a> </body&

APP之紅點提醒階段

istview images 用戶 擴展 cimage art str alt gin 下面這個頁面就是我們進入APP後的主界面。客戶選項的紅點上數字就是顯示我們沒有查看的客戶總數量。 當我們切換到客戶這個fragment時,會顯示貸款客戶數量與保險客

IE和DOM事件、普通事件和綁定事件的區別

strong clas doc cap () 添加多個 nbsp class 器) IE和DOM事件流的區別 IE采用冒泡型事件 Netscape(網絡信息瀏覽器)使用捕獲型事件 DOM使用先捕獲後冒泡型事件 示例: <body> <div

2018-06-25 js表單事件高度和Ajax異步通訊技術

click pre 監聽 ons The element state document name 表單事件:   onfocus -> 表單控件得到焦點時觸發;     obj_ipt.onfocus=function(){};    onblur -> 表單控

反射階段學習筆記

type vpd ffffff water sha shadow 分享圖片 反射 term 反射三個階段學習筆記

oracle資料庫啟動的階段

oracle資料庫啟動的三個階段:nomount,mount,open           nomount的啟動:需要引數檔案           mount的啟動:需要控制檔案 &nbs

互聯網發展的階段

圖片 com tex 讓我 朋友 服務 新浪微博 2.0 技術分享 互聯網發展的三個階段 三個階段 1)PC互聯網(PC Internet) 2)移動互聯網(Mobile Internet) 3)物聯網(IOT Internet Of Things) 互動與互聯 互動1

網際網路發展的階段

網際網路發展的三個階段 三個階段 1)PC網際網路(PC Internet) 2)移動網際網路(Mobile Internet) 3)物聯網(IOT Internet Of Things)   互動與互聯 互動1.0   入口網站,企業入口網站,提供一些資訊服務 互動2.0   

事件事件冒泡、事件捕獲以及DOM事件

事件流:描述的是從頁面中接收事件的順序。 事件冒泡:IE的事件流叫做事件冒泡,即事件開始時由最具體的元素(文件中巢狀層次最深的那個節點)接收,然後逐級上傳播到較為不具體的節點(文件)。 示例程式碼: <!DOCTYPE html> <html> <

PP.io的階段,“強中心”——“弱中心”——“去中心”

什麼是PP.io? PP.io是我和Bill發起的儲存專案,目的在於為開發者提供一個去中心化的儲存和分發平臺,能做到更便宜,更高速,更隱私。 當然做去中心化儲存的專案也有好幾個,FileCoin,SiaCoin,MaidSafe等,但是仔細看看他們流出的資料,官網,白皮書,文章以及各

一切為了落地,為什麼要把PP.io設計成階段

之前的一篇文章,我講解了PP.io的三個階段:“強中心”,“弱中心”,“去中心”。今天來解釋下,我為什麼要分三個階段逐步實現PP.io去中心化儲存網路: 簡單地說,就是在區塊鏈不可能三角理論中,我暫時放棄了去中心化。 我先解釋一下什麼是不可能三角理論。就是說可擴充套件性(Scalable)