前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript捕获和冒泡探讨

JavaScript捕获和冒泡探讨

作者头像
前端开发博客
发布2020-11-04 10:03:39
4970
发布2020-11-04 10:03:39
举报
文章被收录于专栏:前端开发博客

上个星期在微博中一个关于javascript捕获和冒泡代码的讨论,可能没有动手实现一篇的人无法给出确定的答案。

这里再来回顾一下之前的三条微博。

事件的执行顺序

JavaScript冒泡和捕获考察题目看图回答问题,晚上公布答案。 问:点击Li,JS的执行顺序是什么?

总结就是:先捕获,后冒泡,捕获从上到下,冒泡从下到上(形象点说法:捕获像石头沉入海底,冒泡则像气泡冒出水面) 问:假如去掉注释 event.stopPropagation(); 结果又会输出什么?

答:去掉event.stopPropagation() 之后,由于事件有捕获和冒泡时先执行捕获,捕获到div之后,事件被阻止,后面就不在继续传播了。所以只输出divcallback.

在上面的代码如果增加一个div.addEventListener('click',callbackdiv2,false); 则div先执行捕获,接着执行上面这句冒泡,所以微博里的一个朋友评论说事件执行过捕获就不会执行冒泡其实是不对的。 div.addEventListener('click',callbackdiv,true);这一句只能是捕获才执行。

以上代码代码:演示

事件不同浏览器处理函数

  • element.addEventListener(type, listener[, useCapture]); // IE6~8不支持(捕获和冒泡通过useCapture,默认false)
  • element.attachEvent(’on’ + type, listener); // IE6~10,IE11不支持(只执行冒泡事件)
  • element[’on’ + type] = function(){} // 所有浏览器(默认执行冒泡事件)

W3C规范中定义了3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。事件对象按照上图的传播路径依次完成这些阶段。如果某个阶段不支持或事件对象的传播被终止,那么该阶段就会被跳过。举个例子,如果Event.bubbles属性被设置为false,那么冒泡阶段就会被跳过。如果Event.stopPropagation()在事件派发前被调用,那么所有的阶段都会被跳过。

  • 捕获 阶段:在事件对象到达事件目标之前,事件对象必须从window经过目标的祖先节点传播到事件目标。 这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件。
  • 目标 阶段:事件对象到达其事件目标。 这个阶段被我们称为目标阶段。一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。
  • 冒泡 阶段: 事件对象以一个与捕获阶段相反的方向从事件目标传播经过其祖先节点传播到window。这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。

在一个事件完成了所有阶段的传播路径后,它的Event.currentTarget会被设置为null并且Event.eventPhase会被设为0。Event的所有其他属性都不会改变(包括指向事件目标的Event.target属性).

跨浏览器的事件处理函数:

代码语言:javascript
复制
var EventUtil = {  
addHandler: function(element, type, handler) {    
if (element.addEventListener) {  // DOM2
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {  // IE
element.attachEvent('on' + type, handler);
} else {  // DOM0
element['on' + type] = handler;
}
},  
removeHandler: function(element, type, handler) {    
if (element.removeEventListener) {      
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {      
element.detachEvent('on' + type, handler);
} else {      
element['on' + type] = null;
}
}
};

跨浏览器的事件对象:

代码语言:javascript
复制
var EventUtil = {  
getEvent: function(e) {    
return e ? e : window.e;
},  
getTarget: function(e) {    
return e.target || e.srcElement;
},  
preventDefault: function(e) {    
if (e.preventDefault) {      
e.preventDefault();
} else {      
e.returnValue = false;
}
},  
stopPropagation: function(e) {    
if (e.stopPropagation) {      
e.stopPropagation()
} else {      
e.cancelBubble = true;
}
}
}

可以看我之前写过的一篇文章:如何停止冒泡和阻止默认行为

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端开发博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 事件的执行顺序
  • 事件不同浏览器处理函数
  • 跨浏览器的事件处理函数:
  • 跨浏览器的事件对象:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档