1.事件处理程序的返回值
通常情况下,返回值false就是告诉浏览器不要执行这个事件相关的默认操作。例如,表单提交按钮的onclick事件处理程序能通过返回false阻止 浏览器提交表单,再如a标签的onclick事件处理程序通过返回false阻止跳转href页面。类似地,如果用户输入不合适的字符,输入域上的 onkeypress事件处理程序能通过返回false来过滤键盘输入。
事件处理程序的返回值只对通过属性注册的处理程序才有意义。
2.调用顺序
文档元素或其他对象可以为指定事件类型注册多个事件处理程序。当适当的事件发生时,浏览器必须按照如下规则调用所有的事件处理程序:
- 通过设置对象属性或HTML属性注册的处理程序一直优先调用。
- 使用addEventListener()注册的处理程序按照它们的注册顺序调用。
- 使用attachEvent()注册的处理程序可能按照任何顺序调用,所以代码不应该依赖于调用顺序。
3.事件传播
在调用在目标元素上注册的事件处理函数后,大部分事件会“冒泡”到DOM树根。调用目标的父元素的事件处理程序,然后调用在目标的祖父元素上注册的事件处理程序。这会一直到Document对象,最后到达Window对象。
发生在文档元素上的大部分事件都会冒泡,值得注意的例外是focus、blur和scroll事件。文档元素的load事件会冒泡,但它会在 Document对象上停止冒泡而不会传播到Window对象。只有当整个文档都加载完毕时才会触发Window对象的load事件。
4.取消事件默认行为、阻止事件传播
在支持addEventListener()的浏览器中,可以通过调用事件对象的preventDefault()方法取消事件的默认操作。IE9之前的IE中,可以通过设置事件对象的returnValue属性为false达到同样的效果。下面一段代码是结合三种技术取消事件:
function cancelHandler(event){ var event=event||window.event;//兼容IE //取消事件相关的默认行为 if(event.preventDefault) //标准技术 event.preventDefault(); if(event.returnValue) //兼容IE9之前的IE event.returnValue=false; return false; //用于处理使用对象属性注册的处理程序}
取消事件相关的默认操作只是事件取消中的一种,我们也能取消事件传播。在支持addEventListener()的浏览器中,可以调用事件对象的stopPropagation()方法以阻止事件的继续传播。如果在同一对象上定义了其他处理程序,剩下的处理程序将依旧被调用,但调用stopPropagation()之后任何其他对象上的事件处理程序将不会被调用。
IE9之前的IE不支持stopPropagation()方法,而是设置事件对象cancelBubble属性为true来实现阻止事件进一步传播。
js中的preventDefault与stopPropagation详解
首先讲解一下js中preventDefault和stopPropagation两个方法的区别:
preventDefault 方法的起什么作用呢?我们知道比如<a href="http://www.baidu.com">百度</a>,这是html中最基础的东西,起的作用就是点击百度链接到 http://www.baidu.com,这是属于<a>标签的默认行为,而preventDefault方法就是可以阻止它的默认行为的 发生而发生其他的事情。看一段代码大家就明白了:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JS阻止链接跳转</title>
<script type="text/javascript">
function stopDefault( e ) {
if ( e && e.preventDefault )
e.preventDefault();
else
window.event.returnValue = false;
return false;
}
</script>
</head>
<body>
<a href="http://www.baidu.com" id="testLink">百度</a>
<script type="text/javascript">
var test = document.getElementById('testLink');
test.onclick = function(e) {
alert('我的链接地址是:' + this.href + ', 但是我不会跳转。');
stopDefault(e);
}
</script>
</body>
</html>
此时点击百度链接,不会打开http://www.baidu.com,而只是弹出一个alert对话框。preventDefault方法讲解到这里,stopPropagation方法呢?讲stopPropagation方法之前必需先给大家讲解一下js的事件代理。
事件代理用到了两个在JavaSciprt事件中常被忽略的特性:事件冒泡以及目标元素。当一个元素上的事件被触发的时候,比如说鼠标点击了一个按 钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。对任何一个事件来 说,其目标元素都是原始元素,在我们的这个例子中也就是按钮。目标元素它在我们的事件对象中以属性的形式出现。使用事件代理的话我们可以把事件处理器添加 到一个元素上,等待事件从它的子级元素里冒泡上来,并且可以很方便地判断出这个事件是从哪个元素开始的。
stopPropagation方法就是起到阻止js事件冒泡的作用,看一段代码。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xHTML1/DTD/xHTML1-transitional.dtd">
<HTML XMLns="http://www.w3.org/1999/xHTML" lang="gb2312">
<head>
<title> 阻止JS事件冒泡传递(cancelBubble 、stopPropagation)</title>
<meta name="keywords" content="JS,事件冒泡,cancelBubble,stopPropagation" />
<script>
function doSomething (obj,evt) {
alert(obj.id);
var e=(evt)?evt:window.event;
if (window.event) {
e.cancelBubble=true;// ie下阻止冒泡
} else {
//e.preventDefault();
e.stopPropagation();// 其它浏览器下阻止冒泡
}
}
</script>
</head>
<body>
<div id="parent1" onclick="alert(this.id)" style="width:250px;
<p>This is parent1 div.</p>
<div id="child1" onclick="alert(this.id)" style="width:200px;
<p>This is child1.</p>
</div>
<p>This is parent1 div.</p>
</div>
<br />
<div id="parent2" onclick="alert(this.id)" style="width:250px;">
<p>This is parent2 div.</p>
<div id="child2" onclick="doSomething(this,event);" style="width:200px;">
<p>This is child2. Will bubble.</p>
</div>
<p>This is parent2 div.</p>
</div>
</body>
</HTML>---------------------------------------------------------
JS中的事件传播和默认事件取消
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>无标题文档</title>
- </head>
- <body>
- <div id="outDiv" style="display:block;width:100px; height:100px;padding:50px;background-color:#060;">
- <div id="inDiv" style="display:block;width:100px; height:100px; background-color:#FFF;"></div>
- </div>
- <a id="link" href="http://www.jask.cn" target="_blank">Jask</a>
- <script>
- //事件传播
- /*
- 当事件目标是Window对象或其他一些单独对象时,浏览器简单地通过调用对象上适当的处理程序响应事件,
- 当目标对象是文档或文档元素时,大部分事件都会“冒泡”到DOM树根,调用目标的父元素的事件处理程序,然后调用在目标祖父元素上注册的事件处理程序,一直到Domcument对象上,最后到达Window对象。
- 注意:focus blur scroll事件除外其它的大部分事件都会冒泡
- */
- var outDiv = document.getElementById("outDiv");
- var inDiv = document.getElementById("inDiv");
- var links = document.getElementById("link");
- //第三个参数是false是这个冒泡的执行顺序是从内到外,反之,从外到内执行;
- //DOMContentLoaded 这个相当于load
- window.addEventListener("click",function(){alert("load");},false);
- inDiv.addEventListener("click",function(){alert("inDiv");},false);
- outDiv.addEventListener("click",function(event){alert("outDiv");
- //这个是组织向上冒泡的IE8之前的不支持
- //停止向上冒泡执行window中的属性click
- //event.stopPropagation(); //标准
- //event.cancelBubble = true; //IE
- },false);
- //取消默认操作,也就是默认事件,在这里是取消了一个a连接属性href的地址,设置了,就取消了打开www.jask.cn的页面,
- //点击这个连接是一个默认打开新面的事件所以是默认操作
- //如 submit 也有他的默认操作
- links.addEventListener("click",function(event){
- event.preventDefault(); //标准
- //event.returnValue = false //IE
- //return false; //用于处理使用对象属性注册的处理程序
- },false);
- //事件传播和默认操作是二个不同的机制,
- //一个是向上冒泡 一个是执行默认操作
- </script>
- </body>
- </html>