DOM事件与事件委托

DOM事件模型与事件委托

DOM事件模型

捕获与冒泡

事件冒泡和捕捉是两种机制,主要描述当在一个元素上有两个相同类型的事件处理器被激活会发生什么。

当一个事件发生在具备父元素的元素上:html

捕获

在捕获阶段:浏览器

  • 浏览器检查元素的最外层祖先<html>,是否在捕获阶段中注册了一个onclick事件处理程序,若是是,则运行它。
  • 而后,它移动到<html>中单击元素的下一个祖先元素,并执行相同的操做,而后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。

冒泡

在冒泡阶段,偏偏相反:bash

  • 浏览器检查实际点击的元素是否在冒泡阶段中注册了一个onclick事件处理程序,若是是,则运行它
  • 而后它移动到下一个直接的祖先元素,并作一样的事情,而后是下一个,等等,直到它到达<html>元素。

示意图

事件捕获vs事件冒泡

当事件捕获和事件冒泡一块儿存在的状况,事件又是如何触发呢。
这里记被点击的DOM节点为target节点

app

  1. document 往 target节点,捕获前进,遇到注册的捕获事件当即触发执行
  2. 到达target节点,触发事件(对于target节点上,是先捕获仍是先冒泡则捕获事件和冒泡事件的注册顺序,先注册先执行)
  3. target节点 往 document 方向,冒泡前进,遇到注册的冒泡事件当即触发

    总结就是:
  • 对于非target节点则先执行捕获在执行冒泡
  • 对于target节点则是先执行先注册的事件,不管冒泡仍是捕获
  • 对于事件代理来讲,在事件捕获或者事件冒泡阶段处理并无明显的优劣之分,可是因为事件冒泡的事件流模型被全部主流的浏览器兼容,从兼容性角度来讲仍是建议你们使用事件冒泡模型。

addEventListener()

W3C给浏览器提供了一个函数 - addEventListener函数

  • 事件绑定API
    IE5*:baba.attachEvent('onclick',fn) //冒泡
    网景:baba.addEventListener('click',fn) //捕获
    W3C:baba.addEventListener('click',fn,bool)
  • 若是bool不传或为falsy
    就让fn走冒泡,即当前浏览器在冒泡阶段发现babafn监听函数,就会调用fn,并提供事件信息
  • 若是booltrue
    就让fn走捕获,即当浏览器在捕获阶段发现babafn监听函数,就会调用fn,并提供事件信息

事件委托

冒泡还容许咱们利用事件委托——这个概念依赖于这样一个事实,若是你想要在大量子元素中单击任何一个均可以运行一段代码,能够将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每一个子节点单独设置事件监听器。ui

举例1:

你要给多个按钮添加点击事件spa

<div id="div1">
<button>click 1</button>
<button>click 2</button>
<button>click 3</button>
<button>click 4</button>
<button>click 5</button>
<button>click 6</button>
<button>click 7</button>
<button>click 8</button>
<button>click 9</button>
</div>
复制代码

监听这些按钮的祖先,等冒泡的时候判断target是否是这写按钮中的一个代理

div.addEventListener('click',(e)=>{
    const t = e.target
    if(t.tagName.toLowerCase() === 'button'){
        console.log('button 被点击了')
    }
})
复制代码

举例2:

你要监听目前不存在的元素的点击事件code

<div id="div1">

</div>
复制代码

监听祖先元素,等点击的时候看看是否是我想要监听的元素便可cdn

setTimeout(()=>{
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')
    }
})
复制代码

封装事件委托

function on(eventType,element,selector, fn){
    if(!(element instanceof  Element)){
        element = document.querySelector(element)
    }
    element.addEventListener(evenType,(e)=>{
        const t = e.targer
        if(t.matches(selector)){
            fn(e)
        }
    })
}
复制代码
相关文章
相关标签/搜索