js核心基础之Events事件机制(事件冒泡、事件捕获、事件执行顺序、阻止冒泡)
2018-01-16 19:51
836 查看
事件的触发有三个阶段:
1、document往事件触发地点,捕获前进,遇到相同注册事件立即触发执行;
2、到达事件位置,触发事件;
3、事件触发地点往document方向,冒泡前进,遇到相同注册事件立即触发。
注意:无论是冒泡阶段还是捕获阶段触发,都只会触发一次。默认为冒泡模式
例子:
简写的节点树:document->html->body->outdiv->innerdiv
先捕获再冒泡:遍历顺序;
原理:捕获模式,即在捕获阶段触发该函数,当在捕获阶段,即第一遍还未遍历完成,引擎遍历到outdiv上时发现该节点上注册了click函数,就立即触发outdiv上的click,
而后,遍历到innerdiv上,发现也注册了click事件,就触发innerdiv的click事件。
原理:冒泡模式,即在冒泡阶段触发该函数,当在捕获阶段,即便遍历到outdiv时,发现,其身上注册了事件,也不会触发,只有等到冒泡阶段,而冒泡阶段是先遍历到innerdiv,
所以会先触发innerdiv上的click。
总结:当innerdiv 和outdiv分别使用不同模式的时候,则谁是捕获模式,就先触发当前节点上注册的事件。
二、注意点
1、在同一个节点上,事件注册的顺序,会影响它的执行顺序,。
总结: 非目标元素捕获 -> 目标元素代码顺序 -> 非目标元素冒泡。
2、event.stopPropagation()
并不是说,在冒泡阶段阻止事件的发生,而是不仅阻止了事件的冒泡,还阻止事件的继续捕获,简而言之,就是阻止事件的进一步传播。
所以,当事件都是在捕获阶段注册,也是能够阻止的;
例子:
原理:两个事件谁先触发,谁才能阻止后一个事件的触发
比如,当两个事件都是冒泡阶段,如果不做任何操作,所以innerdiv的click事件,先于outdiv触发,
所以,在innerdiv里面写上,stoppropagation,是能够阻止outdiv的click事件的触发的
再比如,当两个事件都是捕获阶段触发,如果不做任何操作,outdiv的click事件,先于innerdiv触发,
所以 ,只能 在outdiv里面写上stoppropagation,才能阻止innerdiv的click事件的触发,但是,问题来了,
既然这样,那么innerdiv上面的事件再也触发不了,其实,也不用担心,因为,我们日常所使用的事件都是在冒泡阶段触发的,
换句话说,点击子节点可以决定是否触发父节点的click,但是,点击父节点,不能决定是否触发子节点的click。
3、stopImmediatePropagation()
例子,
1、document往事件触发地点,捕获前进,遇到相同注册事件立即触发执行;
2、到达事件位置,触发事件;
3、事件触发地点往document方向,冒泡前进,遇到相同注册事件立即触发。
注意:无论是冒泡阶段还是捕获阶段触发,都只会触发一次。默认为冒泡模式
例子:
简写的节点树:document->html->body->outdiv->innerdiv
先捕获再冒泡:遍历顺序;
//捕获阶段 document->html->body->outdiv->innerdiv //冒泡阶段 innerdiv->outdiv->body->html->document
<div id="outdiv"> out div <div id="innerdiv"> innerdiv </div> </div> var outdiv = document.getElementById('outdiv'); var innerdiv = document.getElementById('innerdiv');
//捕获模式 innerdiv.addEventListener('click', function (event) { console.log('innerdiv 捕获模式', event); }, true) outdiv.addEventListener('click', function (event) { console.log('outdiv 捕获模式 ', event); }, true) // result: outdiv then innerdiv
原理:捕获模式,即在捕获阶段触发该函数,当在捕获阶段,即第一遍还未遍历完成,引擎遍历到outdiv上时发现该节点上注册了click函数,就立即触发outdiv上的click,
而后,遍历到innerdiv上,发现也注册了click事件,就触发innerdiv的click事件。
//冒泡模式 innerdiv.addEventListener('click', function (event) { console.log('innerdiv 冒泡模式', event); }, false) outdiv.addEventListener('click', function (event) { console.log('outdiv 冒泡模式 ', event); }, false) //result innerdiv then outdiv
原理:冒泡模式,即在冒泡阶段触发该函数,当在捕获阶段,即便遍历到outdiv时,发现,其身上注册了事件,也不会触发,只有等到冒泡阶段,而冒泡阶段是先遍历到innerdiv,
所以会先触发innerdiv上的click。
总结:当innerdiv 和outdiv分别使用不同模式的时候,则谁是捕获模式,就先触发当前节点上注册的事件。
二、注意点
1、在同一个节点上,事件注册的顺序,会影响它的执行顺序,。
//捕获和冒泡模式下都注册 outdiv.addEventListener('click', function (event) { console.log('outdiv 捕获模式 ', event); }, true) outdiv.addEventListener('click', function (event) { console.log('outdiv 冒泡模式 ', event); }, false) innerdiv.addEventListener('click', function (event) { console.log('innerdiv 捕获模式', event); }, true) innerdiv.addEventListener('click', function (event) { console.log('innerdiv 冒泡模式', event); }, false) // result outdiv innerdiv then innerdiv outdiv
outdiv.addEventListener('click', function (event) { console.log('outdiv 捕获模式 ', event); }, true); outdiv.addEventListener('click', function (event) { console.log('outdiv 冒泡模式 ', event); }, false); innerdiv.addEventListener('click', function (event) { console.log('innerdiv 冒泡模式', event); }, false); innerdiv.addEventListener('click', function (event) { console.log('innerdiv 捕获模式', event); }, true); // result outdiv 捕获 innerdiv 冒泡 then innerdiv捕获 outdiv冒泡
总结: 非目标元素捕获 -> 目标元素代码顺序 -> 非目标元素冒泡。
2、event.stopPropagation()
并不是说,在冒泡阶段阻止事件的发生,而是不仅阻止了事件的冒泡,还阻止事件的继续捕获,简而言之,就是阻止事件的进一步传播。
所以,当事件都是在捕获阶段注册,也是能够阻止的;
例子:
outdiv.addEventListener('click', function (event) { console.log('outdiv ', event); }, false); innerdiv.addEventListener('click', function (event) { console.log('innerdiv', event); event.stopPropagation(); }, false);
原理:两个事件谁先触发,谁才能阻止后一个事件的触发
比如,当两个事件都是冒泡阶段,如果不做任何操作,所以innerdiv的click事件,先于outdiv触发,
所以,在innerdiv里面写上,stoppropagation,是能够阻止outdiv的click事件的触发的
outdiv.addEventListener('click', function (event) { console.log('outdiv ', event); event.stopPropagation(); }, true); innerdiv.addEventListener('click', function (event) { console.log('innerdiv', event); }, true);
再比如,当两个事件都是捕获阶段触发,如果不做任何操作,outdiv的click事件,先于innerdiv触发,
所以 ,只能 在outdiv里面写上stoppropagation,才能阻止innerdiv的click事件的触发,但是,问题来了,
既然这样,那么innerdiv上面的事件再也触发不了,其实,也不用担心,因为,我们日常所使用的事件都是在冒泡阶段触发的,
换句话说,点击子节点可以决定是否触发父节点的click,但是,点击父节点,不能决定是否触发子节点的click。
3、stopImmediatePropagation()
例子,
innerdiv.addEventListener('click', function (event) { console.log('innerdiv', event); event.stopImmediatePropagation(); }, false); innerdiv.addEventListener('click', function (event) { console.log('innerdiv22222', event); }, false); //result: innerdiv
相关文章推荐
- js事件冒泡、事件捕获和阻止默认事件详解
- js冒泡、捕获事件及阻止冒泡方法
- js冒泡、捕获事件及阻止冒泡方法详细总结
- javascript中的事件绑定、事件冒泡、事件捕获和事件执行顺序
- JavaScript中关于事件绑定、冒泡、捕获和执行顺序
- Javascript 事件的捕获,冒泡和目标阶段的回调函数执行顺序
- 看懂此文,不再困惑于javascript中的事件绑定、事件冒泡、事件捕获和事件执行顺序
- DOM事件阶段以及事件捕获与事件冒泡先后执行顺序(图文详解)
- [JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播
- Atitit. Js 冒泡事件阻止 事件捕获 事件传递 事件代理
- js之事件冒泡和事件捕获及其阻止详细介绍
- javaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序整理总结
- Atitit. Js 冒泡事件阻止 事件捕获 事件传递 事件代理
- Atitit. Js 冒泡事件阻止 事件捕获 事件传递 事件代理
- JavaScript-父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序
- DOM事件阶段以及事件捕获与事件冒泡先后执行顺序(图文详解)
- DOM事件阶段以及事件捕获与事件冒泡先后执行顺序
- 看懂此文,不再困惑于javascript中的事件绑定、事件冒泡、事件捕获和事件执行顺序
- JS事件绑定、冒泡/捕获、常见的兼容处理、委托、阻止默认行为和冒泡
- js 事件冒泡详解、 捕获、阻止方法