捕获是什么鬼?冒泡又是什么鬼?
e...这要从IE和网景的掐架说起
为啥子会掐架呢?
来~看图

2002年,W3C发布标准,DOM Level2 events Specification
规定浏览器支持两种调用顺序
先从外向内,然后从内向外找监听函数

addEventListener
addEventListener类似一个队列,用来添加事件监听
div.addEventListener('click',fn)//不写第三个参数默认为false,走冒泡
div.addEventListener('click',fn,true)//第三个参数为true,走捕获
同级事件调用顺序
先捕获后冒泡是父子事件调用顺序
同级事件调用是谁先监听先执行谁
e.target和e.currentTarget
e.targe 用户操作的元素
e.currentTarget 程序员监听的元素
sotpPropagation
e.sotpPropagation()可中断冒泡,一般用于封装某些独立的组件
不可取消冒泡
有些事件不可取消冒泡,比如scrol event,看到Bubbles和Cancelable

自定义事件
浏览器自带事件100多种 浏览器自带事件
button1.addEventListener('click',()=>{//自定义事件
const event = new CustomEvent('frank',{
defult:{name:'小可爱',age:18},
bubbles:true,
cancelable:false
})
button1.dispatchEvent(event)
})
button1.addEventListener('frank',(e)=>{//监听事件
console.log(e.default)
})
事件委托
通过监听父级元素为子级元素添加事件
- 假设现在有100个按钮,等冒泡的时候判断target是不是这100个按钮中的一个.
- 监听目前不存在的元素的点击事件
都和以通过监听父级元素,等点击的时候看是不是想要监听的那个元素。
优点:
省监听数(内存)
可以监听动态元素
div1.addEventListener('click',(e)=>{
if(e.target.tagName.toLowerCase() === 'button'){
console.log('button 被点击了')
}
})
封装事件委托
function on(eventType,element,selector,callback){
if(!(element instanceof Element)){
element = document.querySelector(element)
}
element.addEventListener(eventType,(e)=>{
const {target} = e
while(!target.matches(selector)){
if(element === el){
target = null
break
}
target = target.parentNode
}
target && fn.call(target,e,target)
if(){//判断点击的元素是不是我们要监听的元素
callback()
}
})
return element
}
on('click','#div1','button',(e)=>{
console.log('button 被点击了')
})