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 相关文章推荐
关于IE BUG与字符串截取substr的解决办法
Apr 10 Javascript
javascript中encodeURI和decodeURI方法使用介绍
May 06 Javascript
form表单action提交的js部分与html部分
Jan 07 Javascript
Jquery组件easyUi实现手风琴(折叠面板)示例
Aug 23 Javascript
easyui combobox开启搜索自动完成功能的实例代码
Nov 08 Javascript
jQuery表格的维护和删除操作
Feb 03 Javascript
JS中跳出循环的示例代码
Sep 14 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
Sep 22 Javascript
jQuery中元素选择器(element)简单用法示例
May 14 jQuery
微信小程序实现滑动翻页效果(完整代码)
Dec 06 Javascript
JavaScript 俄罗斯方块游戏实现方法与代码解释
Apr 08 Javascript
node中使用shell脚本的方法步骤
Mar 23 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
PHP Filter过滤器全面解析
2016/08/09 PHP
基于Jquery的简单&amp;简陋Tabs插件代码
2010/02/09 Javascript
DWR实现模拟Google搜索效果实现原理及代码
2013/01/30 Javascript
js和php如何获取当前url的内容
2013/09/22 Javascript
JS实现定时自动关闭DIV层提示框的方法
2015/05/11 Javascript
由ReactJS的Hello world说开来
2015/07/02 Javascript
jQuery 如何给Carousel插件添加新的功能
2016/04/18 Javascript
利用Angularjs和bootstrap实现购物车功能
2016/08/31 Javascript
使用jQuery.Qrcode插件在客户端动态生成二维码并添加自定义Logo
2016/09/01 Javascript
基于 Bootstrap Datetimepicker 联动
2017/08/03 Javascript
JS实现textarea通过换行或者回车把多行数字分割成数组并且去掉数组中空的值
2018/10/29 Javascript
使用puppeteer爬取网站并抓出404无效链接
2018/12/20 Javascript
详解vue 在移动端体验上的优化解决方案
2019/05/20 Javascript
VUE安装使用教程详解
2019/06/03 Javascript
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
2019/06/18 jQuery
vue实现axios图片上传功能
2019/08/20 Javascript
element的el-table中记录滚动条位置的示例代码
2019/11/06 Javascript
微信小程序激励式视频广告组件使用详解
2019/12/06 Javascript
vue实现购物车加减
2020/05/30 Javascript
JavaScript图像放大镜效果实现方法详解
2020/06/28 Javascript
python在windows和linux下获得本机本地ip地址方法小结
2015/03/20 Python
用Python操作字符串之rindex()方法的使用
2015/05/19 Python
python自动化报告的输出用例详解
2018/05/30 Python
对Django中的权限和分组管理实例讲解
2019/08/16 Python
python3 mmh3安装及使用方法
2019/10/09 Python
Python坐标轴操作及设置代码实例
2020/06/04 Python
Python使用Selenium实现淘宝抢单的流程分析
2020/06/23 Python
工程承诺书怎么写
2014/05/24 职场文书
红色旅游心得体会
2014/09/03 职场文书
学院党的群众路线教育实践活动整改方案
2014/10/04 职场文书
工人先锋号申报材料
2014/12/29 职场文书
初中语文教学研修日志
2015/11/13 职场文书
css3实现的加载动画效果
2021/04/07 HTML / CSS
Java新手教程之ArrayList的基本使用
2021/06/20 Java/Android
使用redis实现延迟通知功能(Redis过期键通知)
2021/09/04 Redis
用JS创建一个录屏功能
2021/11/11 Javascript