事件冒泡和事件捕获
1、什么是事件冒泡
在页面上可以有多个事件,也可以多个元素响应同一个事件。假设页面上有两个元素,其中一个元素嵌套在另一个元素里,并且都被绑定了click事件,同时<body>元素也绑定了click事件,完整代码如下:
<script> $(function(){ //为span元素绑定click事件 $("span").bind("click",function(){ var txt=$("#msg").html()+"<p>内层span元素被单击</p>"; $("#msg").html(txt); }); //为div元素绑定click事件 $("#content").bind("click",function(){ var txt=$("#msg").html()+"<p>外层div元素被单击</p>"; $("#msg").html(txt); }); //为body元素绑定click事件 $("body").bind("click",function(){ var txt=$("#msg").html()+"<p>body元素被单击</p>"; $("#msg").html(txt); }); }) </script> <div id="content"> 外层div元素 <span>内层span元素</span> 外层div </div> <div id="msg"></div>
当单击<span>元素,即触发<span>元素的click事件,会输出3条记录来,这就是由事件冒泡引起的。如图所示:
再单击<span>元素的同时,也单击了包含<span>元素的元素<div>和包含<div>元素的元素<body>,并且每一个元素都会按照特定的顺序响应click事件。
元素的click事件会按照以下顺序“冒泡”。
(1)<span>
(2)<div>
(3)<body>
之所以成为冒泡,是因为事件会按照DOM的层次结构像水泡一样不断向上直至顶端,如图
2、停止事件冒泡
停止事件冒泡可以组织事件中其他对象的事件处理函数被执行,在jQuery中提供了stopPropagation()方法来停止事件冒泡。
jQuery代码如下:
$("span").bind("click",function(event){ //event:事件对象 var txt=$("#msg").html()+"<p>内层span元素被单击</p>"; $("#msg").html(txt); event.stopPropagation(); //停止事件冒泡 });
当单击<span>元素时,只会触发<span>元素上的click事件,而不会触发<div>元素和<body>元素的click事件。
可以用同样的方法<div>上的冒泡问题。
3、阻止默认行为
网页中的元素有自己的默认行为,例如,单击超链接后会跳转、单击“提交”按钮后表单会提交,有时需要阻止元素的默认行为。
在jQuery中,提供了preventDefault()方法来阻止元素的默认行为。
举一个例子,在项目中,经常需要验证表单,再单击“提交”按钮时,验证表单内容,例如某元素是否是必填字段,某元素长度是否够6位等,当不符合提交条件时,要阻止表单的提交(默认行为)。
代码如下:
<script> $(function(){ $("#sub").bind("click",function(event){ var username=$("#username").val(); if(username == ""){ $("#msg").html("<p>文本框的值不能为空</p>"); event.preventDefault(); //阻止默认行为(表单提交) } }) }) </script>
如果想同时对事件对象停止冒泡和默认行为,可以在事件处理函数中返回false。这是对在事件上同时调用stopPropagation()方法和preventDefault()方法的一种简写方式。
在表单的例子中,可以把
event.preventDefault(); //阻止默认行为(表单提交)
改写为: return false;
也可以把事件冒泡例子中的
event.stopPropagation(); //停止事件冒泡
改写为: return false;
4、事件捕获
事件捕获和事件冒泡是刚好相反的两个过程,事件捕获是从最顶端往下开始触发。
还是冒泡事件的例子,其中元素的click事件会按照以下顺序捕获。
(1)<body>
(2)<div>
(3)<span>
很显然,事件捕获是从最外层元素开始,然后再到最里层元素。因此绑定的click事件,首先会传递给<body>元素,然后传递给<div>元素,最后才传递给<span>元素。
遗憾的是,并非所有主流浏览器都支持事件捕获,并且这个缺陷无法通过javaScript来修复,jQuery不支持事件捕获,如果需要使用时间捕获,请直接使用原生的javaScript.