javascript事件冒泡和事件捕获详解


Posted in Javascript onMay 26, 2015

事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。

<div id="outer">
  <p id="inner">Click me!</p>
</div>

上面的代码当中一个div元素当中有一个p子元素,如果两个元素都有一个click的处理函数,那么我们怎么才能知道哪一个函数会首先被触发呢?

为了解决这个问题微软和网景提出了两种几乎完全相反的概念。

事件冒泡

微软提出了名为事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。

因此上面的例子在事件冒泡的概念下发生click事件的顺序应该是p -> div -> body -> html -> document

事件捕获

网景提出另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。

上面的例子在事件捕获的概念下发生click事件的顺序应该是document -> html -> body -> div -> p

addEventListener的第三个参数

“DOM2级事件”中规定的事件流同时支持了事件捕获阶段和事件冒泡阶段,而作为开发者,我们可以选择事件处理函数在哪一个阶段被调用。

addEventListener方法用来为一个特定的元素绑定一个事件处理函数,是JavaScript中的常用方法。addEventListener有三个参数:

element.addEventListener(event, function, useCapture)
第一个参数是需要绑定的事件,第二个参数是触发事件后要执行的函数。而第三个参数默认值是false,表示在事件冒泡的阶段调用事件处理函数,如果参数为true,则表示在事件捕获阶段调用处理函数。请看例子。

事件代理

在实际的开发当中,利用事件流的特性,我们可以使用一种叫做事件代理的方法。

<ul id="color-list">
  <li>red</li>
  <li>yellow</li>
  <li>blue</li>
  <li>green</li>
  <li>black</li>
  <li>white</li>
</ul>

如果点击页面中的li元素,然后输出li当中的颜色,我们通常会这样写:

(function(){

    var color_list = document.getElementById('color-list');

    var colors = color_list.getElementsByTagName('li');

    for(var i=0;i<colors.length;i++){                          

 colors[i].addEventListener('click',showColor,false);

    };

    function showColor(e){

        var x = e.target;

        alert("The color is " + x.innerHTML);

    };

})();

利用事件流的特性,我们只绑定一个事件处理函数也可以完成:

(function(){

    var color_list = document.getElementById('color-list');

    color_list.addEventListener('click',showColor,false);

    function showColor(e){

        var x = e.target;

        if(x.nodeName.toLowerCase() === 'li'){

            alert('The color is ' + x.innerHTML);

        }

    }

})();

使用事件代理的好处不仅在于将多个事件处理函数减为一个,而且对于不同的元素可以有不同的处理方法。假如上述列表元素当中添加了其他的元素(如:a、span等),我们不必再一次循环给每一个元素绑定事件,直接修改事件代理的事件处理函数即可。

冒泡还是捕获?

对于事件代理来说,在事件捕获或者事件冒泡阶段处理并没有明显的优劣之分,但是由于事件冒泡的事件流模型被所有主流的浏览器兼容,从兼容性角度来说还是建议大家使用事件冒泡模型。

IE浏览器兼容

IE浏览器对addEventListener兼容性并不算太好,只有IE9以上可以使用。

javascript事件冒泡和事件捕获详解

要兼容旧版本的IE浏览器,可以使用IE的attachEvent函数

object.setCapture();
object.attachEvent(event, function)
两个参数与addEventListener相似,分别是事件和处理函数,默认是事件冒泡阶段调用处理函数,要注意的是,写事件名时候要加上"on"前缀("onload"、"onclick"等)。

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
Extjs EditorGridPanel中ComboBox列的显示问题
Jul 04 Javascript
js window.print实现打印特定控件或内容
Sep 16 Javascript
JavaScript跨平台的开源框架NativeScript
Mar 24 Javascript
jQuery仿gmail实现fixed布局的方法
May 27 Javascript
基于jQuery实现仿51job城市选择功能实例代码
Mar 02 Javascript
JavaScript实现数据类型的相互转换
Mar 06 Javascript
js输出数据精确到小数点后n位代码
Jul 02 Javascript
微信小程序 swiper组件详解及实例代码
Oct 25 Javascript
AngularJS入门示例之Hello World详解
Jan 04 Javascript
微信小程序 MD5加密登录密码详解及实例代码
Jan 12 Javascript
Javascript中的getter和setter初识
Aug 17 Javascript
如何通过Proxy实现JSBridge模块化封装
Oct 22 Javascript
解析javascript中鼠标滚轮事件
May 26 #Javascript
JS中字符串trim()使用示例
May 26 #Javascript
JSON字符串和对象之间的转换详解
May 26 #Javascript
Js和JQuery获取鼠标指针坐标的实现代码分享
May 25 #Javascript
Javascript实现飞动广告效果的方法
May 25 #Javascript
javascript自定义右键弹出菜单实现方法
May 25 #Javascript
JS+DIV实现鼠标划过切换层效果的方法
May 25 #Javascript
You might like
一个odbc连mssql分页的类
2006/10/09 PHP
遍历指定目录下的所有目录和文件的php代码
2011/11/27 PHP
关于初学PHP时的知识积累总结
2013/06/07 PHP
php5.3 注意事项说明
2013/07/01 PHP
PHP按行读取、处理较大CSV文件的代码实例
2014/04/09 PHP
PHP弱类型的安全问题详细总结
2016/09/25 PHP
深入了解PHP中的Array数组和foreach
2016/11/06 PHP
Laravel5.5新特性之友好报错以及展示详解
2017/08/13 PHP
php微信公众号开发之秒杀
2018/10/20 PHP
jQuery 隔行换色 支持键盘上下键,按Enter选定值
2009/08/02 Javascript
Javascript计算两个marker之间的距离(Google Map V3)
2013/04/26 Javascript
如何动态的导入js文件具体该怎么实现
2014/01/14 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
使用时间戳解决ie缓存的问题
2014/08/20 Javascript
javascipt:filter过滤介绍及使用
2014/09/10 Javascript
Linux下使用jq友好的打印JSON技巧分享
2014/11/18 Javascript
Javascript实现字数统计
2015/07/03 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
纯JavaScript 实现flappy bird小游戏实例代码
2016/09/27 Javascript
js移动焦点到最后位置的简单方法
2016/11/25 Javascript
vue实现全选、反选功能
2020/11/17 Javascript
详解vue-cli项目开发/生产环境代理实现跨域请求
2019/07/23 Javascript
django简单的前后端分离的数据传输实例 axios
2020/05/18 Javascript
python编写爬虫小程序
2015/05/14 Python
python登录WeChat 实现自动回复实例详解
2019/05/28 Python
Python+OpenCV图像处理——图像二值化的实现
2020/10/24 Python
利用CSS3的特性改变文本选中时的颜色
2013/09/11 HTML / CSS
印尼最大的在线购物网站:MatahariMall.com
2016/08/26 全球购物
乌克兰在线商店的价格比较:Price.ua
2019/07/26 全球购物
怎样从/向数据文件读/写结构
2014/11/23 面试题
公司采购主管岗位职责
2014/06/17 职场文书
项目投资合作意向书
2014/07/29 职场文书
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
幼师小班个人总结
2015/02/12 职场文书
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python
MySQL表锁、行锁、排它锁及共享锁的使用详解
2022/04/02 MySQL