概念
事件委托是依靠事件冒泡,只需要指定一個事件處理程序,綁定一次就可以處理一類的事件。舉個例子:假如有一個旅游團,其組成有旅游團公司 導游 旅行者。旅游團公司想征求下旅行者是否愿意更改路線,這里就有兩種方式了。第一種:旅游團公司直接和每個旅行者建立聯(lián)系,詢問是否愿意更改路線。第二種:旅游團公司直接和導游取得聯(lián)系,又導游來反饋給旅游團公司。其實第一種就是和每一個節(jié)點建立聯(lián)系,最直接,但是也是比較耗費資源的,第二種就是事件委托機制了,把聯(lián)系委托給導游,最終旅游者的意見會反饋到導游那里,然后旅游團公司再在導游那里做出反應。
優(yōu)點
減少資源消耗。因為每次綁定一個事件是需要消耗系統(tǒng)資源的,內存啊之類的。
減少dom操作,就可以減少頁面的重繪和結構重排,提升流暢性。
實例
<!-- 第一種比較簡單的 -->
<div id="公司">
<ul id="導游">
<li>123</li>
<li>345</li>
<li>567</li>
</ul>
</div>
var ul = document.getElementById("導游");
ul.addEventListener("click", function (event) {
event.target.style.color = "red";
console.log(event.target);
})
//<li>345</li> 等
<!-- 第二種,假如以下這種結構,我還是想將li的事件委托給ul來處理,怎么辦? -->
<div id="公司">
<ul id="導游">
<li>123</li>
<li>345</li>
<li><span>xx</span></li>
<li><span>xx <i>yy</i></span></li>
</ul>
</div>
//如果還是用之前的方法
var ul = document.getElementById("導游");
ul.addEventListener("click", function (event) {
event.target.style.color = "red";
console.log(event.target);
})
//則必然會出現(xiàn)
//<span>xx <i>yy</i></span> 這里觸發(fā)就沒有在li上了
//這里我的解決方案就是使用event下的另外一個屬性,path,這個屬性記錄了從根元素到event.target目標元素的觸發(fā)過程堆棧。
var ul2 = document.getElementById("導游");
ul2.addEventListener("click", function (event) {
var max = event.path.indexOf(event.currentTarget);
for (var i = max; i >= 0; i--) { //這里就在尋找 委托目標 和 實際觸發(fā)的目標之間 是否存在 li 元素,找到就表示存在,就執(zhí)行相應的動作即可
if (event.path[i].nodeName.toLowerCase() === 'li') {
event.path[i].style.color = "red";
console.log(event.path[i])
}
}
})