事件委托
事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown 等)委托给它的父元素,让父元素来监听子元素的冒泡事件,并在子元素发生事件冒泡时找到这个子元素。
举个简单的例子,整个宿舍的同学都需要去取快递,一种方法是让他们一个个去取,另一种方法是把这件事委托给宿舍长,让宿舍长把所有人的快递都取回来,然后再根据收件人一一分发给宿舍的同学。在这里,我们可以将取快递看作一个事件;每个同学看作是需要绑定事件的 DOM 元素;宿舍长看作是这些 DOM 元素的父元素,事件需要绑定在这个父元素上;按照收件人分发快递的过程就是事件执行的过程。
场景1:
要给100个按钮添加点击事件,咋办?
答:监听这个100个按钮的祖先,等冒泡的时候判断target是不是这100个按钮中的一个
代码:
场景2:
你要监听目前不存在的元素的点击事件?
答:监听祖先,等点击的时候看看是不是监听的元素即可。
优点:省监听数(内存),可以动态监听元素
代码:
封装一个事件委托
只要实行一个函数就可以实现事件委托
要求:
写出这样一个函数on('click','#testDiv','li',fn)
当用户点击#testDiv里面的li元素时,调用fn函数
要求用到事件委托
代码:
setTimeout(()=>{
const button = document.createElement('button')
const span = document.createElement('span')
span.textContent='click 1'
button.appendChild(span)
div1.appendChild(button)
},1000)
on('click','#div1','button',()=>{
console.log('button被点击了')
})
function on(eventType,element, selector, fn) {
if(!(element instanceof Element)){
element = document.querySelector(element)
}
element.addEventListener(eventType, e => {
let el = e.target
console.log(el)
while (!el.matches(selector)) {
if (element === el) {
el = null
break
}
el = el.parentNode
console.log(el)
}
el && fn.call(el, e, el)
})
return element
}