20k的前端是這樣寫(xiě)事件委托的
“作者:純純純爺們 鏈接:https://juejin.cn/post/6844904097372438542 來(lái)源:稀土掘金
”

要理解DOM相關(guān)事件,我們先要理解“事件流”這個(gè)概念,事件流描述的是從頁(yè)面中接收事件的順序。
事件冒泡:事件開(kāi)始由最具體的元素接收,然后逐級(jí)向上傳播到較為不具體的節(jié)點(diǎn)或文檔。
事件捕獲:事件開(kāi)始由不太具體的節(jié)點(diǎn)接收,然后逐級(jí)向下傳播到最具體的節(jié)點(diǎn)。它與事件冒泡是個(gè)相反的過(guò)程。
DOM2 級(jí)事件規(guī)定的事件流包括三個(gè)階段:事件捕獲、目標(biāo)階段、事件冒泡。
事件委托
事件委托,通俗的說(shuō)就是將元素的事件委托給它的父級(jí)或者更外級(jí)的元素處理,它的實(shí)現(xiàn)機(jī)制就是事件冒泡。
假設(shè)有一個(gè)列表,要求點(diǎn)擊列表項(xiàng)彈出對(duì)應(yīng)的字段:
"myLink">
??- "1">aaa
??- "2">bbb
??- "3">ccc
不使用事件委托
var?myLink?=?document.getElementById('myLink');
var?li?=?myLink.getElementsByTagName('li');
for(var?i?=?0;?i???li[i].onclick?=?function(e)?{
????var?e?=?event?||?window.event;
????var?target?=?e.target?||?e.srcElement;
????alert(e.target.id?+?':'?+?e.target.innerText);??
??};
}
存在問(wèn)題:
給每一個(gè)列表都綁定事件,消耗內(nèi)存 當(dāng)有動(dòng)態(tài)添加的元素時(shí),需要重新給元素綁定事件
8k的前端寫(xiě)出的事件委托
事實(shí)上很多同學(xué)在網(wǎng)上看到的事件委托的方法都是錯(cuò)的,雖然是錯(cuò)的,但是你面試的時(shí)候也可能會(huì)過(guò),因?yàn)槊婺愕拿嬖嚬倏赡芤膊恢勒_的事件委托應(yīng)該怎么寫(xiě)。
下面我們就來(lái)看一下錯(cuò)誤版的事件委托是怎么寫(xiě)的:
?ul.addEventListener('click',?function(e){
?????if(e.target.tagName.toLowerCase()?===?'li'){
?????????fn()?//?執(zhí)行某個(gè)函數(shù)
?????}
?})
20k的前端寫(xiě)出的事件委托
錯(cuò)誤版事件委托的bug 在于,如果用戶點(diǎn)擊的是 li里面的 span,就沒(méi)法觸發(fā) fn,這顯然不對(duì)。那下面我們來(lái)看一下正確的事件委托應(yīng)該怎么寫(xiě):
function?delegate(element,?eventType,?selector,?fn)?{
?????element.addEventListener(eventType,?e?=>?{
???????let?el?=?e.target
???????while?(!el.matches(selector))?{
?????????if?(element?===?el)?{
???????????el?=?null
???????????break
?????????}
?????????el?=?el.parentNode
???????}
???????el?&&?fn.call(el,?e,?el)
?????})
?????return?element
???}
思路是點(diǎn)擊 span后,遞歸遍歷 span 的祖先元素看其中有沒(méi)有 ul 里面的 li。
事件委托的優(yōu)點(diǎn)
只需要將同類元素的事件委托給父級(jí)或者更外級(jí)的元素,不需要給所有的元素都綁定事件,減少內(nèi)存占用空間,提升性能。
動(dòng)態(tài)新增的元素?zé)o需重新綁定事件
需要注意的點(diǎn)
事件委托的實(shí)現(xiàn)依靠的冒泡,因此不支持事件冒泡的事件就不適合使用事件委托。 不是所有的事件綁定都適合使用事件委托,不恰當(dāng)使用反而可能導(dǎo)致不需要綁定事件的元素也被綁定上了事件。
“告誡自己,即使再累也不要忘記學(xué)習(xí),成功沒(méi)有捷徑可走,只有一步接著一步走下去。共勉!文章中如有不對(duì)的地方,歡迎小伙伴們多多指正。謝謝大家~ ??
”





