js事件冒泡和事件捕获详解
Javascript与HTML之间的交互是通过事件实现。
一、事件流
事件,是文档或浏览器窗口中发生的一些特定的交互瞬间。事件流,描述的是页面中接受事件的顺序。IE9,chrome,Firefox,Opera,Safari均实现了DOM2级规范中定义的标准DOM事件,而IE8和IE8以下版本仍然保留专有的事件处理方式。
事件冒泡
事件冒泡是由IE开发团队提出来的,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Event Bubbling Example</title>
</head>
<style type="text/css">
#myDiv{
width:100px;
height:100px;
background-color:#FF0000;
}
</style>
<body>
<div id="myDiv"></div>
</body>
</html>

当用户点击了<div>元素,click事件将按照<div>—><body>—><html>—>document的顺序进行传播。若在<div>和<body>上都定义了click事件,如下:

<script type="text/javascript">
var div=document.getElementById("myDiv");
div.onclick=function(event){
alert("div");
};
document.body.onclick=function(event){
alert("body");
};
</script>

点击<div>,将先输出“div”,再输出“body”。
IE9,chrome,Firefox,Opera,Safari都支持事件冒泡,并将事件冒泡到window对象。
事件捕获
事件捕获是由Netscape Communicator团队提出来的,是先由最上一级的节点先接收事件,然后向下传播到具体的节点。当用户点击了<div>元素,采用事件捕获,则click事件将按照document—><html>—><body>—><div>的顺序进行传播。
若在<div>和<body>上都定义了click事件,如下:

<script type="text/javascript">
var div=document.getElementById("myDiv");
div.addEventListener("click",function(event){
alert("div");
},true);
document.body.addEventListener("click",function(event){
alert("body");
},true); </script>

(注:addEventListener具体使用见本文DOM2级事件处理)
点击<div>,将先输出“body”,再输出“div”。
IE9,chrome,Firefox,Opera,Safari都支持事件捕获,但是IE8和IE8以下的版本只支持事件冒泡。尽管DOM2规范要求事件应该从document对象开始传播,但是现在的浏览器实现都是从window对象开始捕获事件。
DOM事件流
"DOM2级事件”规定的事件流包含三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,然后是实际的目标接收到事件,最后阶段是冒泡阶段。以上面的HTML页面为例,单击<div>元素将按照下图触发事件:
若在<div>和<body>上都定义了click事件,如下:

<script type="text/javascript">
var div=document.getElementById("myDiv");
div.onclick=function(event){
alert("div");
};
document.body.addEventListener("click",function(event){
alert("event bubble");
},false);
document.body.addEventListener("click",function(event){
alert("event catch");
},true); </script>

点击<div>,将先输出“event catch”,再输出“div”,最后输出“event bubble”。
二、事件处理程序
事件是用户或浏览器自身执行的某种动作,而响应某个事件的函数叫做事件处理程序。HTML事件处理程序、DOM0级事件处理程序和IE事件处理程序均以“on”开头,DOM2级事件处理程序不需要加“on”。
HTML事件处理程序
通过将事件作为HTML元素的属性来实现,包含以下两种方法:
1
|
< input type="button" value="confirm" onclick="alert('confirm')" /> |
或者调用其他地方定义的脚本:
<script type="text/javascript">
function showMessage() {
alert("confirm");
}
</script>
<input type="button" value="confirm" onclick="showMessage()"/>
(注:函数定义必须放在调用之前)
DOM0级事件处理程序
通过Javascript指定事件处理程序的传统方式,所有浏览器均支持。每个元素(包括window,document)都有自己的事件处理程序属性,但是必须在DOM节点加载完之后才会有效。如下所示:
<script type="text/javascript">
var div = document.getElementById("myDiv");
div.onclick = function(event) {
alert("div");
};
</script>
使用DOM0级方法指定的事件处理程序被认为是元素的方法,在元素的作用域中运行。this引用当前元素,如下:
<script type="text/javascript">
var div = document.getElementById("myDiv");
div.onclick = function(event) {
alert(this.id);
};
</script>
输出“myDiv”。
删除通过DOM0级方法指定的事件处理程序:div.onclick=null;
DOM2级事件处理程序
IE9,chrome,Firefox,Opera,Safari均实现了DOM2级事件处理程序,绑定事件方法addEventListener()接收三个参数:事件名称,事件处理函数和一个布尔值。布尔值为true,则表示在捕获阶段调用事件处理程序;如果为false,则表示在冒泡阶段调用事件处理程序。addEventListener允许在同一个元素上添加多个事件处理程序,如下所示:

