DOM 事件模型和事件委托

172 阅读2分钟

DOM 事件模型

用户点击一下鼠标,按一下按钮都对应着一个事件。 DOM 事件模型则通过监听函数对事件做出反应。事件发生后,浏览器监听到了这个事件,就会执行对应的监听函数。

监听函数

监听函数有三种方式,分别是 on- 属性,元素节点的事件属性,和 addEventListener

前两者都有局限性所以用的不多,通常采用第三种方式来监听事件。

window.addEventListener('click', ()=>console.log('事件触发'), true)
// 参数1为事件类型, 参数2为执行函数, 参数3为true走事件捕获,为falsy走事件冒泡,默认为false

事件流

点击 td 后,事件流触发顺序为先捕获后冒泡。

事件捕获window 对象传导到目标节点,从顶至下

事件冒泡 从目标节点传导到 window 对象,从底至上

事件委托

由父元素的监听函数处理一个或多个子元素的事件,这种方法叫做事件委托。

场景一

同时监听一堆元素

问:如果需要给100个按钮添加点击事件,怎么办?

答:监听这100个按钮的父元素,等冒泡的时候再判断 target 是不是这100按钮中的一个

<div id="div1">
    <button data-id=1>
        click 1
    </button>
    <button>
        ...
    </button>
    <button>
        click 100
    </button>
</div>
div.addEventListener('click', (e)=>{
    const t = e.target
    if(t.tagName.toLowerCase() === 'button') {
        console.log('button 被点击了')
        console.log('button data-id 是' + t.dataset.id)
    }
})

优点:省监听数量

场景二

监听目前不存在的元素

问:如何监听目前不存在的元素的点击事件?

答:监听它的父元素,用户点击时判断点击的是否是要监听的元素即可

// 一秒钟后创建一个 button
setTimeout(()=>{
    const button = document.createElement('button')
    button.textContent = 'click 1'
    div1.appendChild(button)
})
div1.addEventListener('click', (e)=>{
    const t = e.target
    if(t.tagName.toLowerCase() === 'button'){
        console.log('button 被 click')
    }
})

优点:可监听动态元素