JavaScript的事件监听、捕获和冒泡
在前端开发中,我们经常需要对某些事件进行监听。这样只要在指定的元素上触发了该事件,就会执行一个回调函数来进行相关的操作。
而JavaScript中事件监听的方法总共有三种,分别如下:
- element.addEventListener(type, listener[, useCapture]); //IE6~8不支持
- element.attachEvent('on' + type, listener) //支持IE6~10,IE11不支持
- element['on' + type] = function(){} //支持所有浏览器
demo:
function cb(){
console.log(1);
}
element.addEventListener('click', cb, false);
element.attachEvent('onclick', cb);
element.onclick = cb;
参数解释:
type:事件类型
listener:事件出发后的回调函数
useCapture:是否使用捕获,如果值为true,useCapture表示用户希望发起捕获。在发起捕获之后,只要DOM子树下发生了该事件类型,都会先被该事件监听器捕获,然后再被派发到DOM子树中的事件监听器中。并且向上冒泡的事件不会触发那些发起捕获的事件监听器。useCapture默认值是true。
addEventListener是W3C工作组在DOM Level 2开始引入的一个注册事件监听器的方法,而在此之前,传统的事件监听方法是通过element['on' + type]的方式来注册的。它们的主要区别是element['on' + type]的方式无法使用事件捕获,并且element['on' + type]不支持对同一个元素的同一个事件注册多个事件监听器。如下面的例子所示,元素被点击之后只会输出1,而不会输出0和1。
element.onclick = function(){ console.log(0); }
element.onclick = function(){ console.log(1); }
然而addEventListener方法在IE6~8的浏览器中不被支持。那么在低版本的IE中怎么来为同一个事件注册多个事件监听器呢?原来IE从IE5.0系列开始就引入了attachEvent()方法来支持这一特性。但遗憾的是该方法也不支持事件捕获。并且从IE11开始,这个方法已经被弃用。
谈谈事件的捕获与冒泡

W3C规范中定义了3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。事件对象按照上图的传播路径依次完成这些阶段。如果某个阶段不支持或事件对象的传播被终止,那么该阶段就会被跳过。举个例子,如果Event.bubbles属性被设置为false,那么冒泡阶段就会被跳过。如果Event.stopPropagation()在事件派发前被调用,那么所有的阶段都会被跳过。
- 捕获 阶段:在事件对象到达事件目标之前,事件对象必须从window经过目标的祖先节点传播到事件目标。 这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件。
- 目标 阶段:事件对象到达其事件目标。 这个阶段被我们称为目标阶段。一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。
- 冒泡 阶段:事件对象以一个与捕获阶段相反的方向从事件目标传播经过其祖先节点传播到window。这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。
在一个事件完成了所有阶段的传播路径后,它的Event.currentTarget会被设置为null并且Event.eventPhase会被设为0。Event的所有其他属性都不会改变(包括指向事件目标的Event.target属性)
知识链接:
1、Event.currentTarget属性:currentTarget 事件属性返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口。在捕获和起泡阶段,该属性是非常有用的,因为在这两个节点,它不同于 target 属性。
/*HTML代码*/
<p id="p1" onmousedown="getEventTrigger(event)">点击我试试</p> /*JavaScript代码*/
function getEventTrigger(event){
var x = event.currentTarget;
alert("The id of the triggered element: " + x.id);
}
2、Event.eventPhase属性:eventPhase 属性返回事件传播的当前阶段。它的值是下面的三个常量之一,它们分别表示捕获阶段、正常事件派发和起泡阶段。

