事件委托
事件委托,本质其实很好理解
就是「监听祖先元素」,可以想象为中介帮忙租房子
场景一
你要给100个按钮添加点击事件,咋办?答案:监听这100个按钮的祖先,等冒泡的时候再判断target是不是这100个按钮中的一个
JS Binjs.jirengu.com
拓展API
data-id
dataset获取
dataset(API)可以获取以"data-"开头的属性的值
更多相关data使用技巧链接:
HTMLElement.datasetdeveloper.mozilla.org
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SM1EWO5UDZyM2YlZTZmhzYkZmZiRzYiFWNxQmN2QGMj9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
js中的dataset问题_qq_39579242的博客-CSDN博客_datasetblog.csdn.net
场景二
你要监听目前不存在的元素的点击是事件,咋办?答案:监听祖先,等点击的时候看看是不是我想要监听的元素即可
- 优点:
省监听数量(省内存)
可以监听动态元素
■ 封装事件委托
要求:
- 写出这样一个函数on('click','#testDiv','li',fn)
- 当用户点击#testDiv里的li元素时,调用fn函数
- 要求用到事件委托
- 答案一
判断target是否匹配'li'示例代码:
JS Binjs.jirengu.com
拓展:matches()API
如果为true则匹配,为false则不匹配matches()API:查看是否为对应的选择器
官方:如果元素被指定的选择器字符串,选择Element.matches()方法返回true,否则false
Element.matches()developer.mozilla.org
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SM1EWO5UDZyM2YlZTZmhzYkZmZiRzYiFWNxQmN2QGMj9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
t.matches(selector) 相等 t.tagName.toLowCase===selector
- 注意:on函数中参数element有可能为字符串或Element(元素对象)
所以要加前提条件
if(!(element instanceof Element)){
element=document.querySelector(element)
}
插曲
刚刚我们通过on函数实现了事件委托
实际上这个答案是错的
但是这个答案会在面试的时候是可以的
面试题:什么是事件委托?
答案:给元素添加监听,查看target是否满足selector(选择器),满足则调用函数fn,不满足则跳过!
写法一:
div1.addEventListener('click',(e)=>{
const t=e.target
if(t.matches(selector)){
console.log('button被点击了')//符合则打印
}
})
————————————————————
写法二:
div1.addEventListener('click',(e)=>{
const t=e.target
if(t.tagName.toLowerCase()==='button'){
console.log('button被点击了')//符合则打印
}
})
为什么是错的呢?
变态:如<button>标签内有放入<span>,<span>标签才是click1文本,这时点击后则失败
因为这是的target从'button'变成了'span','span'不等于'button'(selector),所以会失败。
那么如何解决呢?
答案二:递归判断 target儿/target爸/target爷(一层层向上查找)
JS Binjs.jirengu.com
整合进jQuery
有兴趣可以自己实现$('#xxx').on('click','li',fn)
JS支持事件吗
答案:支持,也不支持。本文章讲的DOM事件不属于JS的共呢个,属于浏览器提供DOM的功能(DOM事件与JS是平级)
JS只是调用了DOM提供的addEventListener而已
- 追问
如何当JS支持事件?请手写一个事件系统?
后期回讲