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 相关文章推荐
比较详细的关于javascript中void(0)的具体含义解释
Aug 02 Javascript
js中的for如何实现foreach中的遍历
May 31 Javascript
js实现iframe自动自适应高度的方法
Feb 17 Javascript
js仿微博实现统计字符和本地存储功能
Dec 22 Javascript
认识Knockout及如何使用Knockout绑定上下文
Dec 25 Javascript
JavaScript的ExtJS框架中数面板TreePanel的使用实例解析
May 21 Javascript
jQuery限制图片大小的方法
May 25 Javascript
详解jQuery停止动画——stop()方法的使用
Dec 14 Javascript
微信小程序 MD5的方法详解及实例代码
Mar 10 Javascript
详解Angular之constructor和ngOnInit差异及适用场景
Jun 22 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
Jul 19 jQuery
使用layui定义一个模块并使用的例子
Sep 14 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
咖啡因含量是由谁决定的?低因咖啡怎么来?低因咖啡适合什么人喝
2021/03/06 新手入门
php将session放入memcached的设置方法
2014/02/14 PHP
全面解读PHP的人气开发框架Laravel
2015/10/15 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
给moz-firefox下添加IE方法和属性
2007/04/10 Javascript
用JavaScript页面不刷新时全选择,全删除(GridView)
2009/04/14 Javascript
jQuery 类twitter的文本字数限制带提示效果插件
2010/04/16 Javascript
高性能web开发 如何加载JS,JS应该放在什么位置?
2010/05/14 Javascript
JavaScript的继承的封装介绍
2013/10/15 Javascript
jQuery获得内容和属性示例代码
2014/01/16 Javascript
JS实现局部选择打印和局部不选择打印
2014/04/03 Javascript
jquery获取一个元素下面相同子元素的个数代码
2014/07/31 Javascript
js事件监听器用法实例详解
2015/06/01 Javascript
js实现上传文件添加和删除文件选择框
2016/10/24 Javascript
解决OneThink中无法异步提交kindeditor文本框中修改后的内容方法
2017/05/05 Javascript
bootstrap插件treeview实现全选父节点下所有子节点和反选功能
2017/07/21 Javascript
JS计算输出100元钱买100只鸡问题的解决方法
2018/01/04 Javascript
Node.js成为Web应用开发最佳选择的原因
2018/02/05 Javascript
VUE基于NUXT的SSR 服务端渲染
2018/11/30 Javascript
[48:05]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 VGJ.T vs VP
2018/03/31 DOTA
Python魔术方法详解
2015/02/14 Python
Python使用正则表达式实现文本替换的方法
2017/04/18 Python
详解python中asyncio模块
2018/03/03 Python
Django使用Mysql数据库已经存在的数据表方法
2018/05/27 Python
python函数的万能参数传参详解
2019/07/26 Python
关于keras中keras.layers.merge的用法说明
2020/05/23 Python
Python自动创建Excel并获取内容
2020/09/16 Python
python如何实现DES加密
2020/09/21 Python
css3实现圆锥渐变conic-gradient效果
2020/02/12 HTML / CSS
纯HTML5+CSS3制作生日蛋糕代码
2016/11/16 HTML / CSS
蔻驰美国官网:COACH美国
2016/08/18 全球购物
中国综合性网上购物商城:当当(网上卖书起家)
2016/11/16 全球购物
英国著名的美容护肤和护发产品购物网站:Lookfantastic
2020/11/23 全球购物
高中生第一学年自我鉴定2015
2014/09/28 职场文书
网络营销计划书
2015/01/17 职场文书
JavaScript+HTML实现学生信息管理系统
2021/04/20 Javascript