简述 DOM 事件模型

140 阅读2分钟

先看一段代码 image.png .爷爷>.爸爸>.儿子,给三个div分别添加事件监听fnYe/fnBa/fnEr

问题一:点击文字,算不算点击了爷爷,爸爸,儿子? 算

问题二:调用顺序,点击文字,最先调用fnYe/fnBa/fnEr中的哪一个函数? 都行

W2C标准

2002年,W3C发布标准,规定浏览器应该同时支持两种调用顺序

  • 首先按照爷爷=>爸爸=>儿子的顺序看有没有函数监听
  • 然后按照儿子=>爸爸=>爷爷的顺序看有没有函数监听
  • 有数据监听就调用,并提供事件信息,没有就跳过

什么是捕获

从外到内找监听函数,叫事件捕获

什么是冒泡

从内到外找监听函数,叫事件冒泡

那fnYe/fnBa/fnEr需要调用两次么?

不用,开发者自己选择把fnYe放在捕获阶段还是冒泡阶段

addEventListener

addEventListener(事件绑定API)

  • ie5:baba.attachEvent('onclick',fn) //冒泡 click前面要加on,后面是要执行的函数
  • 网景:baba.addEventListener('click',fn) //捕获
  • W3C:baba.addEventListener('click',fn,bool)//综合了
  • 如果bool不传或者为falsy值(类似于false的值):就让fn走冒泡,即当浏览器在冒泡阶段发现baba有fn监听函数,就会调用fn,并提供事件信息
  • 如果bool为true:就让fn走捕获阶段,即当浏览器在捕获阶段发现baba有fn监听函数,就会调用fn,并提供事件信息

image.png

W3C事件模型

先捕获再冒泡

有一个e的函数被传给所有监听函数,事件结束后e对象就不存在了

image.png

target与 currentTarget的区别

  • e.target:用户操作的元素
  • e.currentTargent: 程序员监听的元素
  • this是e.currentTargent,个人不推荐使用,因为基本记不住this是e.target还是e.currentTargent -只有一个div被监听时(不考虑父子同时被监听)浏览器会先捕获后冒泡

取消冒泡

捕获不可取消,但是冒泡可以 e.stopPropagation()可中断冒泡,浏览器不在向上走,一般用来封装某些独立的组件

不可取消冒泡

有些事件不可取消冒泡

scroll event(滚动事件),看到Bubble和Cancelable

Bubble的意思是该事件是否冒泡

Cancelable的意思是开发者是否可以阻止默认事件

Cancelable与冒泡无关

image.png

如何阻止滚动

scroll事件不可阻止默认动作

阻止scroll默认动作没用,因先有滚动才有滚动事件

要阻止滚动,可以阻止wheel和touchstart的默认动作

注意你要找准滚动条所在的元素

但滚动条还能用,可用CSS让滚动条witch:0

自定义事件

  • 浏览器自带事件
  • 一共100多种事件,列表在MDN上
  • 开发者可以在自带事件之外,自定义一个事件