目录
DOM事件概述
DOM事件机制
DOM事件特例
一、DOM事件概述
事件模型
浏览器的事件模型,就是通过监听函数对事件做出反应。事件发生后,浏览器监听到了这个事件,就会执行对应的监听函数。
事件的类型
事件类型主要分浏览器自带事件,和开发者自定义事件
-
浏览器自带事件可以上MDN查看事件参考 | MDN (mozilla.org)
-
开发者自定义事件,目前水平太低,以后再补充
二、DOM事件机制
1.事件绑定和删除
target.addEventListener 绑定事件的监听函数
target.removeEventListener 移除事件的监听函数
dispatchEvent() 触发事件
2.浏览器怎么知道有没有该元素有没有事件
-
浏览器首先按
爷爷元素=>爸爸元素=>儿子元素的顺序看有没有函数监听 -
然后再反向执行一遍顺序看有无函数监听
-
如果有函数就调用,并提供事件信息,没有就跳过
-
从外向内找监听函数,术语叫事件捕获
-
从内向外找监听函数,术语叫事件冒泡 //工作最常用这个
-
开发者自己选择把函数放在捕获阶段还是冒泡阶段
-
为什么一件看起来差不多的事要来回做两次呢,看下文
3.事件绑定API
-
关于事件绑定,IE5和网景公司有不同的机制标准
-
IE5:
目标.attachEvent('oncilck',fn)//冒泡机制 -
网景:
目标.addEventListener('cilck',fn)//捕获机制
-
-
W3C最后统一了标准:
目标.addEventListener('cilick',fn,bool)-
如果
bool不传值或为falsy值
-
fn走冒泡机制,即当浏览器在冒泡阶段发现目标有fn监听函数,就调用,并提供事件信息
-
如果
bool为true
- 就让
fn走捕获机制,当浏览器在捕获阶段发现目标有fn监听函数,就调用,并提供事件信息
-
-
捕获与冒泡
-
通俗的讲,捕获先调用爸爸的监听函数
-
冒泡先调用儿子的监听函数
- 代码如下(只展示JS代码)
const level1 = document.querySelector('.level1') const level2 = document.querySelector('.level2') const level3 = document.querySelector('.level3') const level4 = document.querySelector('.level4') const level5 = document.querySelector('.level5') const level6 = document.querySelector('.level6') const level7 = document.querySelector('.level7') let n = 1 const removeX = (e) => { const t = e.currentTarget setTimeout(() => { t.classList.remove('x') }, n * 1000) n += 1 } const addX = (e) => { const t = e.currentTarget setTimeout(() => { t.classList.add('x') }, n * 1000) n += 1 } level1.addEventListener('click', removeX, true) level1.addEventListener('click', addX) level2.addEventListener('click', removeX, true) level2.addEventListener('click', addX) level3.addEventListener('click', removeX, true) level3.addEventListener('click', addX) level4.addEventListener('click', removeX, true) level4.addEventListener('click', addX) level5.addEventListener('click', removeX, true) level5.addEventListener('click', addX) level6.addEventListener('click', removeX, true) level6.addEventListener('click', addX) level7.addEventListener('click', removeX, true) level7.addEventListener('click', addX)- 效果
-
总结
代码中bool值位true的事件为捕获,没有bool值的事件为冒泡
-
4.W3C事件模型
-
默认的执行方式为:先捕获,再冒泡(可以阻止冒泡的过程)
-
注意
e对象被传递给所有监听函数 -
事件结束后,我们可以认为
e这个对象就不存在了 -
如果确实在事件结束后需要
e对象,可以提前把属性复制到自己的变量里,但最好不这么做
三、DOM事件特例
1. 假如只有一个div被监听(不考虑父子同时被监听)
-
如果fn分别在捕获和冒泡阶段都要监听click事件
-
并且用户点击的元素就是开发者所监听的
-
那么捕获和冒泡谁先监听谁就先执行,这时个特例
2.取消冒泡
-
e.stopPropagation()这个api可以中断冒泡,让浏览器不再往上走 -
一般用于封装某些独立的组件
3.不可以被取消冒泡的事件
-
有一些事件不可以被取消冒泡
-
需要了解的时候看MDN
-
Bubbles 代表该事件是否冒泡
-
Cancelable 代表开发者是否能取消冒泡
4. 如何阻止滚动
-
scroll 事件不可取消冒泡
-
阻止scroll 默认动作没有用,因为是先有滚动这个动作才有滚动事件发生
-
要阻止滚动,可以先阻止
whieel和touchstart的默认动作 -
但是要先找准滚动条所在的元素,不然没有效果
-
最后要用CSS让页面中的滚动条消失
-