温故而知新:javascript事件级别和事件流

153 阅读2分钟

前言

在前端开发过程中,我们总是跟事件打着交道,常常会看到或听到与事件相关的一些专有名词,如:事件级别,事件模型,事件流,事件捕获,事件冒泡等等,下面对事件级别和事件流做个梳理

dom级别

dom级别划分的话可以分为4个级别,相当于不同版本的迭代

dom0级

DOM0级是DOM没有被W3C定位标准之前的说法

dom1级

在1998年10月成为W3C标准后,称为DOM1级,DOM1级由两个模块组成:DOM核心和DOM HTML。

其中DOM核心规定的是如何映射基于XML的文档结构,以便简化对文档中任意部分的访问和操作。

DOM HTML模块则在DOM核心的基础上加以扩展,添加了针对html的对象和方法

dom2级

在DOM1级的基础上进行了扩展,为节点添加了更多的方法和属性,添加的模块包括:视图,事件,访问,遍历,样式等。

dom3级

DOM事件

DOM0级事件

DOM0级处理事件就是将一个函数赋值给一个事件处理属性

<button id="myBtn" type="button"></button>

const myBtn = document.getElementById('myBtn')
myBtn.onclick = function() {
  console.lgo('click')
}

DOM2级事件

DOM2级处理事件是在DOM0级的基础上再添加了一些处理程序

  • 可以同时绑定多个事件处理函数

  • 定义了addEventLinstener 和 removeEventLinstener两个方法

addEventLinstener接收三个参数

  • 事件名称(必填):名称不用带on
  • 回调函数(必填):执行的函数
  • 触发类型(选填):true为在捕获阶段执行,false为在冒泡阶段执行,默认为false
<button id="myBtn" type="button"></button>

const myBtn = document.getElementById('myBtn')

function myFun1() {
    console.log('click1')
}
function myFun2() {
    console.log('click2')
}

myBtn.addEventListener('click', myFun1)
myBtn.addEventListener('click', myFun2)
myBtn.addEventListener('click', myFun1)
myBtn.addEventListener('click', myFun2)

DOM3级事件

在DOM2级事件处理基础上添加了更多的事件类型

  • UI事件

  • 焦点事件

  • 鼠标事件

  • 滚轮事件

  • 文本事件

  • 键盘事件

  • 合成事件

  • 变动事件

同时DOM3级事件也容许使用者自定义一些事件

自定义事件

Event

不可传递参数

const myEvent = new Event('refresh')

document.addEventListener('refresh', () => {
    console.log('refresh')
})
document.dispathEvent('myEvent')

CustomEvent

可传递参数

const myEvent = new CustomEvent('myEvent', {detail: {title: 'hello world'}})
document.addEventListener('myEvent', (e) => {
    console.log(e.detail.title) // hello world
})
document.dispatchEvent(myEvent)

dom事件流

事件流:可以理解为事件在目标元素与祖先元素间的触发顺序

事件处理机制的三个阶段

  1. 捕获阶段
  2. 目标阶段
  3. 冒泡阶段

20210530214042969.png

当点击目标元素的时候就是这三步,唯一的区别是控制事件触发在哪个阶段

<body>
  <div class="box1">
    <div class="box2">
      <div class="box3"></div>
    </div>
  </div>
</body>
<script>
  const box1 = document.querySelector('.box1')
  const box2 = document.querySelector('.box2')
  const box3 = document.querySelector('.box3')
  box1.addEventListener('click', () => {
    console.log('我是父元素')
  })
  box2.addEventListener('click', () => {
    console.log('我是子元素')
  })
  box3.addEventListener('click', () => {
    console.log('我是孙元素')
  })
</script>

微信图片_20230311210035.png

如果事件是以捕获阶段触发,那么执行的顺序是由外到内,即父 -> 子 -> 孙

微信图片_20230311210557.png

如果事件是以冒泡阶段触发,那么执行的顺序是由内到外,即孙 -> 子 -> 父

微信图片_20230311210041.png

阻止冒泡和默认行为

阻止冒泡: e.stopPropagation()

阻止默认行为: e.preventDefault()