事件冒泡為何會(huì)觸發(fā)兩次?
事件冒泡(Event Bubbling)是指在DOM中,當(dāng)一個(gè)元素觸發(fā)了某個(gè)事件(例如點(diǎn)擊事件),該事件會(huì)從該元素開始向上冒泡至父元素,直到冒泡到最頂層的文檔對(duì)象為止。事件冒泡是DOM事件模型的一部分,它允許開發(fā)者將事件監(jiān)聽綁定到父元素,從而在子元素觸發(fā)事件時(shí),可以通過冒泡機(jī)制來捕獲并處理事件。
然而,有時(shí)開發(fā)者會(huì)遇到事件冒泡觸發(fā)兩次的情況,這通常出現(xiàn)在嵌套元素中。為了更好地理解為何會(huì)觸發(fā)兩次,我們來看一個(gè)具體的代碼示例。
HTML代碼如下:
<div id="parent"> <div id="child"> <button id="button">點(diǎn)擊我</button> </div> </div>
登錄后復(fù)制
JavaScript代碼如下:
var parent = document.getElementById("parent"); var child = document.getElementById("child"); var button = document.getElementById("button"); parent.addEventListener("click", function(event) { console.log("父元素被點(diǎn)擊"); }); child.addEventListener("click", function(event) { console.log("子元素被點(diǎn)擊"); }); button.addEventListener("click", function(event) { console.log("按鈕被點(diǎn)擊"); event.stopPropagation(); });
登錄后復(fù)制
在上述代碼中,我們有一個(gè)父元素、一個(gè)子元素和一個(gè)按鈕,分別綁定點(diǎn)擊事件監(jiān)聽。當(dāng)我們?cè)诰W(wǎng)頁(yè)中點(diǎn)擊按鈕時(shí),事件將按照冒泡規(guī)則從子元素傳遞至父元素。
現(xiàn)在,讓我們來模擬一次點(diǎn)擊按鈕的操作。當(dāng)我們點(diǎn)擊按鈕時(shí),控制臺(tái)將打印如下輸出:
按鈕被點(diǎn)擊 子元素被點(diǎn)擊
登錄后復(fù)制
為什么會(huì)觸發(fā)兩次呢?
這是因?yàn)槭录芭菀獜挠|發(fā)元素開始依次向上冒泡至父元素,而在這個(gè)過程中經(jīng)過了子元素和父元素兩層。當(dāng)我們點(diǎn)擊按鈕時(shí),首先觸發(fā)了按鈕的點(diǎn)擊事件,打印出”按鈕被點(diǎn)擊”。接著,事件繼續(xù)冒泡至子元素,觸發(fā)了子元素的點(diǎn)擊事件,打印出”子元素被點(diǎn)擊”。最后,冒泡繼續(xù)至父元素,觸發(fā)了父元素的點(diǎn)擊事件。
那如何阻止事件冒泡觸發(fā)兩次呢?
我們可以通過在按鈕的點(diǎn)擊事件處理函數(shù)中調(diào)用event.stopPropagation()
來阻止事件繼續(xù)冒泡。在上述代碼中,我們已經(jīng)在按鈕的點(diǎn)擊事件中使用了這個(gè)方法。當(dāng)我們?cè)俅吸c(diǎn)擊按鈕時(shí),控制臺(tái)將只打印出”按鈕被點(diǎn)擊”,而不會(huì)繼續(xù)冒泡至子元素和父元素。
總結(jié)來說,事件冒泡會(huì)觸發(fā)兩次的情況通常出現(xiàn)在嵌套元素中,當(dāng)一個(gè)元素觸發(fā)了某個(gè)事件時(shí),事件會(huì)從觸發(fā)元素開始向上冒泡至父元素,直到冒泡到最頂層的文檔對(duì)象為止。然而,我們可以通過調(diào)用event.stopPropagation()
來阻止事件繼續(xù)冒泡,從而達(dá)到阻止事件冒泡觸發(fā)兩次的目的。