事件代理(Event Delegation)很簡單,主要是為了減少了事件監聽函數的數量,通過利用事件冒泡階段,将事件的處理放置在父元素上實作。
來看一個例子:
HTML上建立一個id為app的div:
<div id="app"></div>
建立ul清單和li,給每一個li添加一個監聽函數:
<script>
const ul = document.createElement('ul');
for (let i = 0; i < 10; i++) {
const li = document.createElement('li');
li.textContent = `This is line ${i}`;
li.addEventListener('click', () => {
console.log('Responding');
});
ul.appendChild(li);
}
document.getElementById('app').appendChild(ul);
</script>
上面形成的代碼效果如下:
由于每一個li都有對應的監聽函數,但是監聽函數都是一樣的,我們可以把函數提取出來:
<script>
const ul = document.createElement('ul');
function responding() {
console.log('Responding');
}
for (let i = 0; i < 10; i++) {
const li = document.createElement('li');
li.textContent = `This is line ${i}`;
li.addEventListener('click', responding);
ul.appendChild(li);
}
document.getElementById('app').appendChild(ul);
</script>
上面的代碼中,依舊有很多事件監聽函數指向同一個函數,仍然沒有解決問題,我們可以通過事件代理來實作相同的效果:
<script>
const ul = document.createElement('ul');
ul.addEventListener('click', event => {
if(event.target.nodeName.toLowerCase() === 'li'){
console.log('Responding');
}
});
for (let i = 0; i < 10; i++) {
const li = document.createElement('li');
li.textContent = `This is line ${i}`;
ul.appendChild(li);
}
document.getElementById('app').appendChild(ul);
</script>
很簡單,主要是在事件冒泡的階段,目标元素不設定監聽函數,而是在父元素上設定監聽函數,通過
event
對象的
target
屬性确定事件發生的目标元素,當目标元素一緻時,父元素上的監聽函數就進一步起作用。
最後
看到這裡,恭喜你完成了事件代理的學習 🎉🎉🎉