JS的冒泡事件和捕获事件实例讲解
事件的三阶段
1. 捕获阶段
当一个元素上的某个事件被触发的时候,就会有一个事件发射过去。这个事件从 window 发出,不断经过下级节点直到触发的目标节点。在到达目标节点之前的过程,就是捕获阶段。
2. 目标阶段
当事件不断的传递直到目标节点的时候,最终在目标节点上触发这个事件,就是目标阶段。
3. 冒泡阶段
当一个元素上的某个事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一阶段被称为冒泡阶段。
冒泡事件
1. 定义:
当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡。
这个事件从原始元素开始一直冒泡到dom树的最上层。子元素事件被触动,父盒子的同样的事件也会被触动。
下面以案例说明:
//为box1,box2,box3以及document都绑定了点击事件 box1.onclick = function () { console.log("我是box1") } box2.onclick = function () { console.log("我是box2") } box3.onclick = function (event) { console.log("我是box3") } document.onclick = function () { console.log("我是document") }
展示图如下:
结果如下:
① 当点击document部分,结果:
② 当点击box1盒子,结果:
③ 当点击box2盒子,结果:
④ 当点击box3盒子,结果:
发现:
元素事件被触发后,如果他的祖先元素也有该事件,那么祖先元素也会触发该事件,并且是由内往外的顺序,由小到大,即是事件冒泡。
注意:
由于有事件冒泡这个机制,会给程序带来一些不必要的麻烦,因此需要阻止冒泡。
2. 阻止冒泡
火狐谷歌,ie11等 用event.stoppropagation()
ie10及以下 用 event.cancelbubble = true
采用兼容写法:
event = event || window.event; if(event && event.stoppropagation()){ event.stoppropagation(); }else { event.cancelbubble = true; }
那么在上面的案例中:
使box3阻止冒泡,将上述代码修改成以下代码:
box3.onclick = function (event) { //在box3的点击事件中阻止冒泡,阻止后,冒泡将停止不会再执行父系的click事件 event = event || window.event; if(event && event.stoppropagation()){ event.stoppropagation(); } else { event.cancelbubble = true; } console.log("我是box3") }
修改之后,点击box3,可以发现: 只打印了 “ 我是box3 ”,这样就阻止了冒泡
捕获事件
捕获事件是与冒泡相反的方向执行的,由外向内执行,先执行父事件再向内执行,直接当前事件。
利用addeventlistener方法来实现事件捕获。
target.addeventlistener(type, listener, usecapture)
type:监听事件类型的字符串。
listener:事件处理函数。
usecapture:布尔类型值。
usecapture | value |
---|---|
false(默认值) | 表示冒泡事件(由小)。由内往外执行,先执行当前事件再向外执行,直到执行完父事件。 |
true | 表示捕获事件。由外向内执行,先执行父事件再向内执行,直接当前事件 |
将上述案例的js代码改为捕获:
box1.addeventlistener("click",function () { console.log("我是box1") },true); box2.addeventlistener("click",function () { console.log("我是box2") },true); box3.addeventlistener("click",function () { console.log("我是box3") },true); document.addeventlistener("click",function () { console.log("我是document") },true);
点击box3时: