1、為什么要進行事件委托?
首先實現一個小功能:在單擊 HTML 的按鈕后,把消息輸出到控制臺。
為了實現這個小功能,你需要選擇按鈕,然后再用 addEventListener() 方法來附加事件監聽器:
<button id="buttonId">Click me</button>
<script>
document.getElementById('buttonId')
.addEventListener('click', () => console.log('Clicked!'));
</script>
以上就是偵聽單個元素(尤其是按鈕)上事件的方式。
如果需要監聽多個按鈕上的事件呢?下面是一種可能的實現:
<div id="buttons">
<button class="buttonClass">Click me</button>
<button class="buttonClass">Click me</button>
<!-- buttons... -->
<button class="buttonClass">Click me</button>
</div>
<script>
const buttons = document.getElementsByClassName('buttonClass');
for (const button of buttons) {
button.addEventListener('click', () => console.log('Clicked!'));
}
</script>
按鈕列表被迭代為 for (const button of buttons) ,并且每個按鈕都被附加了一個新的偵聽器。另外在列表中的按鈕被添加或刪除后,你必須還要手動刪除或附加事件監聽器。
有沒有更好的方法?
幸運的是,如果我們使用“事件委托”模式的話,偵聽多個元素上的事件只需要一個事件偵聽器。
事件委托使用事件傳播機制的細節。想要要了解事件委托的工作原理,應該先了解什么是事件傳播。
2、事件傳播
點擊事件會觸發多少個元素?毫無疑問,按鈕本身會收到單擊事件。而且所有按鈕的祖先,甚至包括 document 和 window 對象也會收到。
點擊事件的傳播分三個階段:
1.捕獲階段 —— 從window,document 和根元素開始,事件向下擴散至目標元素的祖先
2.目標階段 —— 事件在用戶單擊的元素上觸發
3.冒泡階段——最后,事件冒泡通過目標元素的祖先,一直到根元素 document 和 window。
addEventListener 方法的第三個參數 captureOrOptions:
element.addEventListener(eventType, handler[, captureOrOptions]);
使你可以捕獲來自不同階段的事件。
如果缺少 captureOrOptions 參數,或者參數為 false 或 {capture:false},那么偵聽器將捕獲目標(target)和 冒泡階段(bubble phases)的事件
如果參數是 true 或 {capture:true},那么偵聽器將會偵聽捕獲階段(capture phase)的事件。
通過下面的代碼,你會偵聽到在 <body> 元素上發生的捕獲階段的點擊事件:
document.body.addEventListener('click', () => {
console.log('Body click event in capture phase');
}, true);
那么事件傳播是怎樣幫助捕獲多個按鈕事件的呢?
該算法很簡單:把事件偵聽器附加到按鈕的父級,并在單擊按鈕時捕獲冒泡事件。這就是事件委托的工作方式。
3、事件委托
讓我們用事件委托來捕獲多個按鈕上的點擊:
<div id="buttons"> <!-- Step 1 -->
<button class="buttonClass">Click me</button>
<button class="buttonClass">Click me</button>
<!-- buttons... -->
<button class="buttonClass">Click me</button>
</div>
<script>
document.getElementById('buttons')
.addEventListener('click', event => { // Step 2
if (event.target.className === 'buttonClass') { // Step 3
console.log('Click!');
}
});
</script>
事件委托的思想很簡單。你不需要把委托事件監聽器直接附加到按鈕上,而是可以委托父監聽 <div id="buttons">。單擊按鈕時,父元素的偵聽器將會捕獲冒泡事件(還記得前面所說事件傳播嗎?)。
使用事件委托需要3個步驟:
步驟1:確定要監視事件的元素的父級元素
在上面的例子中, <div id="buttons"> 是按鈕的父元素。
步驟2:把事件偵聽器附加到父元素
document.getElementById('buttons') .addEventListener('click', handler) 將事件偵聽器附加到按鈕的父元素。該事件偵聽器也會對按鈕單擊做出反應,因為按鈕單擊事件冒泡通過祖先元素(由于事件傳播)。
步驟3:用 event.target 選擇目標元素
單擊按鈕時,將會用event 對象參數調用處理函數。屬性 event.target 訪問在其上調度了事件的元素,在例子中是一個按鈕:
// ...
.addEventListener('click', event => {
if (event.target.className === 'buttonClass') {
console.log('Click!');
}
});
順便說明一下,event.currentTarget 指向事件偵聽器直接附加到的元素。在例子中,event.currentTarget 是 <div id="buttons">。
現在,你可以看到事件委托模式的好處:事件委托僅需要一個事件偵聽器,而不必像本文最初那樣將偵聽器附加到每一個按鈕上。
總結
當發生點擊事件(或傳播的任何其他事件)時:
事件從 window、document、根元素向下傳播,并經過目標元素的祖先(捕獲階段);
事件發生在目標(目標階段)上;
最后,事件在目標祖先之間冒出氣泡,直到根元素 document 和 window(冒泡階段)。
該機制稱為事件傳播。
事件委托是一種有用的模式,因為你可以只需要用一個事件處理程序就能偵聽多個元素上的事件。
使用事件委托需要三個步驟:
1.確定要監視事件的元素的父級元素
2.把將事件偵聽器附加到父元素
3.用 event.target 選擇目標元素
猜你喜歡
聯絡方式:
電話:132 5357 1993
郵箱:1069484130@qq.com



