js delegate 实现
事件委托的实现原理
事件委托利用事件冒泡机制,将子元素的事件监听绑定到父元素上。当子元素触发事件时,事件会冒泡到父元素,通过判断事件源来执行对应操作。
document.getElementById('parent').addEventListener('click', function(event) {
if(event.target.matches('.child')) {
// 处理子元素点击逻辑
}
});
动态元素的事件处理
对于动态添加的子元素,传统事件绑定方式需要重复绑定,而事件委托只需在父元素绑定一次。

// 传统方式需要每次添加元素都绑定事件
const newChild = document.createElement('div');
newChild.className = 'child';
newChild.addEventListener('click', handler);
parent.appendChild(newChild);
// 事件委托方式
document.getElementById('parent').addEventListener('click', function(event) {
if(event.target.classList.contains('child')) {
handler(event);
}
});
性能优化建议
事件委托能显著减少事件监听器数量,提升页面性能。当页面中存在大量相似元素时,这种优势更加明显。

// 不推荐的写法(为每个元素绑定事件)
document.querySelectorAll('.item').forEach(item => {
item.addEventListener('click', handleClick);
});
// 推荐的委托写法
document.body.addEventListener('click', function(e) {
if(e.target.classList.contains('item')) {
handleClick(e);
}
});
复杂场景下的委托处理
当目标元素内部包含其他元素时,可能需要使用closest方法向上查找匹配元素。
document.getElementById('list').addEventListener('click', function(e) {
const item = e.target.closest('.list-item');
if(item) {
// 处理列表项点击
}
});
事件委托的注意事项
避免在document或window上绑定过多委托事件,应根据实际需要选择最近的公共父元素。同时注意事件冒泡可能带来的意外触发。
// 不推荐的全局委托
document.addEventListener('click', function(e) {
if(e.target.matches('.btn')) {
// 可能影响页面其他部分
}
});
// 建议限定作用范围
const container = document.getElementById('app');
container.addEventListener('click', function(e) {
if(e.target.matches('.btn')) {
// 仅处理容器内的按钮
}
});