window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(event){
alert(event.eventPhase); //2
}
document.body.addEventListener("click",function(event){
alert(event.eventPhase); //1
},true);
document.body.onclick = function(event){
alert(event.eventPhase); //3
}
}
JavaScript的事件监听、捕获和冒泡的更多相关文章
- javascript的事件监听与捕获和冒泡
在前端开发中,我们经常需要对某些事件进行监听.这样只要在指定的元素上触发了该事件,就会执行一个回调来进行相关的操作. 而js中事件监听方法总共有三种,分别如下所示: element.addEventL ...
- javascript之事件监听
addEventListener是一个监听事件并处理相应的函数,用于向指定元素添加事件句柄,可使用removeEventListener()方法来移除addEventListener()方法添加的事件 ...
- JavaScript addEventListener()事件监听方法
addEventListener()方法将事件处理程序附加到指定的元素. addEventListener()方法将事件处理程序附加到元素,而不覆盖现有的事件处理程序. 您可以向一个元素添加许多事件处 ...
- DOM 事件监听 事件冒泡 事件捕获
addEventListener() 方法 实例: // 当用户点击按钮时触发监听事件: document.getElementById("myBtn").addEventList ...
- [JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播
-->事件冒泡和捕获-->事件监听-->阻止事件传播 一.事件冒泡和捕获 1.概念:当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,点击子元素时,父元素的oncl ...
- javascript事件监听与事件委托
事件监听与事件委托 在js中,常用到element.addEventListener()来进行事件的监听.但是当页面中存在大量需要绑定事件的元素时,这种方式可能会带来性能影响.此时,我们可以用事件 ...
- js事件监听机制(事件捕获)总结
在前端开发过程中我们经常会遇到给页面元素添加事件的问题,添加事件的js方法也很多,有直接加到页面结构上的,有使用一些js事件监听的方法,由于各个浏览器对事件冒泡事件监听的机制不同,le浏览器只有事件冒 ...
- JavaScript事件监听以及addEventListener参数分析
事件监听 在Javascript中事件的监听是用来对某些操作做出反应的方法.例如监听一个按钮的pressdown, 或者获取鼠标左键按下时候鼠标的位置.这些都需要使用监听来完成.监听的函数很简单:ad ...
- js事件监听机制(事件捕获)
在前端开发过程中我们经常会遇到给页面元素添加事件的问题,添加事件的js方法也很多,有直接加到页面结构上的,有使用一些js事件监听的方法,由于各个浏览器对事件冒泡事件监听的机制不同,le浏览器只有事件冒 ...
随机推荐
- SPOJ - OTOCI LCT
OTOCI Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/problem/viewProblem. ...
- RotatingDoughnut
RotatingDoughnut.zip
- android实现弧形进度表盘效果
附件:Cirbar.rar
- android EditText输入变化事件详解
editText.addTextChangedListener(new TextWatcher(){ public void afterTextChanged(Editable s) { // ...
- android学习日记19--四大组件之BroadcastReciver(广播接收者)
二.BroadcastReciver(广播接收者) 1.简述 BroadcastReciver位于android.content包下,主要用于对广播消息(Intent)的过滤并响应的控件.可以理解为全 ...
- Unity手游之路<七>角色控制器
我们要控制角色的移动,能够所有细节都由自己来实现.控制角色模型的移动,同一时候移动摄影机,改变视角.当然Unity也提供了一些组件,能够让我们做更少的工作,实现我们所期望的功能.今天我们就一起系统来学 ...
- [018]C++ explicit构造函数
explicit [英][ɪkˈsplɪsɪt][美][ɪkˈsplɪsɪt] adj.明确的,清楚的; 直言的; 详述的; 不隐瞒的; 看到上面的英文解释,我们应该就知道explicit构造函数是什 ...
- 十、Socket之UDP编程
UDP基础知识 UDP(User Datagram Protocol,用户数据报协议)是一个简单的.面向数据报的无连接协议,提供了快速但不一定可靠的传输服务. UDP与TCP相比主要有以下区别. 1. ...
- Android_AsyncTask_json
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...
- AngularJS中在前后端分离模式下实现权限控制 - 基于RBAC
一:RBAC 百科解释: 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注.在RBAC中,权限与角色相关联,用 ...