利用?JS 事件冒泡動(dòng)態(tài)為元素綁定事件的方法稱為事件委托(Event Delegation飒责,也稱為“事件代理”),是 JavaScript 中最熱門的技術(shù)之一仿便。
事件委托就是把原本需要綁定在子元素上的事件(onclick靶累、onkeydown 等)委托給它的父元素顾患,讓父元素來監(jiān)聽子元素的冒泡事件暇检,并在子元素發(fā)生事件冒泡時(shí)找到這個(gè)子元素款熬。
舉個(gè)簡(jiǎn)單的例子深寥,整個(gè)宿舍的同學(xué)都需要去取快遞,一種方法是讓他們一個(gè)個(gè)去取贤牛,另一種方法是把這件事委托給宿舍長(zhǎng)惋鹅,讓宿舍長(zhǎng)把所有人的快遞都取回來,然后再根據(jù)收件人一一分發(fā)給宿舍的同學(xué)殉簸。在這里闰集,我們可以將取快遞看作一個(gè)事件;每個(gè)同學(xué)看作是需要綁定事件的 DOM 元素般卑;宿舍長(zhǎng)看作是這些 DOM 元素的父元素武鲁,事件需要綁定在這個(gè)父元素上;按照收件人分發(fā)快遞的過程就是事件執(zhí)行的過程椭微。
為什么要使用事件委托
在 JavaScript 中洞坑,頁面內(nèi)事件處理程序的個(gè)數(shù)會(huì)直接影響頁面的整體性能,因?yàn)槊總€(gè)事件處理程序都是對(duì)象蝇率,對(duì)象會(huì)占用內(nèi)存迟杂,內(nèi)存中的對(duì)象越多,頁面的性能則越差本慕。此外排拷,事件處理程序需要與 DOM 節(jié)點(diǎn)進(jìn)行交互,訪問 DOM 的次數(shù)越多锅尘,引起瀏覽器重繪和重排的次數(shù)也就越多监氢,從而影響頁面的性能布蔗。
重繪是指當(dāng)元素樣式改變時(shí),瀏覽器會(huì)根據(jù)元素的新樣式重新繪制元素的外觀浪腐。重排是指當(dāng) DOM 樹的一部分發(fā)生變化時(shí)(例如元素尺寸改變)纵揍,瀏覽器會(huì)重新創(chuàng)建 DOM 樹。
當(dāng)頁面中很多表格或列表需要添加事件時(shí)议街,如果逐個(gè)添加那就太麻煩了泽谨,但是使用事件委托就能極大的減輕我們的工作量,同時(shí)也能提高頁面的性能特漩。
事件委托實(shí)現(xiàn)原理
事件委托是利用事件的冒泡原理來實(shí)現(xiàn)的吧雹,大致可以分為三個(gè)步驟:
1.確定要添加事件元素的父級(jí)元素;
2.給父元素定義事件涂身,監(jiān)聽子元素的冒泡事件雄卷;
3.使用 event.target 來定位觸發(fā)事件冒泡的子元素。
注意:使用事件委托時(shí)蛤售,并不是說把事件委托給隨意一個(gè)父元素就行丁鹉。因?yàn)槭录芭莸倪^程也需要消耗時(shí)間,距離越遠(yuǎn)悴能,所需的時(shí)間也就越長(zhǎng)鳄炉,所有最好在直接父元素上使用事件委托。
通過上面的代碼可以看出搜骡,要為每個(gè) li 標(biāo)簽綁定點(diǎn)擊事件拂盯,首先需要找到 ul 標(biāo)簽,然后通過 ul 標(biāo)簽找到所有 li 標(biāo)簽记靡, 最后在通過遍歷所有 li 標(biāo)簽來綁定事件谈竿。若使用事件委托的話,就會(huì)簡(jiǎn)單很多摸吠,示例代碼如下:
通過代碼可以看出空凸,使用事件委托我們只需要為 ul 標(biāo)簽綁定事件,當(dāng) li 標(biāo)簽被點(diǎn)擊時(shí)寸痢,由于事件冒泡的特性呀洲,會(huì)觸發(fā) ul 標(biāo)簽上的事件,我們只需要在事件中通過 event 對(duì)象中的 target 屬性來找到被點(diǎn)擊的 li 標(biāo)簽即可啼止。不過這樣做也有一個(gè)弊端道逗,那就是當(dāng)我們點(diǎn)擊 ul 標(biāo)簽時(shí),也會(huì)觸發(fā)事件献烦。
另外滓窍,如果我們需要?jiǎng)討B(tài)的向 ul 標(biāo)簽中添加 li 標(biāo)簽,同時(shí)也需要在新添加的 li 標(biāo)簽中添加點(diǎn)擊事件巩那,就必須通過事件委托來實(shí)現(xiàn)了吏夯,示例代碼如下: