JavaScript单线程和浏览器事件循环简述
- - 破狼 BlogJavaScript单线程. 在上篇博客 《Promise的前世今生和妙用技巧》的开篇中,我们曾简述了JavaScript的单线程机制和浏览器的事件模型. 应很多网友的回复,在这篇文章中将继续展开这一个话题. 当然这里是博主的一些理解,如果还存在什么纰漏的话,请不吝指教. JavaScript这门语言运行在浏览器中,是以单线程的方式运行的.
最近在阅读 javascript高级程序设计
,事件这一块还是有很多东西要学的,就把一些思考和总结记录下。
在事件处理,事件对象,阻止事件的传播等方法或对象存在着浏览器兼容性问题,开发过程中最好编写成一个通用的事件处理工具。
(function(){
var EU = {};
//...
//在这里添加一些通用的事件处理方法
//...
window.EventUtil = EU;
})();
事件的绑定主要为IE8以下浏览器做兼容处理:
IE8以下只支持事件冒泡
IE事件处理使用attachEvent
detachEvent
EU.addHandler = function(element,type,handler){
//DOM2级事件处理,IE9也支持
if(element.addEventListener){
element.addEventListener(type,handler,false);
}
else if(element.attachEvent){
//type加'on'
//IE9也可以这样绑定
element.attachEvent('on' + type,handler);
}
//DOM0级事件处理步,事件流也是冒泡
else{
element['on' + type] = handler;
}
};
和绑定事件的处理基本一致,有一个注意点:
传入的
handler
必须与绑定事件时传入的相同(指向同一个函数)
EU.removeHandler = function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler);
}
else if(element.attachEvent){
element.detachEvent('on' + type,handler);
}
else{
//属性置空就可以
element['on' + type] = null;
}
};
注意点:
IE下
event
是全局对象,通过window.event
取得
EU.getEvent = function(event){
return event || window.event;
}
注意点:
IE下通过
attachEvent
绑定事件,内部this
并非触发事件的DOM
,而是window;
通过目标对象来获取DOM
节点,IE下是srcElement
属性,等同于其他浏览器的target
属性
EU.addTarget = function(event){
return event.target || event.srcElement;
}
EU.preventDefault = function(event){
if(event.preventDefault){
event.preventDefault();
}
//IE下处理
else{
event.returnValue = false; //默认为true
}
}
关于 事件默认行为
EU.stopPropagation = function(event){
if(event.stopPropagation){
event.stopPropagation();
}
//IE下处理
else{
event.cancelBubble = true;//默认为false,注意区分于returnValue
}
}
注意点:
阻止的是
DOM层级
间的事件传播
比如:对于一个DOM元素,同时绑定捕获事件与冒泡事件,如果在捕获阶段使用 stopPropagation
,不会阻断冒泡事件的执行;
Demo地址: http://runjs.cn/detail/hyrdjfyj
如果对子元素和父元素以冒泡形式都绑定'click'事件,在子元素的事件处理中使用 stopPropagation
阻止事件传播,父元素绑定的 click
事件不会执行。
Demo地址: http://runjs.cn/detail/sf0t1bso