<script type="text/javascript">
var div = document.getElementById("myDiv");
div.addEventListener("click", function(event) {
alert("event bubble");
}, false);
div.addEventListener("click", function(event) {
alert("event catch");
}, true);
</script>

先输出“event bubble”,后输出“event catch”,说明addEvenListener绑定的处理程序执行顺序和绑定顺序相同。
通过DOM2级事件处理程序指定的方法,this也引用当前元素,如下:
<script type="text/javascript">
var div = document.getElementById("myDiv");
div.addEventListener("click", function(event) {
alert(this.id);
}, false);
</script>
输出“myDiv”。
删除DOM2级事件处理程序,采用removeEventListener(),删除时传入的参数必须和绑定时传入的参数相同,不能传入匿名函数。如下所示:

<script type="text/javascript">
var div = document.getElementById("myDiv");
var handler=function(event){
alert("delete");
};
div.addEventListener("click",handler,false);
div.removeEventListener("click",handler,false);
</script>

IE事件处理程序
IE8和IE8以下的版本不支持addEventListener(),而是采用attachEvent()来实现事件绑定。目前只有IE和Opera支持attachEvent()。IE9支持addEventListener(),同时也兼容IE8的attachEvent()方法,但是IE9和IE8对attachEvent()的实现有点不同。如下所示:

<script type="text/javascript">
var div = document.getElementById("myDiv");
div.attachEvent("onclick", function(event) {
alert("1");
});
div.attachEvent("onclick", function(event) {
alert("2");
});
</script>

IE9和IE10先输出“1”,再输出“2”,而IE8和IE7先输出“2”,再输出“1”。
删除IE事件处理程序,采用detachEvent(),删除时传入的参数必须和绑定时传入的参数相同,不能传入匿名函数。如下所示:

<script type="text/javascript">
var div = document.getElementById("myDiv");
var handler = function(event) {
alert("delete");
};
div.attachEvent("onclick",handler);
div.detachEvent("onclick",handler);
</script>

总结:attachEvent()采用冒泡方式,而addEventListener()可以采用冒泡或事件捕获方式。
先按由上往下的顺序执行事件捕获的执行程序,再执行目标元素的执行程序,最后按由下往上的顺序执行冒泡事件。代码如下所示:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Event Bubbling Example</title>
</head>
<style type="text/css">
#child {
width: 100px;
height: 100px;
background-color: #FF0000;
}
</style>
<body>
<div id="parent">
<div id="child"></div>
</div>
</body>
<script type="text/javascript">
var parent = document.getElementById("parent");
var child = document.getElementById("child");
child.onclick = function(event) {
alert("child");
};
document.body.addEventListener("click", function(event) {
alert("body:event bubble");
}, false);
parent.attachEvent("onclick", function(event) {
alert("parent:event bubble");
});
document.body.addEventListener("click", function(event) {
alert("body:event catch");
}, true);
parent.addEventListener("click", function(event) {
alert("parent:event catch");
}, true);
</script>
</html>

