可以逐步理解捕获和鼓泡
addevent监听器监听事件
DOM事件机制
消除起泡
无法阻止默认行为
委托事件
要说的话就用例子让他们阶段性地理解捕获和冒泡、事件和事件的委托。
数据来自饥民谷
关于捕获和冒泡
下面的代码都以点击事件为例
先一步一步地理解。
上传代码
代码-HTML div class=爷爷div class=爸爸div class=儿子字符/div /div/div以上的代码即.爷爷.爸爸.儿子
在3个div上分别添加事件监听fnYe/fnBa/fnEr。 点击谁拦截谁
关于上面的代码问题1:是谁点击了文字,点击了儿子吗?
点击文字,不点击爸爸吗?
点击文字,不是就会点击爷爷吗?
答案是:
问题2:调用顺序是,单击字符,首先调用fnYe /fnBa/fnEr中的哪个函数?
答案可以是: 让我们看看浏览器是如何实现的。
IE5先调整fnEr,网络场景以为是先调整了fnYe,掐了一下,最后变成了W3C
和事人W3C 2002年,W3C发表了名为DOM Level 2 Events Specification的标准文件
浏览器必须支持这两种调用顺序
首先按照爷爷=爸爸=儿子的顺序看有无函数监听
然后儿子=爸爸=爷爷的顺序看有无函数监听
如果有监听函数则调用,提供事件信息,如果没有则跳过
一定是你在捕获和冒泡捕获和冒泡术语从外向内寻找拦截函数,事件捕获
从内向外寻找拦截函数,事件冒泡
疑问:从外到内,从内到外,这不是在fnYe/fnBa/fnEr中都被调用两次吗?
不! 开发者自己将fnYe放入捕获阶段,还是冒泡阶段
DOM事件机制图标
说明:
蓝色的td被点击了。 要一个一个地问,首先询问窗口。 有函数被调用的东西吗? 因为子孙的子孙…被点击了。 window说:“我没有可以管理的函数。 然后这样按顺序调用,直到问td。 这个过程结束后,有一个目标阶段是在td中判断是否需要冒泡。 td“我需要感冒。 那就冒险回去吧。 然后再从td走到窗口,再次调用所有函数。 (有则调谐,无则不调谐。 )
addevent监听器监听事件
事件绑定API ie5 * : Baba.attach event (‘onclick’,fn )//冒泡
网景: Baba.addevent listener (‘click’,fn )//捕获
W3C : Baba.addevent listener (‘click’、fn、bool ) )。
如果bool不传递falsy或为fn执行冒泡,即在冒泡阶段浏览器发现baba具有fn侦听函数,则会调用fn并提供事件信息
如果bool为真
让fn去捕捉。 这意味着,如果浏览器在捕获阶段发现baba具有fn侦听函数,它将调用fn并提供事件信息,使您可以选择将fn放置在何处
代码示例
简化代码的图解
两个人的疑问集中在一起,儿子被点击了。 你不是点击了老子吗? 计算
那么是先调用老子的函数,还是先调用儿子的函数? 我不确定。 IE先叫儿子,firefox先叫老子。 最终W3C说我两个都支持。 我先从老子给儿子,从儿子给老子,这样你们满意了吧。
捕获和冒泡捕获说先调用父亲的拦截函数,再调用儿子的拦截函数
泡泡说要调用儿子的监听函数,然后调用爸爸的监听函数
W3C事件模型捕获后(先爸爸=儿子)会起泡吗? (再儿子=爸爸) )可以阻止起泡) )。
请注意,e对象将传递给所有监听函数
活动结束后,e对象将不再存在
不存在意味着我不想e烦恼。 不建议在活动结束后继续使用e。 由于e会被浏览器安静地更改,所以在使用之前应该事先将属性复制到自己的变量中。 例如,代码示例const t=e.currentTarget是将currentTarget的引用复制到t。
target v.s. currentTarget -区分
e.target-用户交互的元素
e.currentTar
get-程序员监听的元素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先执行
正确答案:谁先监听谁先执行,没有父子
总结:这是一个特例
取消冒泡 捕获不可取消,但冒泡可以e.stopPropagation()可中断冒泡,浏览器不再向上走。通俗来说:有人打我,我自己解决,别告诉我老子
一般用于封装某些独立的组件
不可阻止默认动作 有些事件不能阻止默认动作MDN搜索scroll event,看到Bubbles和 Cancelable
Bubbles的意思是该事件是否冒泡,所有冒泡都可取消
Cancelable的意思是开发者是否可以阻止默认事件
Cancelable与冒泡无关
推荐看MDN英文版,中文版内容不全
如何阻止滚动scroll 事件不可阻止默认动作
阻止scroll默认动作没用,因先有滚动才有滚动事件
要阻止滚动,可阻止 wheel和 touchstart的默认动作
注意你需要找准滚动条所在的元素,示例
但是滚动条还能用,可用CSS让滚动条width: 0 (::-webkit-scrollbar { width: 0 !important })
CSS也行使用overflow: hidden可以直接取消滚动条
但此时JS依然可以修改scrollTop
小结 target和currentTarget一个是用户点击的,一个是开发者监听的
取消冒泡e.stopPropagation()
事件的特性Bubbles表示是否冒泡
Cancelable表示是否支持开发者取消冒
如scroll不支持取消冒泡
如何禁用滚动取消特定元素的wheel和touchstart的默认动作
自定义事件 浏览器自带事件一共100多种事件,列表在MDN 上
提问开发者能不能在自带事件之外,自定义一个事件
答案:可以,见示例
事件委托 委托一个元素监听我本该监听的东西。就是把事件监听放在祖先元素(如父元素、爷爷元素)上。
你要给100个按钮添加点击事件,咋办?
答:监听这100个按钮的祖先,等冒泡的时候判断target是不是这100个按钮中的一个,代码示例
场景二你要监听目前不存在的元素的点击事件,咋办?
答:监听祖先,等点击的时候看看是不是我想要监听的元素即可,代码示例
优点省监听数(内存)
可以监听动态元素
封装事件委托 要求写出这样一个函数on(‘click’, ‘#testDiv’, ‘li’, fn)
注意:先搞清楚输入(封装的四个参数,事件绑定、元素选择器 Element.matches 、事件 event 对象,某些函数)在搞清楚输出
当用户点击#testDiv里的li元素时,调用fn函数
要求用到事件委托
答案一判断target是否匹配’li’等选择器,代码示例答案二
递归判断target / target的爸爸/target的爷爷。(当前元素不匹配button就看他的爸爸匹配不,只要我的祖先中某一项是button,说明点击的就是button),代码示例整合进jQuery
有兴趣可以自己实现$(’#xxx’).on(‘click’, ‘li’, fn) JS支持事件吗 答
不支持。本次讲的DOM事件不属于JS的功能,是浏览器提供的 DOM的功能
JS只是调用了DOM提供的addEventListener而已
–continue
这是懦弱的樱桃的学习之旅
既然看到这了都那就