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 有趣而诡异的数组
Apr 06 Javascript
P3P Header解决Cookie跨域的问题
Mar 12 Javascript
js的onload事件及初始化按钮事件示例代码
Sep 25 Javascript
js快速排序的实现代码
Dec 08 Javascript
JavaScript实现16进制颜色值转RGB的方法
Feb 09 Javascript
js验证框架实现代码分享
May 18 Javascript
js事件冒泡与事件捕获详解
Feb 20 Javascript
D3.js实现简洁实用的动态仪表盘的示例
Apr 04 Javascript
vue.js 图片上传并预览及图片更换功能的实现代码
Aug 27 Javascript
React优化子组件render的使用
May 12 Javascript
浅谈Vue3.0之前你必须知道的TypeScript实战技巧
Sep 11 Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
Feb 06 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
在Windows中安装Apache2和PHP4的权威指南
2006/10/09 PHP
粗略计算在线时间,bug:ip相同
2006/12/09 PHP
php输出xml格式字符串(用的这个)
2012/07/12 PHP
php根据某字段对多维数组进行排序的方法
2015/03/07 PHP
PHP内核探索之变量
2015/12/22 PHP
Mac系统下安装PHP Xdebug
2018/03/30 PHP
js 异步处理进度条
2010/04/01 Javascript
jQuery.query.js 取参数的两点问题分析
2012/08/06 Javascript
中国地区三级联动下拉菜单效果分析
2012/11/15 Javascript
解析使用JS 清空File控件的路径值
2013/07/08 Javascript
关于js中for in的缺陷浅析
2013/12/02 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
2013/12/04 Javascript
JavaScript极简入门教程(一):基础篇
2014/10/25 Javascript
实现前后端数据交互方法汇总
2015/04/07 Javascript
JS Testing Properties 判断属性是否在对象里的方法
2017/10/01 Javascript
vue.js实现简单轮播图效果
2017/10/10 Javascript
Postman模拟发送带token的请求方法
2018/03/31 Javascript
vue-cli3全面配置详解
2018/11/14 Javascript
总结4个方面优化Vue项目
2019/02/11 Javascript
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
Vue动态修改网页标题的方法及遇到问题
2019/06/09 Javascript
javascript中的with语句学习笔记及用法
2020/02/17 Javascript
实现一个Vue自定义指令懒加载的方法示例
2020/06/04 Javascript
[06:33]3.19 DOTA2发布会 海涛、冷冷、2009见证希望
2014/03/21 DOTA
[02:29]完美世界高校联赛上海赛区回顾
2015/12/15 DOTA
[50:24]VGJ.S vs Pain 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
[59:15]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第一场 11.20
2020/11/20 DOTA
Python里隐藏的“禅”
2014/06/16 Python
Python 利用pydub库操作音频文件的方法
2019/01/09 Python
定义一结构体变量,用其表示点坐标,并输入两点坐标,求两点之间的距离
2015/08/17 面试题
国家励志奖学金个人先进事迹材料
2014/05/04 职场文书
经营目标管理责任书
2014/07/25 职场文书
小石潭记导游词
2015/02/03 职场文书
南京南京观后感
2015/06/02 职场文书
2016年习总书记讲话学习心得体会
2016/01/20 职场文书
小型企业的绩效考核制度模板
2019/11/21 职场文书