再谈事件冒泡之前,先谈一谈事件对象
由于在IE-DOM和标准DOM实现事件对象的方法各不相同,那究竟有什么不同,我们可以来看一下:
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含所有与事件有关的信息,包括导致事件的元素,事件类型以及其他与特定事件相关的信息。
在兼容DOM的浏览器会将一个event对象传入事件处理程序中。无论指定事件处理程序中指定什么方法(DMO0级或者DOM2级),都会传入event对象,但是与访问DOM 中的event对象不同,要访问IE对象有几种不同的方式,取决于指定事件处理程序的方法。在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在,我们可以通过window对象来获取event对象,如果事件处理程序是使用attachEvent()添加的,那么就会有一个event对象作为参数被传入到事件处理程序函数中去。
在JS中,虽然DOM和IE中的event对象不同,但是基于它们之间的相似 性(IE中的event对象的全部信息和方法DOM对象中都有,只不过实现方式不太一样),我们可以根据这种关系来找到两者之间的映射,求同存异。
下面是一段针对到跨浏览器的事件对象的兼容代码:
var EventUtil = {
addHandler: function(element,type,handler){
if(element.addEventListener){
//在jQuery中,不支持事件捕获,如果需要使用事件捕获,需要使用JS的原生代码
element.addEventListener(type,handler,false);//false表示在事件冒泡期间将其捕获
}else if(element.attachEvent){//对于IE浏览器的事件捕获函数
element.attachEvent("on"+type,handler);
}else{
element["on"+type] = handler;
}
},
getEvent:function(event){
return event?event:window.event;
},
getTarget:function(){
return event.target||event.srcElement;
},
//在jQuery中可以利用stopPropagation()来阻止事件冒泡
preventDefault:function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
}
那针对不同浏览器中事件对象实现方法各不相同的问题,jQuery进行了必要的扩展和封装,从而使得在任何浏览器中都可以轻松获取事件对象以及事件对象的属性以及方法
什么是事件冒泡?
页面上可以有多个事件,也可以多个元素响应同一个事件。假设网页上有两个元素,其中一个元素嵌套在另一个元素里面,并且绑定了click事件,同时在body元素上也绑定了click事件,代码如下:
<body>
<div id="content" style="width: 200px;height: 200px;background-color: pink;">
<span style="width:100px;height: 100px;background-color: skyblue;">内层span元素</span>
</div>
<div id="msg"></div>
</body>
$(function(){
$('span').click(function(){
alert("haha");
var txt = $('msg').html()+'<span>内层span元素被单击</span>';
$('#msg').html(txt);
});
//为div绑定click事件
$('#content').click(function(){
var txt = $('#msg').html()+'<p>外层的div元素被单击.<p>';
$('#msg').html(txt);
});
//为body添加点击事件
$('body').click(function(){
var txt = $('#msg').html()+'<p>body元素被单击</body>';
$('#msg').html(txt);
})
})
当点击内部的span元素时,同时也会触发div和body上绑定的click事件,这就是由事件冒泡所引起的。
在单击元素的同时,也单击了包含元素的元素
元素click事件会按照以下顺序响应:
1.
<span>
2.
<div>
3.
<body>
如何阻止事件冒泡?
事件冒泡可能会引起预料之外的效果,在jQuery中可以使用stopPropagation()方法来阻止事件冒泡
例如上面的代码可以修改为下面的这种形式,即可以阻止事件冒泡的发生:
$(function(){
$('span').click(function(event){
alert("haha");
var txt = $('msg').html()+'<span>内层span元素被单击</span>';
$('#msg').html(txt);
event.stopPropagation();//停止事件冒泡
});
})
阻止事件的默认行为
网页上的元素有自己的默认行为,例如单击超链接之后会跳转,单击“提交”按钮会提交,有时候需要阻止事件的默认行为
jQuery中提供了preventDefault()方法来阻止事件的默认行为
事件捕获
事件捕获和事件冒泡是截然相反的两个过程,事件捕获是从最顶端开始向下触发,但是并不是所有的主流浏览器都支持事件捕获,如果需要使用事件捕获,需要使用原生的JS代码。