摘要:事件冒泡由微軟提出,事件會從最內從的元素開始發生,再向外傳播,正好與事件捕獲相反。為了解決上述問題,我們可以利用事件委托的思想,在父級注冊一個事件監聽器,統一進行子元素的事件處理。
原理
事件捕獲
由網景最先提出,事件會從最外層開始發生,直到最具體的元素,也就是說假如父元素與子元素都綁定有點擊事件,又互相重疊,那么先出發的會是父元素的事件,然后再傳遞到子元素。
事件冒泡
由微軟提出,事件會從最內從的元素開始發生,再向外傳播,正好與事件捕獲相反。
這兩個概念都是為了解決頁面中事件流的發生順序,w3c采取了折中的辦法,制定了統一的標準:先捕獲再冒泡。
addEventListeneraddEventListen(event, function, useCapture)添加事件的第三個參數默認值為false,即默認使用事件冒泡,若為true則使用事件捕獲的機制,以下為示例:
當我們使用默認事件注冊機制的時候,點擊child元素時,會先后輸出child,container,這就是事件冒泡機制:
container.addEventListener("click", () => console.log("container")) child.addEventListener("click", () => console.log("child"))
將第三個參數設為true,點擊child元素時,輸出順序就會變為container、child:
container.addEventListener("click", () => console.log("container"), true) child.addEventListener("click", () => console.log("child"), true)
假若你希望點擊child只打印child,不觸發container的事件,我們就需要用到stopPropagation,它阻止捕獲和冒泡階段中當前事件的進一步傳播:
container.addEventListener("click", () => console.log("container")) child.addEventListener("click", (e) => { e.stopPropagation(); console.log("child"); })
若你想要點擊child只打印container,就需要進行捕獲事件,并在container事件觸發時進行阻止捕獲:
container.addEventListener("click", (e) => { e.stopPropagation(); console.log("container") }, true) child.addEventListener("click", () => console.log("child"), true)
與stopPropagation,還有一種事件方式叫做preventDefault,它的作用不是用于阻止冒泡,而是阻止瀏覽器默認行為,如a標簽跳轉,表單提交等。
事件委托事件委托,又稱為事件代理,通俗來講是將元素的事件函數處理交由其他對象處理。它允許您避免向特定節點添加事件偵聽器,我們這里所談論的事件委托,與冒泡捕獲流程相關,因此事件委托在此場景指的是子對象的處理事件交由父對象處理。
當你需要為一個動態的列表元素添加click事件時,若直接對列表項綁定事件,可能會重復注冊很多個事件監聽器。為了解決上述問題,我們可以利用事件委托的思想,在父級注冊一個事件監聽器,統一進行子元素的事件處理。
為了更好的說明,在這里舉一個示例:
為了給每一個li綁定上事件,若采用通常的方法,可能我們需要這樣寫代碼:
document.querySelectorAll(".item").forEach(item => { item.onclick = e => handleClick(e.target.dataset.id) })
但是列表數據可能會動態的變化,這樣我們就避免不了動態的去注冊事件,數量還可能很多,那有沒有什么一勞永逸的方法呢?當然,讓我們使用事件委托的方法,也就是將點擊事件綁定到ul元素上:
document.querySelector(".list").onclick = e => { if (e.target.matches("li.item")) { handleClick(e.target.dataset.id) } }
值得注意的是,event.target代表事件起源目標的引用,若要尋找當前注冊事件對象的引用,請用event.currentTarget。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102291.html
摘要:定位問題根據調用棧很快定位到了代碼,源碼定位到之前一位同事寫的組件代碼,大概是這樣的部分業務代碼報錯的地方部分業務代碼發現是觸發了事件,因為沒有這個字段,導致拋出異常。它的和鼠標事件很像,非常容易遷移。 同步自我的博客,歡迎交流 這篇文章在草稿箱里躺了很久,因為最近又遇到了相關問題,于是又整理了一下。請注意這里講的不是 css 的 pointer-events。 起因 從某個月黑風高的...
摘要:子組件向父組件通信方法一使用事件父組件向子組件傳遞事件方法,子組件通過觸發事件,回調給父組件。非父子組件兄弟組件之間的數據傳遞非父子組件通信,官方推薦使用一個實例作為中央事件總線。 寫在前面 因為對Vue.js很感興趣,而且平時工作的技術棧也是Vue.js,這幾個月花了些時間研究學習了一下Vue.js源碼,并做了總結與輸出。 文章的原地址:https://github.com/answ...
閱讀 1574·2021-11-23 10:01
閱讀 2968·2021-11-19 09:40
閱讀 3214·2021-10-18 13:24
閱讀 3464·2019-08-29 14:20
閱讀 2979·2019-08-26 13:39
閱讀 1275·2019-08-26 11:56
閱讀 2661·2019-08-23 18:03
閱讀 373·2019-08-23 15:35