摘要:事件冒泡由微軟提出,事件會(huì)從最內(nèi)從的元素開始發(fā)生,再向外傳播,正好與事件捕獲相反。為了解決上述問題,我們可以利用事件委托的思想,在父級(jí)注冊(cè)一個(gè)事件監(jiān)聽器,統(tǒng)一進(jìn)行子元素的事件處理。
原理
事件捕獲
由網(wǎng)景最先提出,事件會(huì)從最外層開始發(fā)生,直到最具體的元素,也就是說假如父元素與子元素都綁定有點(diǎn)擊事件,又互相重疊,那么先出發(fā)的會(huì)是父元素的事件,然后再傳遞到子元素。
事件冒泡
由微軟提出,事件會(huì)從最內(nèi)從的元素開始發(fā)生,再向外傳播,正好與事件捕獲相反。
這兩個(gè)概念都是為了解決頁面中事件流的發(fā)生順序,w3c采取了折中的辦法,制定了統(tǒng)一的標(biāo)準(zhǔn):先捕獲再冒泡。
addEventListeneraddEventListen(event, function, useCapture)添加事件的第三個(gè)參數(shù)默認(rèn)值為false,即默認(rèn)使用事件冒泡,若為true則使用事件捕獲的機(jī)制,以下為示例:
當(dāng)我們使用默認(rèn)事件注冊(cè)機(jī)制的時(shí)候,點(diǎn)擊child元素時(shí),會(huì)先后輸出child,container,這就是事件冒泡機(jī)制:
container.addEventListener("click", () => console.log("container")) child.addEventListener("click", () => console.log("child"))
將第三個(gè)參數(shù)設(shè)為true,點(diǎn)擊child元素時(shí),輸出順序就會(huì)變?yōu)閏ontainer、child:
container.addEventListener("click", () => console.log("container"), true) child.addEventListener("click", () => console.log("child"), true)
假若你希望點(diǎn)擊child只打印child,不觸發(fā)container的事件,我們就需要用到stopPropagation,它阻止捕獲和冒泡階段中當(dāng)前事件的進(jìn)一步傳播:
container.addEventListener("click", () => console.log("container")) child.addEventListener("click", (e) => { e.stopPropagation(); console.log("child"); })
若你想要點(diǎn)擊child只打印container,就需要進(jìn)行捕獲事件,并在container事件觸發(fā)時(shí)進(jìn)行阻止捕獲:
container.addEventListener("click", (e) => { e.stopPropagation(); console.log("container") }, true) child.addEventListener("click", () => console.log("child"), true)
與stopPropagation,還有一種事件方式叫做preventDefault,它的作用不是用于阻止冒泡,而是阻止瀏覽器默認(rèn)行為,如a標(biāo)簽跳轉(zhuǎn),表單提交等。
事件委托事件委托,又稱為事件代理,通俗來講是將元素的事件函數(shù)處理交由其他對(duì)象處理。它允許您避免向特定節(jié)點(diǎn)添加事件偵聽器,我們這里所談?wù)摰氖录?,與冒泡捕獲流程相關(guān),因此事件委托在此場(chǎng)景指的是子對(duì)象的處理事件交由父對(duì)象處理。
當(dāng)你需要為一個(gè)動(dòng)態(tài)的列表元素添加click事件時(shí),若直接對(duì)列表項(xiàng)綁定事件,可能會(huì)重復(fù)注冊(cè)很多個(gè)事件監(jiān)聽器。為了解決上述問題,我們可以利用事件委托的思想,在父級(jí)注冊(cè)一個(gè)事件監(jiān)聽器,統(tǒng)一進(jìn)行子元素的事件處理。
為了更好的說明,在這里舉一個(gè)示例:
為了給每一個(gè)li綁定上事件,若采用通常的方法,可能我們需要這樣寫代碼:
document.querySelectorAll(".item").forEach(item => { item.onclick = e => handleClick(e.target.dataset.id) })
但是列表數(shù)據(jù)可能會(huì)動(dòng)態(tài)的變化,這樣我們就避免不了動(dòng)態(tài)的去注冊(cè)事件,數(shù)量還可能很多,那有沒有什么一勞永逸的方法呢?當(dāng)然,讓我們使用事件委托的方法,也就是將點(diǎn)擊事件綁定到ul元素上:
document.querySelector(".list").onclick = e => { if (e.target.matches("li.item")) { handleClick(e.target.dataset.id) } }
值得注意的是,event.target代表事件起源目標(biāo)的引用,若要尋找當(dāng)前注冊(cè)事件對(duì)象的引用,請(qǐng)用event.currentTarget。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/102291.html
摘要:年初,許多事件使得被大眾所接受。這使得應(yīng)用程序更為迅捷地響應(yīng)用戶交互,并避免了在網(wǎng)絡(luò)上發(fā)送那些沒有改變的信息,減少用戶等待時(shí)間,帶來非常好的用戶體驗(yàn)。調(diào)用方法后立即觸發(fā),若未被調(diào)用則不會(huì)觸發(fā)此事件。 了解Ajax的起源、概念及特點(diǎn) 起源 該技術(shù)在1998年前后得到了應(yīng)用。允許客戶端腳本發(fā)送HTTP請(qǐng)求(XMLHTTP)的第一個(gè)組件由Outlook Web Access小組寫成。該組...
摘要:年初,許多事件使得被大眾所接受。這使得應(yīng)用程序更為迅捷地響應(yīng)用戶交互,并避免了在網(wǎng)絡(luò)上發(fā)送那些沒有改變的信息,減少用戶等待時(shí)間,帶來非常好的用戶體驗(yàn)。調(diào)用方法后立即觸發(fā),若未被調(diào)用則不會(huì)觸發(fā)此事件。 了解Ajax的起源、概念及特點(diǎn) 起源 該技術(shù)在1998年前后得到了應(yīng)用。允許客戶端腳本發(fā)送HTTP請(qǐng)求(XMLHTTP)的第一個(gè)組件由Outlook Web Access小組寫成。該組...
摘要:年初,許多事件使得被大眾所接受。這使得應(yīng)用程序更為迅捷地響應(yīng)用戶交互,并避免了在網(wǎng)絡(luò)上發(fā)送那些沒有改變的信息,減少用戶等待時(shí)間,帶來非常好的用戶體驗(yàn)。調(diào)用方法后立即觸發(fā),若未被調(diào)用則不會(huì)觸發(fā)此事件。 了解Ajax的起源、概念及特點(diǎn) 起源 該技術(shù)在1998年前后得到了應(yīng)用。允許客戶端腳本發(fā)送HTTP請(qǐng)求(XMLHTTP)的第一個(gè)組件由Outlook Web Access小組寫成。該組...
摘要:定位問題根據(jù)調(diào)用棧很快定位到了代碼,源碼定位到之前一位同事寫的組件代碼,大概是這樣的部分業(yè)務(wù)代碼報(bào)錯(cuò)的地方部分業(yè)務(wù)代碼發(fā)現(xiàn)是觸發(fā)了事件,因?yàn)闆]有這個(gè)字段,導(dǎo)致拋出異常。它的和鼠標(biāo)事件很像,非常容易遷移。 同步自我的博客,歡迎交流 這篇文章在草稿箱里躺了很久,因?yàn)樽罱钟龅搅讼嚓P(guān)問題,于是又整理了一下。請(qǐng)注意這里講的不是 css 的 pointer-events。 起因 從某個(gè)月黑風(fēng)高的...
摘要:子組件向父組件通信方法一使用事件父組件向子組件傳遞事件方法,子組件通過觸發(fā)事件,回調(diào)給父組件。非父子組件兄弟組件之間的數(shù)據(jù)傳遞非父子組件通信,官方推薦使用一個(gè)實(shí)例作為中央事件總線。 寫在前面 因?yàn)閷?duì)Vue.js很感興趣,而且平時(shí)工作的技術(shù)棧也是Vue.js,這幾個(gè)月花了些時(shí)間研究學(xué)習(xí)了一下Vue.js源碼,并做了總結(jié)與輸出。 文章的原地址:https://github.com/answ...
閱讀 1590·2021-11-23 10:01
閱讀 2978·2021-11-19 09:40
閱讀 3227·2021-10-18 13:24
閱讀 3481·2019-08-29 14:20
閱讀 2989·2019-08-26 13:39
閱讀 1282·2019-08-26 11:56
閱讀 2678·2019-08-23 18:03
閱讀 384·2019-08-23 15:35