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')
}
})
优点:可监听动态元素