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 相关文章推荐
Js基础学习资料
Nov 23 Javascript
关于Mozilla浏览器不支持innerText的解决办法
Jan 01 Javascript
使用PHP+JQuery+Ajax分页的实现
Apr 23 Javascript
jquery插件uploadify多图上传功能实现代码
Aug 12 Javascript
JavaScript的变量声明提升问题浅析(Hoisting)
Nov 30 Javascript
TypeScript学习之强制类型的转换
Dec 27 Javascript
详解使用Vue Router导航钩子与Vuex来实现后退状态保存
Sep 11 Javascript
vue首次赋值不触发watch的解决方法
Sep 11 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
Dec 05 Javascript
JS实现动态添加外部js、css到head标签的方法
Jun 05 Javascript
Vue使用Proxy代理后仍无法生效的解决
Nov 13 Javascript
vue使用lodop打印控件实现浏览器兼容打印的方法
Feb 07 Vue.js
解析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/01 无线电
php获取文章上一页与下一页的方法
2014/12/01 PHP
php微信扫码支付 php公众号支付
2019/03/24 PHP
JQuery 中几个类选择器的简单使用介绍
2013/03/14 Javascript
js输入框邮箱自动提示功能代码实现
2013/12/10 Javascript
JavaScript中的document.referrer在各种浏览器测试结果
2014/07/18 Javascript
深入理解setTimeout函数和setInterval函数
2016/05/20 Javascript
基于Turn.js 实现翻书效果实例解析
2016/06/20 Javascript
AngularJS入门教程之 XMLHttpRequest实例讲解
2016/07/27 Javascript
如何制作幻灯片(代码分享)
2017/01/06 Javascript
Vue实现调节窗口大小时触发事件动态调节更新组件尺寸的方法
2018/09/15 Javascript
[42:34]VP vs VG 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python操作xml文件详细介绍
2014/06/09 Python
Python通过websocket与js客户端通信示例分析
2014/06/25 Python
Python中的is和id用法分析
2015/01/26 Python
Python实现识别手写数字大纲
2018/01/29 Python
Python实现SQL注入检测插件实例代码
2019/02/02 Python
PyQt编程之如何在屏幕中央显示窗体的实例
2019/06/18 Python
python实现简单成绩录入系统
2019/09/19 Python
Python Des加密解密如何实现软件注册码机器码
2020/01/08 Python
Django模型验证器介绍与源码分析
2020/09/08 Python
Perry Ellis官网:美国男士品味服装
2016/12/09 全球购物
欧洲领先的电子和电信零售商和服务提供商:Currys PC World Business
2017/12/05 全球购物
德国BA保镖药房中文网:Bodyguard Apotheke
2021/03/09 全球购物
出国考察邀请函
2014/01/21 职场文书
数控技术学生的自我评价
2014/02/15 职场文书
结婚保证书(三从四德)
2015/02/26 职场文书
2015年库房工作总结
2015/04/30 职场文书
单方投资意向书
2015/05/11 职场文书
爱的教育观后感
2015/06/17 职场文书
《夹竹桃》教学反思
2016/02/23 职场文书
创业计划书之韩国烧烤店
2019/09/19 职场文书
《卧薪尝胆》读后感3篇
2019/12/26 职场文书
python munch库的使用解析
2021/05/25 Python
vue判断按钮是否可以点击
2022/04/09 Vue.js
mybatis 获取更新记录的id
2022/05/20 Java/Android