发送DOM事件是为了将发生的相关事情通知代码。每个事件都是继承自Event 接口的对象,可以包括自定义的成员属性及函数用于获取事件发生时相关的更多信息。
DOM事件流(调用顺序)
事件流又称为事件传播,描述的是从页面中接收事件的顺序。
- 事件捕获(capturing phase):事件按 window -> document -> html -> body -> ... -> 目标元素 的方向向下层元素传递。
- 事件冒泡(bubbling phase):事件开始时由最具体的元素(目标元素)接收,然后逐级向上传播。
parent.addEventListener('click',fn,bool)
// bool值为falsy或不传,冒泡;bool为true,捕获
注意
- 一般来说,事件流先进行事件捕获阶段,后进行事件冒泡阶段。
- 如果 ①只有一个div被监听;②用户点击的元素就是开发者监听的元素,则谁先被监听谁先执行。
- 捕获不可被取消,冒泡阶段可以
e.stopPropagation()- 有些事件的冒泡阶段不可中断,详见其
cancelable属性。
事件委托
把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件的方法称为事件委托(delegation)。
优点
- 在监听多个事件时省监听数,即省监听内存。
- 监听动态元素:可以监听目前不存在的事件
封装事件委托
function on (element, eventType, selector, fn) {
if (!(element instanceof Element)) {
element = document.querySelector(element)
}
element.addEventListener(eventType, e => {
let el = e.target //e在事件结束后“消亡”,用一个变量储存e的值
while (!el.matches(selector)) {
if (element === el) {
el = null
break //跳出循环,避免匹配到上层节点
}
el = el.parentNode
}
el && fn.call(el, e, el)
})
return element
}