一、点击事件
示例代码:
<div class = 爷爷>
<div class = 爸爸>
<div class = 儿子>
文字
</div>
</div>
</div>
即.爷爷>.爸爸>.儿子
给三个div分别添加事件监听fnYe/fnBa/fnEr
提问一:点击了谁?
- 点击文字,算不算点击儿子?
- 点击文字,算不算点击爸爸?
- 点击文字,算不算点击爷爷?
- 答案:都算
提问二:调用顺序
- 点击文字,最先调用fnYe/fnBa/fnEr中的哪一个函数?
- 答案:都行
IE5认为先调fnEr,网景认为先调fnYe
-
最后:W3C发布标准 文档名为DOM Level 2 Events Specification 规定浏览器应该同时支持两种调用顺序 首先按 爷爷=〉爸爸=> 儿子顺序看有没有函数监听 有监听函数就调用,并提供事件信息,没有就跳过
-
冒泡是ie发明的
1、事件捕获: 从外向内找监听函数
2、事件冒泡: 从内向外找监听函数
事件冒泡:JS中当出发某些具有冒泡性质的事件是,首先在触发元素寻找是否有相应的注册事件,如果没有再继续向上级父元素寻找是否有相应的注册事件作出相应,这就是事件冒泡。
二、addEventListener
1、事件绑定API
IE5*:baba.attachEvent('onclick',fn) //冒泡
网景:baba.addEventListener('click',fn) //捕获
W3C:baba.addEventListener('click',fn,bool)
2、如果bool不传或为falsy
就让fn走冒泡,即当浏览器在冒泡阶段发现baba有fn监听函数,就会调用fn,并提供事件信息
3、如果bool为true
就让fn走捕获,即当浏览器在捕获阶段发现baba有fn监听函数,就会调用fn,并提供事件信息
小结
1、两个疑问
儿子被点击了,算不算点击老子?
那么先调用老子的函数还是先调用儿子的函数?
2、捕获与冒泡
捕获说先调用爸爸的监听函数
冒泡说先调用儿子的监听函数
3、W3C事件模型
先捕获(先爸爸=>儿子)再冒泡(再儿子=>爸爸)
注意e对象被传给所有监听函数
事件结束后,e对象就不存在了
三、target vs currentTarget
区别
e.target-用户操作的元素
e.currentTarget-程序员监听的元素
this是e.currentTarget,老师不推荐使用
举例
div>span{文字},用户点击文字
e.target就是span
e.currentTarget就是div
一个特例
背景
- 只有一个div被监听(不考虑父子同时被监听)
- fn分别在捕获阶段和冒泡阶段监听click事件
- 用户点击的元素就是开发者监听的
div.addEventLisenter('click',f1)
div.addEventLisenter('click',f2,true)
请问,f1先执行还是f2先执行?
如果把两行调换位置后,请问哪个先执行?
错误答案:f2先执行
正确答案:谁先监听谁先执行
总结:这是一个特例
const level1 = document.querySelector('.level1')
const level2 = document.querySelector('.level2')
const level2 = document.querySelector('.level3')
const level2 = document.querySelector('.level4')
const level2 = document.querySelector('.level5')
const level2 = document.querySelector('.level6')
const level2 = document.querySelector('.level7')
level7.addEventListener('click',()=>{
console.log(2)
},true) //捕获
level7.addEventListener('click',()=>{
console.log(1)
}) //冒泡
四、取消冒泡
捕获不可取消,但冒泡可以
- e.stopPropagation()可中断冒泡,浏览器不再向上走
- 通俗来说:有人打我,我自己解决,别告诉我老子
- 一般用于封装某些独立的组件
五、不可阻止默认动作
有些事件不能阻止默认动作
- MDN搜索scroll event,看到Bubbles和Cancelable
- Bubbles的意思是该事件是否冒泡,所有冒泡都可取消
- Cancelable的意思是开发者是否可以阻止默认事件
- Cancelable与冒泡无关
CSS也行
-
使用overflow:hidden可以直接取消滚动条
-
但此时JS依然可以修改scrollTop
小结
1、target和currentTarget
- 一个是用户点击的,一个是开发者监听的
2、取消冒泡
- e.stopPropagation()
3、事件的特性
- Bubbles表示是否冒泡
- Cancelable表示是否支持开发者取消冒泡
- 如scroll不支持取消冒泡
4、如何禁用滚动
- 取消特定元素的wheel和touchstart的默认动作