js事件的捕获和冒泡阶段
讨论的主要是两个事件模型:IE事件模型与DOM事件模型
IE内核浏览器的事件模型是冒泡型事件(没有捕获事件过程),事件句柄的触发顺序是从ChildNode到ParentNode。
<div id="ancestor">
<button id="child">
Open the console and click me
</button>
</div>
以上的HTML代码在IE内核下,事件是这样传播的:{
1、Button#child;
2、div#ancestor;
3、Body;
4、Document
}
DOM标准的浏览器事件是:捕获事件和冒泡事件。
捕获事件过程:{
1、Window
2、Document
3、Body
4、Div#ancestor
5、Button#child
}
冒泡事件过程:{
6、Div#ancestor
7、Body
8、Document
9、Window
}
当开发者在一个元素上注册了事件后,这个事件的响应顺序是从window(最顶层)开始一级一级的向下传播,然后到了该元素后事件捕获过程结束,事件开如冒泡,一级一级向父层元素冒泡(请注意第6步)。
当然,开发者可以很轻松的决定DOM标准的浏览器中的事件需要在哪个传播过程触发。
事件的注册机制:
DOM标准的浏览器事件注册方法是通过addEventListener方法注册,而IE内核的浏览器则是通过attachEvent方法注册。
这两个方法的区别:
addEventListener方法带有三个参数,分别是:eventType、handler、useCapture。
eventType不带有on字符串;
handler参数是一个事件句柄,这个函数或方法带有一个事件对象参数;
useCapture参数决定了事件句柄触发在哪种事件传播阶段,如果useCapture为true则为捕获阶段,反之则为冒泡阶段。
继续看演示:
var ancestorHandler = function (e){
//......
},
childHandler = function (e){
//......
};
document.querySelector('#ancestor').addEventListener('click',ancestorHandler,false);//注意第三个参数 ,注册了一个在冒泡阶段触发的事件句柄
document.querySelector('#child').addEventListener('click',childHandler,true);//注意第三个参数 ,注册了一个在捕获阶段的事件句柄
当用户在这个DIV元素上点击时,事件的执行顺序是childHandler、ancestorHandler。
原因:按钮的事件是在捕获阶段触发的,也就是从上到下,而DIV的事件是注册在冒泡阶段,也就是点击了这个按钮开始从这个按钮的位置往上冒泡。
阻止事件的冒泡:
DOM事件对象提供了stopPropagation方法用于阻止事件流。
var ancestorHandler = function (e){
//......
},
childHandler = function (e){
e.stopPropagation();
//......
};
以上代码在childHandler函数中添加了e.stopPropagation()代码片段,它将阻止事件流,事件流包括捕获阶段及冒泡阶段的事件流。
再修改上面的代码如下:
var ancestorHandler = function (e){
//......
},
childHandler = function (e){
//......
};
document.querySelector('#ancestor').addEventListener('click',ancestorHandler,true);//注意第三个参数
document.querySelector('#child').addEventListener('click',childHandler,true);//注意第三个参数
以上的代码产生的结果是:用户在DIV元素上单击时,将会依次触发ancestorHandler、childHandler函数,为什么?因为我们将div#ancestor的事件注册到捕获阶段了,也就是从上至下。当然了我们还可以阻止childHandler方法的执行。
以上代码将阻止按钮的事件触发。当用户点击了DIV的区域,仅仅触发ancestorHandler函数,因为阻止了事件流。
IE内核的浏览器中是如何注册事件的。IE内核提供了attachEvent方法为元素注册事件,注意该方法与DOM的addEventListener方法区别很大!该方法带有两个参数:
{
eventType 事件类型,请注意这个参数与addEventListener的eventType的区别,它必须带有on;
handler 事件句柄 ,请注意attachEvent没有提供事件捕获阶段的参数,IE内核的事件都是发生在冒泡阶段!
}
var ancestorHandler = function (e){
//......
},
childHandler = function (e){
//......
};
document.getElementById('ancestor').attachEvent('onclick',ancestorHandler);//注意没有第三个参数
document.getElementById('child').attachEvent('onclick',childHandler);//注意没有第三个参数
以上代码在IE中将为DIV元素和按钮元素注册了不同的事件。
另外还有一些注意事项:
1、DOM标准的addEventListener方法执行事件的顺序是按照事件注册的顺序执行的。而attachEvent方法则相反–后注册的事件先觖发,先注册的事件后触发。
2、DOM标准的浏览器文本节点也会冒泡,而IE内核的浏览器文本节点不会冒泡。
3、DOM标准的浏览器事件对象与IE内核的浏览器事件不同(具体请参阅http://www.quirksmode.org/js/introevents.html)。
4、DOM标准的浏览器事件卸载方式与IE内核的事件卸载方式不同。
1 object.removeEventListener(eventType,handler,useCapture);//DOM标准的事件卸载方式
2 object.detachEvent(eventType,handler);//IE内核的事件卸载方式
在DOM标准的事件卸载方式中需要注意的是:事件捕获的参数。如果你的事件是注册在捕获阶段,则卸载事件时,必须将其指定为捕获阶段(true),否则无法卸载;如果你的事件注册在注册在冒泡阶段,则必须将其指定为冒泡阶段(false),否则同样无法卸载!
写作不易,难免有疏漏和错误,还请慷慨指正,不错请推荐
每天多学一点点 代码少敲一点点
js事件的捕获和冒泡阶段的更多相关文章
- 探讨Js的事件的冒泡阶段
近来看到了一个新的知识点叫Js的事件冒泡,因此决定自己来研究一番. 大家应该都知道,Js中的事件处理分为三个阶段,1:事件的捕获阶段,2:处于目标阶段,3:事件的冒泡阶段.那么什么是事件的捕获和冒泡呢 ...
- js事件流机制冒泡和捕获
JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间. 事件流 从页面中接收事件的顺序称为事件流. IE --> 事件冒泡流 Netsc ...
- js中addEventListener第三个参数涉及到的事件捕获与冒泡
js中,我们可以给一个dom对象添加监听事件,函数就是 addEventListener("click",function(){},true); 很容易理解,第一个参数是事件类型, ...
- js事件冒泡和事件捕获详解
Javascript与HTML之间的交互是通过事件实现. 一.事件流 事件,是文档或浏览器窗口中发生的一些特定的交互瞬间.事件流,描述的是页面中接受事件的顺序.IE9,chrome,Firefox,O ...
- js事件流 事件捕获 及时间冒泡详解
Javascript与HTML之间的交互是通过事件实现. 一.事件流 事件,是文档或浏览器窗口中发生的一些特定的交互瞬间.事件流,描述的是页面中接受事件的顺序.IE9,chrome,Firefox,O ...
- Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制
一.事件的捕获与冒泡 由W3C规定的DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡,在捕获和冒泡阶段,会依次检查途径的每个节点,如果该节点注册了相应的监听函数,则执行监 ...
- dom事件不求甚解,色解事件捕获和冒泡
以前对事件只会用jq的bind绑定一下,脑海里留着书中的事件循环,一直认为事件就是这儿循环的,最近看园子里的文章,对事件的了解更模糊了 所以我做了个小实验,总结一下看的这些零零碎碎的文章,如果总结错了 ...
- javascript的事件监听与捕获和冒泡
在前端开发中,我们经常需要对某些事件进行监听.这样只要在指定的元素上触发了该事件,就会执行一个回调来进行相关的操作. 而js中事件监听方法总共有三种,分别如下所示: element.addEventL ...
- js 事件流和事件冒泡阻止
js 事件流和事件冒泡阻止 事件流 当浏览器发展到第四代的时候(IE4与Netscape4)浏览器开发团队遇到一个有意思的的问题: 页面的哪一部分会拥有某个特定的事件? 比如在纸上画上一组同心圆,如果 ...
随机推荐
- C51中的关键字data,idata,xdata,pdata,bdata
写在最前面的话:官方网站的解答是最可信的.英语不错的必看.http://www.keil.com/support/man/docs/c51/c51_le_memtypes.htm 下面转载几篇中文的, ...
- CAS (1) —— Mac下配置CAS到Tomcat(服务端)
CAS (1) -- Mac下配置CAS到Tomcat(服务端) tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 cas版本: cas4.1.2 cas-clie ...
- cxDBVerticalGrid
定位在第一行并显示内置编辑器 cxDBVerticalGrid1.FocusedRow := cxDBVerticalGrid1.Rows[0]; cxDBVerticalGrid1.ShowEdit ...
- [转发]VMware厚置备延迟置零 、 厚置备置零、精简置备 区别
1.厚置备延迟置零(zeroed thick) 以默认的厚格式创建虚拟磁盘.创建过程中为虚拟磁盘分配所需空间.创建时不会擦除物理设备上保留的任何数据,但是以后从虚拟机首次执行写操作时会按需要将其置零. ...
- hdu6447 YJJ's Salesman
这个题意和数据范围一看就是离散化之后树状数组优化DP.给的"从左下方走上去才能拿到收益"的性质其实可以当成"必须从横纵坐标严格比某个点小的地方转移过来".1A了 ...
- 【uoj#209】[UER #6]票数统计 组合数+乱搞
题目描述 一个长度为 $n$ 的序列,每个位置为 $0$ 或 $1$ 两种.现在给出 $m$ 个限制条件,第 $i$ 个限制条件给出 $x_i$ .$y_i$ ,要求至少满足以下两个条件之一: 序列的 ...
- line search中的重要定理 - 梯度与方向的点积为零
转载请注明出处:http://www.codelast.com/ 对精确的line search(线搜索),有一个重要的定理: ∇f(xk+αkdk)Tdk=0 这个定理表明,当前点在dk方向上移动到 ...
- 一千个不用Null的理由
原文链接:http://www.importnew.com/27378.html 原文出处: xrzs 港真,Null 貌似在哪里都是个头疼的问题,比如 Java 里让人头疼的 NullPointer ...
- Maximum repetition substring POJ - 3693(重复次数最多的连续重复子串)
这题和SPOJ - REPEATS 一样 代码改一下就好了 这个题是求这个重复子串,还得保证字典序最小 巧妙运用sa 看这个 https://blog.csdn.net/queuelovestack ...
- c# 方法参数 params 的试用
//添加方法 public void test(params string[] messages) { } //调用方法 test("aaa","bbb",&q ...