先看一段代码
.爷爷>.爸爸>.儿子,给三个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,并提供事件信息
W3C事件模型
先捕获再冒泡
有一个e的函数被传给所有监听函数,事件结束后e对象就不存在了
target与 currentTarget的区别
- e.target:用户操作的元素
- e.currentTargent: 程序员监听的元素
- this是e.currentTargent,个人不推荐使用,因为基本记不住this是e.target还是e.currentTargent -只有一个div被监听时(不考虑父子同时被监听)浏览器会先捕获后冒泡
取消冒泡
捕获不可取消,但是冒泡可以 e.stopPropagation()可中断冒泡,浏览器不在向上走,一般用来封装某些独立的组件
不可取消冒泡
有些事件不可取消冒泡
scroll event(滚动事件),看到Bubble和Cancelable
Bubble的意思是该事件是否冒泡
Cancelable的意思是开发者是否可以阻止默认事件
Cancelable与冒泡无关
如何阻止滚动
scroll事件不可阻止默认动作
阻止scroll默认动作没用,因先有滚动才有滚动事件
要阻止滚动,可以阻止wheel和touchstart的默认动作
注意你要找准滚动条所在的元素
但滚动条还能用,可用CSS让滚动条witch:0
自定义事件
- 浏览器自带事件
- 一共100多种事件,列表在MDN上
- 开发者可以在自带事件之外,自定义一个事件