Skip to content

浏览器事件(Event) #208

Open
@yaofly2012

Description

@yaofly2012

一、浏览器事件

MDN Introduction to events

1.1 事件传播

一个事件对象一般经历捕获,执行,冒泡三个阶段。
image

  1. 整个过程中事件对象是同一个,即所有的事件处理函数操作的是同一个对象;
  2. 所有的事件都会有捕获阶段,但是并不是所有的事件都会经历冒泡阶段(比如focus事件);

各阶段Event.currentTarget, Event.targetEvent.eventPhase的取值

image

  1. Event.eventPhase表示事件对象所处的阶段;
  2. 传播过程中Event.target取值始终不变,即使事件处理完毕后;
  3. 传播过程中Event.currentTarget取值表示当前绑定事件处理函数的EventTarget对象,所以会变;并且事件处理完毕后Event.currentTarget都会变成null
    当心异步访问Event.currentTarget

阻止传播

  1. Event.cancelBubble=true/Event.stopPropagation/Event.stopImmediatePropagation阻止传播,在各阶段调用都有效;
  2. Event.cancelBubble=true和Event.stopPropagation`是等价的。

1.2 绑定事件的方式

3中方式

  1. html特性
  2. DOM的onXXX属性
  3. addEventListener
    IE兼容attachEvent

1.2 触发事件

除了用户触发事件外,还可以通过JS直接触发事件。但是两种方式存在差异。

JS触发

  • JS里触发事件(dispatchEvent, HTMLElement.click, HTMLElement.focus)是同步的;
  • 事件处理函数都是同步调用的;
  • 整个冒泡和捕获流程中都是同步执行的。
<button id="btn">click</button>
<script>
 var oBtn = document.getElementById('btn')
    oBtn.addEventListener('click', function () {
        Promise.resolve().then(() => console.log('微任务 1'))
        console.log('listener1')
    })
    oBtn.addEventListener('click', function () {
        Promise.resolve().then(() => console.log('微任务 2'))
        console.log('listener2')
    })
    oBtn.click()
    console.log('after click')
</script>

看下这个问题点击鼠标和主动调用click方法有什么不同,为什么有下面这种现象。

用户触发

用户触发的事件是由浏览器通过eventQueue告诉程序的。并且整个捕获冒泡过程中所有的事件处理函数都是异步调用。
demo

既然都是异步的,那怎么之前事件被取消了?

1.3 执行事件处理函数

  1. 不同的触发事件方式(如上)导致的事件处理函数调用方式不同;
  2. 实参是事件对象;
    3 this是当前绑定事件处理函数的EventTarget,注意不一定是触发事件的EventTarget

1.4 事件代理

如下

二、APIs

事件相关的APIs主要是:

  1. EventTarget
    可以添加、触发,接收事件的对象。
  2. Event对象
    事件处理函数接收的实参,即事件对象。
  3. EventListener
    可以处理事件的对象。这个很少用到,一般直接给EventTarget.addEventListener直接指定callback

2.1 EventTarget

3大功能:

  • 添加事件处理函数;
  • 删除事件处理函数;
  • 触发事件。

在设计模式里叫什么?

addEventListener

  1. option参数;
  2. Passive Event
  3. 回调函数的this是绑定事件处理函数的EventTarget对象。
    不一定是触发事件的EventTarget对象。

removeEventListener

dispatchEvent

  1. 可以通过在创建事件对象时指定的bubbles的值控制触发的事件是否走事件捕获和冒泡阶段;
  2. 事件处理函数可以利用Event.isTrusted属性判断事件是由用户触发的还是JS触发的。
  3. Unlike "native" events, which are fired by the DOM and invoke event handlers asynchronously via the event loop, dispatchEvent() invokes event handlers synchronously

2.2 Event对象

  1. preventDefault()/defaultPrevented/cancelable
  2. stopPropagation() / cancelBubble
  3. stopImmediatePropagation()
  4. eventPhase
  5. target/currentTarget

参考

  1. MDN Introduction to events
  2. Dispatching custom events

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions