事件简介

常见浏览器事件

  1. 鼠标

    • click

    • contextmenu

    • mouseover/mouseout

    • mousedown/mouseup

    • mousemove

  2. 键盘

    • keydown
    • keyup
  3. 表单

    • submit
    • focus
  4. Document事件

    • DOMContentLoaded
  5. 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() 方法,可以用于停止冒泡,并阻止当前元素上的处理程序运行。使用该方法之后,其他处理程序就不会被执行

捕获

事件传播三个阶段

  1. 捕获阶段
    • 事件(从 Window)向下走近元素
  2. 目标阶段
    • 事件到达目标元素
  3. 冒泡阶段

事件是默认是冒泡,修改为捕获阶段的操作: capture 选项设置为 true。

用addEventListener添加事件为捕获时,移除的时候也要标注为捕获,这样才能正确删除处理程序

事件委托

如果我们有许多以类似方式处理的元素,那么就不必为每个元素分配一个 处理程序 —— 而是将单个处理程序放在它们的共同祖先上。

事件必须是冒泡

算法

  1. 在容器(container)上放一个处理程序
  2. 在处理程序中 —— 检查源元素 event.target
  3. 如果事件发生在我们感兴趣的元素内,那么处理该事件。

搭配下列方法,做事件委托

  • event.target.closest(selector)
    • 返回与 selector 匹配的最近的祖先
  • selector1.containes(selector2)
    • 检查selector2是否在selector1中

“行为”模式

使用事件委托将“行为(behavior)”以 声明方式 添加到具有特殊特性 (attribute)和类的元素中

行为模式分为两个部分

  1. 我们将自定义特性添加到描述其行为的元素
  2. 用文档范围级的处理程序追踪事件,如果事件发生在具有特定特性的元素上 —— 则执行行为(action)。

浏览器默认行为

阻止浏览器行为方式

  • event.preventDefault()
  • 如果处理程序是使用on<event>,则返回false也有效
  • 如果默认行为被阻止,则event.defaultPrevented属性为true,否则为false

event.stopPropagation() 和 event.preventDefault()

之间毫无相关,一个是阻止冒泡,一个是阻止默认行为

创建自定义事件

构造器

  1. new Event(type, [, options])

    • type: 类型

    • options

      • bubbles: true/false —— 如果为 true ,那么事件会冒泡
      • cancelable: true/false —— 如果为 true ,那么“默认行为”就会被阻止
        • 如果 event.preventDefault() 应该有效,则 cancelable: true
  2. `new CustomEvent(type, detail)

派发 dispatchEvent(event)

相当于触发了这个event事件

事件的发生顺序

事件中的事件是同步的,通常事件是在队列中处理的。也就是说:如果浏览器正在处理 onclick ,这时发生了 一个新的事件,例如鼠标移动了,那么它的处理程序会被排入队列,相应的 mousemove 处理程序将在 onclick 事件处理完成后被调用

但也有例外:一个事件是在另一个事件发起的。例如使用 dispatchEvent 。这类事件将会被立即处理,即在新的事件处理程序被调用之后, 恢复到当前的事件处理程序

  • 例如点击事件里面的处理程序中又派发了事件,则这类事件将会被立即处理