输出顺序:body:event catch—>parent:event catch—>child—>parent:event bubble—>body:event bubble
js事件冒泡和事件捕获详解的更多相关文章
- JS事件冒泡和事件捕获的详解
在学校,听老师讲解事件冒泡和事件捕获机制的时候跟听天书一样,只依稀记得IE使用的是事件冒泡,其他浏览器则是事件捕获.当时的我,把它当成IE浏览器兼容问题,所以没有深究(IE8以下版本的浏览器已基本退出 ...
- JS事件(事件冒泡和事件捕获)
事件流:描述的是在页面中接收事件的顺序 事件冒泡:由最具体的元素接收,然后逐级向上传播至最不具体的元素的节点(文档) 事件捕获:最不具体的节点先接收事件,而最具体的节点应该是最后接收事件 DOM中:用 ...
- JS中的事件绑定,事件捕获,事件冒泡以及事件委托,兼容IE
转载请注明出处:http://www.cnblogs.com/zhangmingze/p/4864367.html ● 事件分为三个阶段: 事件捕获 --> 事件目标 --> ...
- js进阶 12-2 彻底弄懂JS的事件冒泡和事件捕获
js进阶 12-2 彻底弄懂JS的事件冒泡和事件捕获 一.总结 一句话总结:他们是描述事件触发时序问题的术语.事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件.相反的,事件 ...
- JS事件冒泡与事件捕获怎么理解?
在js中存在事件冒泡与事件捕获两种概念,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题. 事件冒泡(dubbed bubbling) 事件冒泡我们从字面意思理解就是当用户行为触发我们页面的定 ...
- js 事件冒泡和事件捕获
事件流:指的是网页中元素接受事件的顺序,它是一个概念,而不是具体的实际的东西 事件冒泡:指的是内层元素的事件,会触发包含着此元素的外层元素的事件,触发的顺序是:由内而外的 例如: <!DOCTY ...
- 彻底弄懂JS的事件冒泡和事件捕获
先上结论:在事件执行流中有两种执行方式.一种是事件冒泡(即事件的执行顺序是从下往上执行的) ; 另一种是捕获(即事件的执行顺序是从上往下执行的); 阻止事件冒泡: return false; ...
- js高级:event,事件冒泡,事件捕获
1.事件 浏览器客户端上客户触发的行为都称为事件 所有的事件都是天生自带的,不需要我们去绑定,只需要我们去触发. 通过 obj.事件名=function(){} 事件名:onmouseover 鼠标悬 ...
- JS高级:事件冒泡和事件捕获;
1.事件:浏览器客户端上客户触发的行为成为时事件:所有的事件都是天生自带的,不需要我们去绑定,只需要我们去触发 当用户触发一个事件时,浏览器的所有详细信息都存在一个叫做event的对象上,我们把它叫做 ...
- 彻底弄懂JS的事件冒泡和事件捕获(不推荐阅读)
由于搬去敌台了,好久没来博客园,今天无意中翻到有“误认子弟”的评论,这里特意做个说明. 本文中关于事件冒泡和事件捕获的描述和例子都是OK的,错就错在后面用jquery去展示了利用事件冒泡的例子有误,其 ...
随机推荐
- noip第20课资料
- 1.SpringMVC入门
创建一个web工程 导入jar 配置web.xml 在web.xml配置前端控制器:DispatcherServlet <?xml version="1.0" encodin ...
- Android-Java-抽象类
定义抽象类,就一定会定义抽象方法,抽象方法没有方法体{},就证明抽象方法 是不运行的,抽象方法 是给子类继承覆盖运行的, 子类继承->抽象类 就必须覆盖抽象方法,否则编译都失败: 水果案例: 定 ...
- [转]kaldi特征和模型空间转换
转:http://blog.csdn.net/shmilyforyq/article/details/76807431 博主话:这篇博客是对kaldi官网中Feature and model-spac ...
- 安卓Task和Back Stack
概述 一个Activity允许用户完成一些操作,甚至,Android中设计Activity为组件的形式,这样,多个Activity--甚至是其它App的Activity可以一起完成一项任务. Task ...
- Archive required for library “xxx” cannot be read or is not a valid zip file报错解决
在项目中导入别人的maven项目时报错:Archive required for library “xxx” cannot be read or is not a valid zip file 网上查 ...
- 百度Ueditor富文本编辑器 .net版本 任意文件上传执行漏掉修复
问题描述: 借由上传网络图片功能中可传递可执行文件.后台代码中只做了文件类型的检测未能正确的拦截掉非法文件. 只需将上传地址改为 XXXXXX.jpg?.aspx最终服务上最终存储的文件会变为XXXX ...
- 200行代码实现简版react🔥
200行代码实现简版react
- JodaTimeUtil日期处理工具类(简单、实用)
一.maven依赖 <!--joda time--> <dependency> <groupId>joda-time</groupId> <art ...
- oracle笔记--查询10条之后记录的数据
本文版权归 远方的风lyh和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 由于之前一直在用mysql 对于oracle 的一些语法不太了解,自己有一次去面试让写一个oracle ...