摘要:本文主要解決兩個(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)擊事件。在寒假深入學(xué)習(xí)JavaScript時(shí),愈發(fā)覺(jué)得自己對(duì)DOM事件了解不夠,遂打開(kāi)我的《JavaScript高級(jí)程序設(shè)計(jì)》,翻到DOM事件那一章,開(kāi)始第二次學(xué)習(xí)之旅。
當(dāng)然,DOM事件所囊括的知識(shí)較為龐雜,所以本文專(zhuān)注與自己學(xué)習(xí)時(shí)所碰到的難點(diǎn),DOM事件流。
流的概念,在現(xiàn)今的JavaScript中隨處可見(jiàn)。比如說(shuō)React中的單向數(shù)據(jù)流,Node中的流,又或是今天本文所講的DOM事件流。都是流的一種生動(dòng)體現(xiàn)。
至于流的具體概念,我們采用下文的解釋?zhuān)?/p>
事件流之事件冒泡與事件捕獲用術(shù)語(yǔ)說(shuō)流是對(duì)輸入輸出設(shè)備的抽象。以程序的角度說(shuō),流是具有方向的數(shù)據(jù)。
通通連起來(lái)——無(wú)處不在的流 淘寶FED--愈之
在瀏覽器發(fā)展的過(guò)程中,開(kāi)發(fā)團(tuán)隊(duì)遇到了一個(gè)問(wèn)題。那就是頁(yè)面中的哪一部分擁有特定的事件?
可以想象畫(huà)在一張紙上的一組同心圓,如果你把手指放在圓心上,那么你的手指指向的其實(shí)不是一個(gè)圓,而是紙上所有的圓。放到實(shí)際頁(yè)面中就是,你點(diǎn)擊一個(gè)按鈕,事實(shí)上你還同時(shí)點(diǎn)擊了按鈕所有的父元素。
開(kāi)發(fā)團(tuán)隊(duì)的問(wèn)題就在于,當(dāng)點(diǎn)擊按鈕時(shí),是按鈕最外層的父元素先收到事件并執(zhí)行,還是具體元素先收到事件并執(zhí)行?所以這兒引入了事件流的概念。
事件流所描述的就是從頁(yè)面中接受事件的順序。
因?yàn)橛袃煞N觀點(diǎn),所以事件流也有兩種,分別是事件冒泡和事件捕獲。現(xiàn)行的主流是事件冒泡。
事件冒泡事件冒泡即事件開(kāi)始時(shí),由最具體的元素接收(也就是事件發(fā)生所在的節(jié)點(diǎn)),然后逐級(jí)傳播到較為不具體的節(jié)點(diǎn)。
舉個(gè)栗子,就很容易明白了。
Event Bubbling
然后,我們給button和它的父元素,加入點(diǎn)擊事件。
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"); };
效果如圖所示:
在代碼所示的頁(yè)面中,如果點(diǎn)擊了button,那么這個(gè)點(diǎn)擊事件會(huì)按如下的順序傳播(Chrome瀏覽器):
button
body
document
window
也就是說(shuō),click事件首先在元素上發(fā)生,然后逐級(jí)向上傳播。這就是事件冒泡。
事件捕獲事件捕獲的概念,與事件冒泡正好相反。它認(rèn)為當(dāng)某個(gè)事件發(fā)生時(shí),父元素應(yīng)該更早接收到事件,具體元素則最后接收到事件。比如說(shuō)剛才的demo,如果是事件捕獲的話,事件發(fā)生順序會(huì)是這樣的:
window
document
body
button
當(dāng)然,由于時(shí)代更迭,事件冒泡方式更勝一籌。所以放心的使用事件冒泡,有特殊需要再使用事件捕獲即可。
DOM事件流包括三個(gè)階段。
事件捕獲階段
處于目標(biāo)階段
事件冒泡階段
如圖所示(圖片源于網(wǎng)絡(luò),若侵權(quán)請(qǐng)告知):
也就是說(shuō),當(dāng)事件發(fā)生時(shí),首先發(fā)生的是事件捕獲,為父元素截獲事件提供了機(jī)會(huì)。
例如,我把上面的Demo中,window點(diǎn)擊事件更改為使用事件捕獲模式。(addEventListener最后一個(gè)參數(shù),為true則代表使用事件捕獲模式,false則表示使用事件冒泡模式。不理解的可以去學(xué)習(xí)一下addEventListener函數(shù)的使用)
window.addEventListener("click", function() { console.log("4. You click window"); }, true);
此時(shí),點(diǎn)擊button的效果是這樣的。
可以看到,點(diǎn)擊事件先被父元素截獲了,且該函數(shù)只在事件捕獲階段起作用。
處于目標(biāo)與事件冒泡階段事件到了具體元素時(shí),在具體元素上發(fā)生,并且被看成冒泡階段的一部分。
隨后,冒泡階段發(fā)生,事件開(kāi)始冒泡。
事件冒泡過(guò)程,是可以被阻止的。防止事件冒泡而帶來(lái)不必要的錯(cuò)誤和困擾。
這個(gè)方法就是:stopPropagation()
我們對(duì)button的click事件做一些改造。
button.addEventListener("click", function(event) { // event為事件對(duì)象 console.log("1. You click Button"); event.stopPropagation(); console.log("Stop Propagation!"); }, false);
點(diǎn)擊后,效果如下圖:
不難看出,事件在到達(dá)具體元素后,停止了冒泡。但不影響父元素的事件捕獲。
總結(jié)與感想事件流:描述的就是從頁(yè)面中接受事件的順序。分有事件冒泡與事件捕獲兩種。
DOM事件流的三個(gè)階段:
事件捕獲階段
處于目標(biāo)階段
事件冒泡階段
在學(xué)習(xí)DOM事件的過(guò)程中,了解了DOM事件的三個(gè)階段,也知道事件冒泡是干啥用的,又如何阻止。配合前期所學(xué)的二叉樹(shù)的相關(guān)知識(shí),受益匪淺。
前端路漫漫,且行且歌~
最后附上本人博客地址和原文鏈接,希望能與各位多多交流。
Lxxyx的前端樂(lè)園
原文鏈接:寒假前端學(xué)習(xí)(10)——理解DOM事件流的三個(gè)階段
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/49738.html
摘要:本文主要解決兩個(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)擊事件。...
摘要:事件流是事件冒泡,而的事件流就是事件捕獲。所有現(xiàn)代瀏覽器都支持事件冒泡,并且會(huì)將事件一直冒泡到對(duì)象。事件捕獲的用以在于事件到達(dá)預(yù)定目標(biāo)之前捕獲它。事件流級(jí)事件規(guī)定事件流包括三個(gè)階段,事件捕獲階段處于目標(biāo)階段和事件冒泡階段。 最近在復(fù)習(xí)前端的基礎(chǔ),看到事件這一節(jié)的時(shí)候,剛好發(fā)現(xiàn)了筆記中一道特別好玩并且十分有趣的代碼,根據(jù)這么一道題目,基本上能夠把事件冒泡和事件捕獲的盲區(qū)給掃空。本文就帶你...
摘要:事件流是事件冒泡,而的事件流就是事件捕獲。所有現(xiàn)代瀏覽器都支持事件冒泡,并且會(huì)將事件一直冒泡到對(duì)象。事件捕獲的用以在于事件到達(dá)預(yù)定目標(biāo)之前捕獲它。事件流級(jí)事件規(guī)定事件流包括三個(gè)階段,事件捕獲階段處于目標(biāo)階段和事件冒泡階段。 最近在復(fù)習(xí)前端的基礎(chǔ),看到事件這一節(jié)的時(shí)候,剛好發(fā)現(xiàn)了筆記中一道特別好玩并且十分有趣的代碼,根據(jù)這么一道題目,基本上能夠把事件冒泡和事件捕獲的盲區(qū)給掃空。本文就帶你...
摘要:事件流是事件冒泡,而的事件流就是事件捕獲。所有現(xiàn)代瀏覽器都支持事件冒泡,并且會(huì)將事件一直冒泡到對(duì)象。事件捕獲的用以在于事件到達(dá)預(yù)定目標(biāo)之前捕獲它。事件流級(jí)事件規(guī)定事件流包括三個(gè)階段,事件捕獲階段處于目標(biāo)階段和事件冒泡階段。 最近在復(fù)習(xí)前端的基礎(chǔ),看到事件這一節(jié)的時(shí)候,剛好發(fā)現(xiàn)了筆記中一道特別好玩并且十分有趣的代碼,根據(jù)這么一道題目,基本上能夠把事件冒泡和事件捕獲的盲區(qū)給掃空。本文就帶你...
閱讀 2857·2023-04-25 17:59
閱讀 689·2023-04-25 15:05
閱讀 676·2021-11-25 09:43
閱讀 3041·2021-10-12 10:13
閱讀 3546·2021-09-27 13:59
閱讀 3591·2021-09-23 11:21
閱讀 3892·2021-09-08 09:35
閱讀 572·2019-08-29 17:12