前言
很久沒(méi)有在簡(jiǎn)書(shū)上寫(xiě)blog床蜘,都在github上寫(xiě)了杀狡,看有點(diǎn)時(shí)間就搬運(yùn)一下
關(guān)于事件委托的概念和原理就不多說(shuō)锈嫩,自行Google衍慎。
二層元素實(shí)現(xiàn)的委托
二層元素實(shí)現(xiàn)的委托是我自己定義的名稱(chēng),具體是如下的場(chǎng)景
<div id="tab">
<a href="javascript:;" title="left">left</dl>
<a href="javascript:;" title="right">right</dl>
</div>
然后將事件綁定在id="tab"
元素上命迈。這樣的場(chǎng)景也是在比較多的贩绕,高程對(duì)事件委托的解析也是用以上差不多的代碼解析的,具體實(shí)現(xiàn)是這樣的:
先是將事件綁定在id="tab"
元素上壶愤,點(diǎn)擊是判斷title淑倾,title === ‘left’
時(shí)觸發(fā)left的邏輯,否則觸發(fā)right
的邏輯
document.querySelector('#tab')
.addEventListener('touchstart', e => {
const target = e.target;
if(target.title === 'left') {
// left的邏輯代碼
} else {
// right的邏輯代碼
}
}, false);
這樣的代碼乍看之下貌似沒(méi)有問(wèn)題征椒,但是娇哆,加入是下面的html代碼就會(huì)出現(xiàn)bug:
<div id="tab">
<a href="javascript:;" title="left"><img src="left_icon.png"> left</a>
<a href="javascript:;" title="right"><img src="right_icon.png"> right</a>
</div>
當(dāng)點(diǎn)擊a便簽的圖標(biāo),就會(huì)出現(xiàn)bug勃救,只要是點(diǎn)擊中圖標(biāo)碍讨,無(wú)論是點(diǎn)擊left還是right都會(huì)是觸發(fā)right的邏輯,
為什么蒙秒?因?yàn)辄c(diǎn)擊中icon的話勃黍,e.target
是img便簽,而不是a便簽晕讲,而img并沒(méi)有title覆获,如果你說(shuō)可以給img便簽也可以添加title,但這不是一個(gè)之便不治本的解決方案嗎瓢省?加入a便簽內(nèi)有更多的后代元素怎么辦弄息?全都添加title嗎?明顯不現(xiàn)實(shí)勤婚。
event.path屬性實(shí)現(xiàn)委托
使用console.log(e)
點(diǎn)path屬性摹量,你可以卡到path是一個(gè)數(shù)組
升序正好是冒泡順序,正好可以利用這個(gè)順序?qū)崿F(xiàn)多層元素的事件委托。
document.querySelector('#tab')
.addEventListener('touchstart', e => {
const path = e.path;
for (let index = 0; index < path.length; index++) {
const element = path[index];
if(element.title === 'left') {
// left
break;
} else if(element.title === 'right') {
// right
break;
}
}
}, false);
event.composedPath()
雖說(shuō)以上代碼已經(jīng)可以實(shí)現(xiàn)多級(jí)元素的事件委托荆永,但是不幸的是path的兼容性是比較差[捂臉]
看上面的引用废亭,可以知道path
并非標(biāo)準(zhǔn)的,而composedPath
才是標(biāo)準(zhǔn)的具钥,但也是比較新的,換言之液兽,兼容性也不會(huì)有多好骂删,但path
和composedPath
一起使用,兼容必然會(huì)更高四啰。
document.querySelector('#tab')
.addEventListener('touchstart', e => {
const path = e.path || e.composedPath();
for (let index = 0; index < path.length; index++) {
const element = path[index];
if(element.title === 'left') {
// left
break;
} else if(element.title === 'right') {
// right
break;
}
}
}, false);
小結(jié)
以上實(shí)現(xiàn)委托的方法是我自己自行意淫的宁玫,是不是主流實(shí)現(xiàn)方法?我還還沒(méi)有去驗(yàn)證柑晒,先留個(gè)坑欧瘪,誰(shuí)那么巧合看到了我的文章,有更好的想法匙赞,或者主流方法實(shí)現(xiàn)佛掖,請(qǐng)不吝賜教。