DOM事件模型与事件委托

166 阅读2分钟

捕获是什么鬼?冒泡又是什么鬼?

e...这要从IE和网景的掐架说起
为啥子会掐架呢?
来~看图

事件模型
反正就是谁也不服谁?那作为开发者就很懵逼了,我到底该用哪一个!所以w3c站出来当了和事佬
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

不可取消冒泡
scroll 事件不可取消冒泡,因为现有滚动才有滚动事件,要阻止滚动,可阻止whell和touchstart的默认动作

自定义事件

浏览器自带事件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)
})

事件委托

通过监听父级元素为子级元素添加事件

  1. 假设现在有100个按钮,等冒泡的时候判断target是不是这100个按钮中的一个.
  2. 监听目前不存在的元素的点击事件

都和以通过监听父级元素,等点击的时候看是不是想要监听的那个元素。
优点:
省监听数(内存)
可以监听动态元素

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 被点击了')
})