日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Event flow

發布時間:2023/12/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Event flow 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

考慮這么個例子:

<div><button id="btn">Click Me!</button> </div>

哪怕一個web開發的初學者都會知道,當我們鼠標在button上點擊時,會在button上觸發一個click事件。但是:

  • button是div的一個子Node;從界面上來看,在button里點擊相當于在div里點擊;那click事件也會觸發在div上嗎?
  • 如果click事件也觸發在div上,那它們會不會共用同一個事件對象?
  • 如果click事件也觸發在div上,誰的事件會先發生?
  • click事件還會在哪些元素上面觸發?
  • 等等...

想解答上述問題,我們需要理解事件(Event)一個很重要的機制:事件流動(Event Flow)。

事件流動

DOM事件不單單只會在一個Element上觸發,它還會流向其他Element。事件的流動通常會經歷這么三個階段:

捕獲階段 -> 目標階段 -> 冒泡階段

"eventPhase"

“eventPhase”是“Event”下的一個屬性,它指明當前event屬于那一個階段。
“eventPhase”可能是一下其中一個值:

  • Event.NONE,0,沒有事件需要處理
  • Event.CAPTURING_PHASE,1,捕獲階段
  • Event.AT_TARGET,2,目標階段,事件對象到達事件目標上
  • Event.BUBBLING_PHASE,3,冒泡階段

下面我們詳細討論一下這三個階段。

捕獲階段(capture phase)

捕獲階段的定義如下(w3c):

The event object propagate through the target's ancestors from the defaultView to the target's parent.
事件對象在事件目標的祖先中上到下順向傳播,從最頂層的defaultView到事件目標的(直系)父元素。

捕獲階段發生在整個事件流動的開始。在這階段里事件會從父(主干)到子(分支)由上往下傳播,被元素一層層地捕獲。
文章開頭的例子里面,捕獲階段的click事件會依次在document、body、div上觸發:

document 1v body 2v div 3 v button

一般我們沒太大需要監聽捕獲階段的事件;如果你確實希望這么做,需要將addEventListener的第三個參數設置為true:

// 第三個參數設置是否為捕獲階段,默認為false element.addEventListener('click', function() {}, true)

目標階段(target phase)

目標階段的定義是(w3c):

The event object arrive at the event object's event target.
事件對象到達事件目標。

例子里面,就是事件在button上觸發的。addEventListener可以監聽目標階段的事件:

element.addEventListener('click', function() {})

如果事件是不可冒泡的,那整個事件流動會到此為止,不會發生下面的冒泡階段。

冒泡階段(bubble phase)

冒泡階段的定義如下(w3c):

The event object propagates through the target's ancestors in reverse order, starting with the target's parent and ending with the defaultView.
事件對象會在事件目標的祖先元素里反向傳播,由開始的父元素到最后的defaultView(document)。

冒泡階段發生在最后,這也是我們最為熟悉的一個階段。在這階段里事件會從子(分支)到父(主干)逆向傳播,看起來像是一個水里的泡泡往上冒。
例子里面,冒泡階段的click事件會依次在div、body、document上觸發:

document 3^ body 2^ div 1 ^ button

"bubbles"

Event下的bubbles屬性標明該事件是否為可冒泡的。一旦該值為false,則說明 evnet不可冒泡,那其流動也會在第二階段“目標階段”后就終止。


總結

若一個元素(div)是目標元素(button)的祖先,那事件對象會在該元素上觸發兩次:一次是捕獲階段(1)的,另一次是冒泡階段(3)的。當事件對象在事件目標元素(button)上觸發時,事件流動進入了目標階段(2)。

  • 想監聽捕獲階段的事件,可以這樣:element.addEventListener('click', cb, true),將第三個參數設置為true。
  • 想監聽冒泡階段的事件,可以這樣:element.addEventListener('click', cb,),不使用第三個參數或將其設置為false。
  • 而上述的任何一種監聽方式都可以監聽到目標階段的事件。

最后,你可以配合這個例子來確認一下你的理解。

let divElement = document.querySelector('div')let btnElement = document.querySelector('button') document.body.addEventListener('click', event => { console.log('Body Click in Bubble Phase.') console.log('Event Phase: ' + event.eventPhase) }) document.body.addEventListener('click', event => { console.log('Body Click in Capture Phase.') console.log('Event Phase: ' + event.eventPhase) }, true) divElement.addEventListener('click', event => { console.log('Div Click in Bubble Phase.') console.log('Event Phase: ' + event.eventPhase) }) divElement.addEventListener('click', event => { console.log('Div Click in Capture Phase.') console.log('Event Phase: ' + event.eventPhase) }, true) btnElement.addEventListener('click', event => { console.log('Button Click in Target Phase.') console.log('Event Phase: ' + event.eventPhase) }) btnElement.addEventListener('click', event => { console.log('Button Click in Target Phase.') console.log('Event Phase: ' + event.eventPhase) }, true) Body Click in Capture Phase. Event Phase: 1 Div Click in Capture Phase. Event Phase: 1 Button Click in Target Phase. Event Phase: 2 Button Click in Target Phase. Event Phase: 2 Div Click in Bubble Phase. Event Phase: 3 Body Click in Bubble Phase. Event Phase: 3



作者:butterandfly
鏈接:https://www.jianshu.com/p/382895a4027d
來源:簡書

轉載于:https://www.cnblogs.com/Yehudic/p/10139752.html

總結

以上是生活随笔為你收集整理的Event flow的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。