事件冒泡與事件捕獲怎麼理解?
在js中存在事件冒泡與事件捕獲兩種概念,這兩個概念都是為了解決頁面中事件流(事件發生順序)的問題, 那這兩種機制究終是為何物,我們今天來看一下
先上一張圖了解一下
事件冒泡(dubbed bubbling)
事件冒泡我們從字面意思理解就是當用戶行為觸發我們頁面的定義好的事件後,會有一個由内到外的一個冒泡過程,而不是一下子就命中事件綁定的元素
事件捕獲(event capturing)
事件捕獲與冒泡恰恰相反,當鼠标點擊或者觸發dom事件時,浏覽器會從根節點開始由外到内進行事件傳播,即點擊了子元素,如果父元素通過事件捕獲方式注冊了對應的事件的話,會先觸發父元素綁定的事件
我們用代碼來理解一下
在下邊這個例子中,如果兩個元素都有一個click的處理函數,那麼我們怎麼才能知道哪一個函數會首先被觸發呢?為了解決這種腦殼痛的問題,就有了今天的主題冒泡與捕獲
<div id="wrapper"> <button id="event">JS每日一題=>事件處理程序</button> </div> const wrapper = document.getElementById('wrapper'); const event = document.getElementById('event'); wrapper.addEventListener("click", () => { alert("1"); }, true) event.addEventListener("click", () => { alert("2"); }, true) wrapper.addEventListener("click", () => { alert("3"); }, false) event.addEventListener("click", () => { alert("4"); }, false)
上面的代碼最終輸出結果為:
在DOM2級事件規定的時間流包括 三個階段:
我們可以看到addEventListener的第三個參數我們傳入的不同,也就是上面結果為什麼沒有順序執行的原因,這裡我們在來回顧一下addEventListener
addEventListener
語法: target.addEventListener(type, listener[, useCapture])
useCapture 可選Boolean, 當useCapture為true 事件句柄在捕獲階段執行,也就是事件由外向内執行 當useCapture為false 事件句柄在冒泡階段執行,也就是事件由内向外執行
看到這也應該了解上面代碼為何會輸出1243了
好了,回來業務中,實際應用場景我們肯定不願同時觸發多個click, 在點擊子元素時我們不想觸發父元素的事, 這個時候我們就可以使用stopPropagation來停止事件冒泡
代碼理解
<div id="wrapper"> <button id ="event">JS每日一題=>事件處理程序</button> </div> const wrapper = document.getElementById('wrapper'); const event = document.getElementById('event'); wrapper.onclick = (e) => { console.log('捕獲階段執行父元素wrapper的事件處理程序') } event.onclick = (e) => { // 阻止事件冒泡 e.stopPropagation() console.log('冒泡階段執行子元素event的事件處理程序') }
上面的示例中我們使用了stopPropagation來阻止冒泡,所以此時隻會觸發一個事件了
總結
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!