持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
一、事件机制(事件流)
浏览器中的事件流意味着页面上可有不仅一个,甚至多个元素响应同一个事件。 而这一个或多个元素响应事件发生的先后顺序在各个浏览器(主要针对IE和Netscape)上是不同的。
冒泡型事件(Dubbed Bubbling)
IE上的解决方案就是冒泡型事件(Dubbed Bubbling),冒泡型事件的基本思想是, 事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
捕获型事件(Event Capturing)
相对IE4.0,Netscape4.0则使用的是捕获型事件的解决方案。
这个事件触发的过程则正好和冒泡相反——在捕获型事件中,事件从最不精确的对象(document对象)开始触发,然后到最精确的对象。
**DOM 事件流 **
这个事件流则是W3C制定一个标准规范,它同时支持两种事件流模式, 不过是先发生捕获型事件流,再发生冒泡型事件流。
DOM事件流最独特的是,它支持文本节点也触发事件(IE中这不支持)。
二、事件绑定
事件处理函数/监听函数
1、在DOM元素中直接绑定
2、在JavaScript代码中绑定
3、绑定事件监听函数
具体实践:
IE中attachEvent(”NAME_OF_EVENT_HANDLER”, fnHandler)给元素绑定事件;
而在支持DOM事件流的浏览器里,则使用addEventListener(”NAME_OF_EVENT_HANDLER”, fnHandler, isCapture);
前面控制FIREFOX中触发捕获事件流,就是通过设置isCapture(ture:捕获;false:冒泡)做到的;
function addEvent(obj,type,handle){
try{ // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
obj.addEventListener(type,handle,false);
}catch(e){
try{ // IE8.0及其以下版本
obj.attachEvent('on' + type,handle);
}catch(e){ // 现代浏览器
obj['on' + type] = handle;
}
}
}
哪些事件是支持冒泡,那些不支持?
基本上只有onload,unload,focus,blur,submit和change事件是不支持冒泡的;
像keydownkeypress,keyup,click,dbclick,mousedown,mouseout,mouseover,mouseup,mousemove支持冒泡
三、事件委托
document.onclick,这个示例把事件委托放到了document上,即点击document就直接触发我们相应的事件。
document.onclick = function(event){
var event = event || window.event; //IE doesn't pass in the event object
var target = event.target || event.srcElement; //IE uses srcElement as the target
switch(target.id){
case "help-btn":
openHelp();
break;
case "save-btn":
saveDocument();
break;
case "undo-btn":
undoChanges();
break;
//如果有其元素需要处理点击事件, 只需要在这里添加不同的case分支就行。
}
};
优点:
从“处理速度”、“新增元素事件处理”和“内存消耗”三方面比较了“事件委托”和“事件绑定”的对比,
可以很容易看出,“事件委托”在“处理速度”和“内存消耗”上,有得天独厚的优势。
所以,在Web编程的时候,尤其在构建大型系统的时候,应该尽量考虑使用“事件委托”。
缺点:
使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。
事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。
四、阻止事件冒泡和阻止事件默认行为
1.阻止事件冒泡
function stopBubble(e) {
//如果提供了事件对象,则这是一个非IE浏览器
if ( e && e.stopPropagation ){
e.stopPropagation(); //因此它支持W3C的stopPropagation()方法
}else{
window.event.cancelBubble = true; //否则,我们需要使用IE的方式来取消事件冒泡
}
}
2.当按键后,不希望按键继续传递给如HTML文本框对象时,可以取消返回值.即停止事件默认行为;
//阻止浏览器的默认行为
function stopDefault(e) {
//如果提供了事件对象,则这是一个非IE浏览器
if (e && e.preventDefault ){
e.preventDefault(); //阻止默认浏览器动作(W3C)
}else{
window.event.returnValue = false; //IE中阻止函数器默认动作的方式
}
}