JS 事件冒泡和事件捕获 事件委托

发现之前学的一些知识,不怎么用的时候容易忘记,这样不好,所以记录下来

      他们是描述事件触发时序问题的术语。
      事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。事件从最上一级标签开始往下查找,直到捕获到事件目标(target)。
      相反的,事件冒泡是自下而上的去触发事件。事件从事件目标(target)开始,往上冒泡直到页面的最上一级标签。

      支持W3C标准的浏览器在添加事件时用 addEventListener(event,fn,useCapture) 方法,基中第3个参数 useCapture 是一个Boolean值,用来设置事件是在事件捕获时执行,还是事件冒泡时执行。而不兼容W3C的浏览器(IE)用 attachEvent() 方法,此方法没有相关设置,不过IE的事件模型默认是在事件冒泡时执行的,也就是在 useCapture 等于false的时候执行,所以把在处理事件时把 useCapture 设置为false是比较安全,也实现兼容浏览器的效果。PS:true–捕获,false–冒泡,IE9及以上支持addEventListener

举个例子

1
2
3
<div>
<p>Hello World!</p>
</div>

如果给上面 divp 标签都绑定了 click 事件,那么哪一个先触发呢?
如果 div 绑定的 click 事件先触发,就是事件捕获,如果 p 绑定的事件先触发,就是事件冒泡。

例:

1
2
3
4
5
6
7
8
9
<div id="parent">
<p id="child">Hello World!</p>
</div>
var parent = document.getElementById('parent');
var child = document.getElementById('child');
parent.addEventListener('click', function(){console.log('parent')}, true)
child.addEventListener('click', function(){console.log('child')}, true)
// parent
// child

DOM事件流

将事件分为三个阶段:捕获阶段、目标阶段、冒泡阶段。先调用捕获阶段的处理函数,其次调用目标阶段的处理函数,最后调用冒泡阶段的处理函数。document –> target –> document,先自上而下到目标,在从目标自下而上。

阻止事件冒泡和捕获

IE8以及以前可以通过 window.event.cancelBubble=true 阻止事件的继续传播。IE9+/FF/Chrome通过event.stopPropagation()阻止事件的继续传播。

一段有意思的代码(来自 http://blog.csdn.net/aitangyong/article/details/43231111):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
window.onload = function(){
var outA = document.getElementById("outA");
var outB = document.getElementById("outB");
var outC = document.getElementById("outC");
// 目标
outC.addEventListener('click',function(event){alert("target");},false);
// 事件冒泡
outA.addEventListener('click',function(){alert("bubble");},false);
// 事件捕获
outA.addEventListener('click',function(){alert("capture");event.stopPropagation();},true);
};
</script>
<body>
<div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">
<div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">
<div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div>
</div>
</div>
</body>

最终只打印了 capture,这是因为 DOM事件流先发生事件捕获,也就是先执行 outA.addEventListener(‘click’,function(){alert(“capture”);event.stopPropagation();},true); ,但是该代码内通过 event.stopPropagation() 阻止了事件的传播,所以接下来的事件冒泡并没有出现。

事件委托请查看:http://www.cnblogs.com/liugang-vip/p/5616484.html

Newer Post

插件

波浪进度指示器:https://github.com/newraina/waveLoading.js 移动web端调试工具 eruda :https://github.com/liriliri/eruda 规则引擎的介绍与 Drools 的流程分析:http://www.jianshu.com …

继续阅读
Older Post

vue学习

VueJS 开发常见问题集锦 请看 https://segmentfault.com/a/1190000010230843#articleHeader11 新手向:Vue 2.0 的建议学习顺序–尤雨溪 请看 https://zhuanlan.zhihu.com/p/23134551 vue-cl …

继续阅读