摘要:也就是說(shuō)如果我們直接單擊目標(biāo),那么當(dāng)事件被觸發(fā)時(shí),正處于第二階段,這時(shí)所有的事件按照注冊(cè)先后順序觸發(fā),與是否設(shè)置第三個(gè)參數(shù)無(wú)關(guān)。
我的原文鏈接:再探事件的三個(gè)階段
偶然間看到一篇經(jīng)典博客,文中有一個(gè)例子挺有意思,大概是:
parent
問(wèn)點(diǎn)擊div時(shí),事件觸發(fā)的順序是什么?
根據(jù)事件的三個(gè)階段,我最初推測(cè)應(yīng)該是先觸發(fā)捕獲事件再觸發(fā)冒泡事件,但實(shí)際結(jié)果卻是先彈出冒泡再?gòu)棾霾东@。這是為什么呢?
事情先要從 addEventListener() 方法說(shuō)起,MDN文檔中關(guān)于此方法有明確描述:
如果事件監(jiān)聽(tīng)器恰好注冊(cè)到了事件目標(biāo)上,那么這個(gè)事件會(huì)處于“目標(biāo)階段”,而不是冒泡階段或者捕獲階段。在目標(biāo)階段的事件會(huì)觸發(fā)所有的監(jiān)聽(tīng)器,而不在乎這個(gè)監(jiān)聽(tīng)器到底在注冊(cè)時(shí) useCapture 參數(shù)值是什么。
也就是說(shuō)如果我們直接單擊目標(biāo),那么當(dāng)事件被觸發(fā)時(shí),event target正處于第二階段,這時(shí)所有的事件按照注冊(cè)先后順序觸發(fā),與是否設(shè)置第三個(gè)參數(shù)無(wú)關(guān)。
event 對(duì)象中有一個(gè)字段專門用于描述事件當(dāng)前是處于哪個(gè)階段:eventPhase:
0:當(dāng)前沒(méi)有事件需要處理;
1:捕獲階段,事件從window傳遞到目標(biāo);
2:命中階段,事件已經(jīng)到達(dá)目標(biāo);
3:冒泡階段,事件從目標(biāo)傳達(dá)到最頂層的window的過(guò)程;
W3C標(biāo)準(zhǔn)中有一張圖描述了這個(gè)過(guò)程:
其中提到的三個(gè)階段是 capture phase,target phase,bubble phase,事件對(duì)象的傳播是根據(jù) propagation path 進(jìn)行的。完整的例子如下:
codepen
我對(duì)事件的整個(gè)生命周期的各個(gè)階段的了解其實(shí)是非常有限的,個(gè)人推測(cè)如下:
操作系統(tǒng)捕獲事件(點(diǎn)擊、觸摸等);
瀏覽器從操作系統(tǒng)那里獲得事件的相關(guān)信息并生成事件對(duì)象;
瀏覽器計(jì)算事件傳播的路徑;
按照路徑傳播并觸發(fā)相應(yīng)節(jié)點(diǎn)上的事件;
最后由瀏覽器銷毀事件對(duì)象;
基于以上猜測(cè),有幾點(diǎn)不是很明白:
為什么要設(shè)計(jì)成三個(gè)階段?
有些地方是講的:因?yàn)闅v史原因——N公司提倡捕獲,M公司提倡冒泡,兩個(gè)公司互不妥協(xié),于是標(biāo)準(zhǔn)組織干脆兼容兩者,讓事件跑一個(gè)來(lái)回,倘若不支持某個(gè)過(guò)程則靜默出進(jìn)入相關(guān)階段就好。久而久之,大家都認(rèn)了這個(gè)規(guī)則,但是實(shí)際上來(lái)說(shuō)讓事件跑一個(gè)來(lái)回效率上肯定是不高的,而且從我的理解來(lái)看只進(jìn)行捕獲或者冒泡也是合乎邏輯的。所以為什么現(xiàn)代瀏覽器(比如chrome)要同時(shí)支持兩種傳播方式呢?
傳播路徑如何確定?
上文中說(shuō)到事件在傳播前,瀏覽器會(huì)先為其計(jì)算出傳播路徑,然而DOM樹(shù)表面上看并不是一棵查找二叉樹(shù),只是一種描述層級(jí)關(guān)系的樹(shù)狀數(shù)據(jù)結(jié)構(gòu)。那么假設(shè)瀏覽器從操作系統(tǒng)拿到了事件的基本信息(點(diǎn)擊位置,哪個(gè)鍵位,發(fā)生時(shí)間等),瀏覽器怎么在這樣的樹(shù)狀結(jié)構(gòu)中查找出一條確定的路徑呢?遍歷當(dāng)然是可以的,但是這樣效率是否太低?如果每個(gè)元素都有一個(gè)獨(dú)一無(wú)二的ID,對(duì)這個(gè)路徑查找問(wèn)題有幫助嗎?
事件與其它過(guò)程如何交互?
問(wèn)題可能說(shuō)的有點(diǎn)抽象,假設(shè)我們?cè)赿iv元素上綁定了一個(gè)hover動(dòng)畫(huà),那么當(dāng)鼠標(biāo)劃過(guò)時(shí)需要發(fā)生兩件事情:展示動(dòng)畫(huà)和觸發(fā)mouseover事件。我覺(jué)得合理的設(shè)計(jì)應(yīng)該是先觸發(fā)動(dòng)畫(huà)再觸發(fā)事件,有兩種可能性:
瀏覽器在事件傳播前觸發(fā)動(dòng)畫(huà),無(wú)論是捕獲還是冒泡,對(duì)動(dòng)畫(huà)觸發(fā)先后沒(méi)有影響;
瀏覽器在在事件傳播過(guò)程中觸發(fā)動(dòng)畫(huà),那么動(dòng)畫(huà)觸發(fā)順序可能和采用捕獲還是冒泡有關(guān)系;
請(qǐng)不吝賜教。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/80423.html
摘要:二基本服務(wù)簡(jiǎn)單使用語(yǔ)音文本轉(zhuǎn)換假定已經(jīng)完成關(guān)于的注冊(cè)和服務(wù)的創(chuàng)建。但是協(xié)議是一種非持久的單向的網(wǎng)絡(luò)協(xié)議。而彌補(bǔ)了這一缺點(diǎn),它是一種全雙工通信協(xié)議,在通過(guò)建立握手后,單獨(dú)建立一條通道用以服務(wù)器和瀏覽器之間的信息傳送。 這是這個(gè)系列的第二篇文章,主要基于上一篇文章中提到服務(wù)進(jìn)行一些基礎(chǔ)的功能實(shí)現(xiàn)。 二. 基本服務(wù)簡(jiǎn)單使用 2.1 speech to text(語(yǔ)音文本轉(zhuǎn)換) 假定已經(jīng)完成關(guān)...
摘要:今天接著介紹看過(guò)上篇的同學(xué),應(yīng)該都會(huì)用的高級(jí)爬蟲(chóng)功能了,附上姐妹篇鏈接除了爬蟲(chóng)之外,也可以幫你完成一些頁(yè)面上的重復(fù)操作,也可以當(dāng)作自動(dòng)化測(cè)試開(kāi)門見(jiàn)山,今天的目標(biāo)是,爬取頭條前端的文章,自動(dòng)推薦到掘金廢話不多說(shuō),直接上動(dòng)圖看效果圖很大,請(qǐng)稍等 今天接著介紹Puppeteer 看過(guò)上篇的同學(xué),應(yīng)該都會(huì)用Puppeteer的高級(jí)爬蟲(chóng)功能了,附上姐妹篇鏈接:https://segmentfa...
摘要:本文主要解決兩個(gè)問(wèn)題什么是事件流事件流的三個(gè)階段起因在學(xué)習(xí)前端的大半年來(lái),對(duì)事件了解甚少。事件流所描述的就是從頁(yè)面中接受事件的順序。事件流事件流包括三個(gè)階段。防止事件冒泡而帶來(lái)不必要的錯(cuò)誤和困擾。分有事件冒泡與事件捕獲兩種。 本文主要解決兩個(gè)問(wèn)題: 什么是事件流 DOM事件流的三個(gè)階段 起因 在學(xué)習(xí)前端的大半年來(lái),對(duì)DOM事件了解甚少。一般也只是用用onclick來(lái)綁定個(gè)點(diǎn)擊事件。...
摘要:本文主要解決兩個(gè)問(wèn)題什么是事件流事件流的三個(gè)階段起因在學(xué)習(xí)前端的大半年來(lái),對(duì)事件了解甚少。事件流所描述的就是從頁(yè)面中接受事件的順序。事件流事件流包括三個(gè)階段。防止事件冒泡而帶來(lái)不必要的錯(cuò)誤和困擾。分有事件冒泡與事件捕獲兩種。 本文主要解決兩個(gè)問(wèn)題: 什么是事件流 DOM事件流的三個(gè)階段 起因 在學(xué)習(xí)前端的大半年來(lái),對(duì)DOM事件了解甚少。一般也只是用用onclick來(lái)綁定個(gè)點(diǎn)擊事件。...
閱讀 5519·2021-09-22 15:59
閱讀 2070·2021-08-23 09:42
閱讀 2705·2019-08-29 18:42
閱讀 3586·2019-08-29 10:55
閱讀 2237·2019-08-27 10:57
閱讀 1888·2019-08-26 18:27
閱讀 2856·2019-08-23 18:26
閱讀 3115·2019-08-23 14:40