-
什么是本地區關鍵詞全國性關鍵詞?
地區性關鍵詞:是指關鍵詞中帶有地區名稱,如:關鍵詞為“深圳網站建設公司”,該詞為地區性關鍵詞,因為關鍵詞中出現了地區名稱“深圳”。全國性關鍵詞:是指關鍵...
-
企業標志LOGO如何確定?請記住這5點!
對于很多甲方企業客戶來說,因為自己公司沒有專業品牌管理團隊和品牌形象管理總監,當他們面對專業品牌設計公司提供的企業標志LOGO設計方案的時候,很難從提供的方案中進行正確選擇,而對于LOGO標志設計師的創意詮釋和推薦,有的時候也表現的難以定奪,所以這成為很多企業在進行選擇時的一個大大的問號。今天,就由專業的網站建設公司深正互聯來分享如何正確選擇LOGO標志?...
-
商家揭秘:讓你剁手的19個“潛規則”
很早之前就有一個說法,淘寶是女人的天下,京東是男人的天下,但目前崛起的很多電子商務網站,如聚美優品、蘑菇街、唯品會卻更針對的是女性群體。有的人覺得女性購物好做,有的人覺得...
-
讓新手快速熟悉的四個網站設計技巧
如何吸引用戶點擊停留?是網站設計非常重要的方向,現在就讓小編給大家介紹一定要知道的四個網站設計技巧! 1、網站簡潔又個性的設計 在互聯網絡中4秒就是用戶給網站設計者的展法工夫。用戶的急躁是無限的,網站設計師務必要在無限的工夫內讓用戶加深對網站的記憶和互動。這就務求網站設計師務必要精準、簡潔的轉達出網站最做什么的、網站的性能是什么等用戶想要曉得的信息。 2、網站設計標點符號 網站中的每一個標點符號的設計都有可能吸引到用戶點擊,因而網站設計師在繼續網站設計時定然要準確到標點符號,讓相反...
-
資深程序猿意見:選redis還是memcache?
memcache和redis是互聯網分層架構中,最常用的KV緩存。不少同學在選型的時候會糾結,到底是選擇memcache還是redis。 畫外音:不鼓勵粗暴的實踐,例如“memcache提供的功能是redis提供的功能的子集,不用想太多,選redis準沒錯”。 雖然redis比memcache更晚出來,且功能確實也更豐富,但對于一個技術人,了解“所以然”恐怕比“選擇誰”更重要一些。 網站開發公司.jpg 什么時候傾向于選擇redis? 業務需求決定技術選型,當業務有這樣一些特...