事件简介
常见浏览器事件
鼠标
click
contextmenu
mouseover/mouseout
mousedown/mouseup
mousemove
键盘
- keydown
- keyup
表单
- submit
- focus
Document事件
- DOMContentLoaded
CSS
- transitionend
移除一个处理程序——赋值为null
处理程序中的 this 的值是对应的元素。就是处理程序所在的那个元素
addEventListener
element.addEventListener(event, handler[, options]);
- options
once
:如果为 true ,那么会在被触发后自动删除监听器capture
:事件处理的阶段,我们稍后将在 冒泡和捕获 一章中介绍。由于历史原因, options 也可以是 false/true ,它与 {capture: false/true} 相同passive
:如果为 true ,那么处理程序将不会调用preventDefault()
- 用途:passive: true 选项告诉浏览器,处理程序不会取消滚动。然后浏览器立即滚动页面以提供最大程度的流畅体验,并通过某种方式处理事件。
移除处理程序 removeEventListener
element.removeEventListener(event, handler[, options])
- handler函数要与之前添加事件函数是同一个
事件对象
当事件发生时,浏览器会创建一个event
对象,将详细信息放入其中,并将其作为参数传递给处理程序
- event.type
- 事件类型
- event.currentTarget
- 与this相同(除非是箭头函数,或this被绑定其他东西)
- event.eventPhase
- 当前阶段(capturing=1,target=2,bubbling=3)
冒泡和捕获
冒泡
当一个事件发生在一个元素上,它会首先运行在该元素上的处理程序,然后运行其父元素上的处理程序,然后一直向上到其他祖先上的处理程序
几乎所有事件都是冒泡,例外:focus事件
event.target
- 父元素上的处理程序始终可以获取事件实际发生位置的详细信息
- 与this和event.currentTarget不同,它们是“当前”元素
停止冒泡
event.stopPropagation
- event.stopPropagation() 停止向上移动,但是当前元素上的其他处理程序都会继续运行。
- event.stopImmediatePropagation() 方法,可以用于停止冒泡,并阻止当前元素上的处理程序运行。使用该方法之后,其他处理程序就不会被执行
捕获
事件传播三个阶段
- 捕获阶段
- 事件(从 Window)向下走近元素
- 目标阶段
- 事件到达目标元素
- 冒泡阶段
事件是默认是冒泡,修改为捕获阶段的操作: capture 选项设置为 true。
用addEventListener添加事件为捕获时,移除的时候也要标注为捕获,这样才能正确删除处理程序
事件委托
如果我们有许多以类似方式处理的元素,那么就不必为每个元素分配一个 处理程序 —— 而是将单个处理程序放在它们的共同祖先上。
事件必须是冒泡
算法
- 在容器(container)上放一个处理程序
- 在处理程序中 —— 检查源元素 event.target
- 如果事件发生在我们感兴趣的元素内,那么处理该事件。
搭配下列方法,做事件委托
- event.target.closest(selector)
- 返回与 selector 匹配的最近的祖先
- selector1.containes(selector2)
- 检查selector2是否在selector1中
“行为”模式
使用事件委托将“行为(behavior)”以 声明方式 添加到具有特殊特性 (attribute)和类的元素中
行为模式分为两个部分
- 我们将自定义特性添加到描述其行为的元素
- 用文档范围级的处理程序追踪事件,如果事件发生在具有特定特性的元素上 —— 则执行行为(action)。
浏览器默认行为
阻止浏览器行为方式
- event.preventDefault()
- 如果处理程序是使用
on<event>
,则返回false也有效 - 如果默认行为被阻止,则event.defaultPrevented属性为true,否则为false
event.stopPropagation() 和 event.preventDefault()
之间毫无相关,一个是阻止冒泡,一个是阻止默认行为
创建自定义事件
构造器
new Event(type, [, options])
type: 类型
options
- bubbles: true/false —— 如果为 true ,那么事件会冒泡
- cancelable: true/false —— 如果为 true ,那么“默认行为”就会被阻止
- 如果 event.preventDefault() 应该有效,则 cancelable: true
`new CustomEvent(type, detail)
派发 dispatchEvent(event)
相当于触发了这个event事件
事件的发生顺序
事件中的事件是同步的,通常事件是在队列中处理的。也就是说:如果浏览器正在处理 onclick ,这时发生了 一个新的事件,例如鼠标移动了,那么它的处理程序会被排入队列,相应的 mousemove 处理程序将在 onclick 事件处理完成后被调用
但也有例外:一个事件是在另一个事件中发起的。例如使用 dispatchEvent 。这类事件将会被立即处理,即在新的事件处理程序被调用之后, 恢复到当前的事件处理程序
- 例如点击事件里面的处理程序中又派发了事件,则这类事件将会被立即处理