事件委托
利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
冒泡过程的传播路径为由内到外,利用此特点,不直接将监听器绑定至目标元素,而是绑定在其祖先元素上,由此也可实现一个监听器监听多个元素。
使用场景
- 需要同时监听多个子元素
<div id="div1">
<button>click 1</button>
<button>click 2</button>
<button>click 3</button>
<button>click 4</button>
<button>click 5</button>
</div>
<script>
div1.addEventListener('click', (e)=> {
//把目标元素赋给t
const t = e.target
// 判断是否匹配目标元素
if (t.tagName.toLowerCase() === 'button') {
console.log('button内容是:' + t.textContent);
}
});
</script>
通过在父元素div上绑定监听器,实现对其所有子元素的监听,与为每一个子元素绑定监听器相比,节省了内存。
- 监听动态元素/不存在的元素
<div id="div1">
</div>
<script>
setTimeout(()=>{
//div1里面延迟添加一个button
const button = document.creatElement('button')
button.textContent = 'click 1'
div1.appendChild(button)
},1000)
div1.addEventListener('click',(e)=>{
const t=e.target
if (t.tagName.toLowerCase() ==='button'){
console.log('button被click')
}
});
</script>
元素不存在时无法为其绑定监听器,可以通过对其父元素绑定监听器来实现监听。
封装事件委托
<div id="div1">
</div>
<script>
setTimeout(()=>{
const button = document.creatElement('button')
button.textContent = 'click 1'
div1.appendChild(button)
},1000)
on('click','#div1','button',()=>{
console.log('button被点击了')
})
function on(eventType, element, selector, fn){
//判断element是否为元素
if(!(element instanceof Element)){
element = document.querySelector(element)
//非元素则视为CSS选择器
}
element.addEventListener(eventType,(e)=>{
const t = e.target
//matches判断一个元素是否满足一个选择器
if(t.matches(selector)){
fn(e) //函数处理事件信息
}
})
}
</script>