不知不覺每日的挑戰發文活動,也進行到22天了,這件事已經變成每日必做的事,像平日就是工作結束後,就是點開iT鐵人賽進行發文,而假日的話則是起床後,首要進行的事項,有時睡前還要確認下今天是不是已經發文了,就是要堅持的將挑戰完成!
今天要介紹的事件委派 Delegation 和 [Day 17] JS - 冒泡事件 (Event Bubbling) 所介紹的基礎觀念有關係,可以藉此再一併複習一次。
事件委派簡單說,在父層元素綁定一事件,當觸發子層的元素事件時,透過冒泡特性觸發父層的事件。
彭彭 - JavaScript 面試:事件傳遞機制和事件委託 Event Propagation & Event Delegation,從事件傳遞的基礎介紹,如:捕獲 (Capture) 和冒泡 (Bubble) 階段,而到事件委派的運作,以按鈕的區分、選項切換效果等範例說明。
我們希望 ul
下的列表,透過點擊1111
會印出111、點擊2222
會印出2222、點擊3333
會印出3333,預想會認為要在個別元素上去建立監聽事件。
<div id="box">
<ul id='my-list'>
<li >1111</li>
<li >2222</li>
<li >3333</li>
</ul>
</div>
li
元素,並一個個綁定事件// 取得容器
var myList = document.getElementById('my-list');
// 分別為 li 綁定事件
if (myList.hasChildNodes()) {
for (let i = 0; i < myList.childNodes.length; i++) {
// nodeType === 1 代表為實體 HTML 元素
if (myList.childNodes[i].nodeType === 1) {
myList.childNodes[i].addEventListener('click', function () {
console.log(this.textContent);
}, false);
}
}
}
li
// 建立新的 <li> 元素
var newList = document.createElement('li');
// 建立 textNode 文字節點
var textNode = document.createTextNode("Hello world!");
// 透過 appendChild 將 textNode 加入至 newList
newList.appendChild(textNode);
// 透過 appendChild 將 newList 加入至 myList
myList.appendChild(newList);
此時,會發現一個問題,就是後來才新增的 newList 節點並不會有 click 事件的註冊。因為新增新的li
,而需要再另外建立新的監聽事件,此方式變得繁雜且容易出錯。
my-list
執行,透過檢查事件的目標並判斷e.target
目標元素為li
,來判斷並獲取li
,再執行要click
的事宜。click
事件,當子層項目被點擊時,點擊事件就會從子層冒泡。li
元素,也會有click
的效果。// 取得容器
var myList = document.getElementById('my-list');
// 改讓外層 myList 來監聽 click 事件
myList.addEventListener('click', function (e) {
// 判斷目標元素若是 li 則執行 console.log
if (e.target.tagName.toLowerCase() === 'li') {
console.log(e.target.textContent);
}
}, false);
// 建立新的 <li> 元素
var newList = document.createElement('li');
// 建立 textNode 文字節點
var textNode = document.createTextNode("Hello world!");
// 透過 appendChild 將 textNode 加入至 newList
newList.appendChild(textNode);
// 透過 appendChild 將 newList 加入至 myList
myList.appendChild(newList);
data-* attribute
.delegate()
id='box'
的 div,它有綁定一個事件,所以必須要在 ul 的監聽事件,增加 event.stopPropagation();
避免冒泡渲染到外層。 <div id="box">
<ul id='my-list'>
<li data-id="li-1">001</li>
<li data-id="li-2">002</li>
<li data-id="li-3">003</li>
<li data-id="li-4">004</li>
</ul>
</div>
<script>
$(function () {
$("#my-list").delegate("li", "click", function (event) {
event.stopPropagation();
console.log($(this).data("id"))
});
$('#box').click(function (event) {
console.log('I am box');
})
})
</script>
1.讓語法更簡潔,減少建立多個且繁瑣的監聽事件。
2.可以方便地些改元素,不需因元素的更動,還需而外修改監聽事件。
3.使增進擷取元素的效能,且減少內存的佔用。