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 request函数 用来获取url参数
May 17 Javascript
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
Oct 01 Javascript
用dtree实现树形菜单 dtree使用说明
Oct 17 Javascript
JavaScript去除空格的三种方法(正则/传参函数/trim)
Feb 06 Javascript
JS将数字转换成三位逗号分隔的样式(示例代码)
Feb 19 Javascript
javascript中的Function.prototye.bind
Jun 25 Javascript
Javascript实现代码折叠功能
Aug 25 Javascript
jQuery实现简易的输入框字数计数功能示例
Jan 16 Javascript
javaScript基础详解
Jan 19 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
Sep 04 jQuery
Vue 重置组件到初始状态的方法示例
Oct 10 Javascript
vue-socket.io跨域问题有效解决方法
Feb 11 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实现UTF-8文件BOM自动检测与移除实例
2014/11/05 PHP
PHP版微信公众平台红包API
2015/04/02 PHP
为数据添加append,remove功能
2006/10/03 Javascript
innertext , insertadjacentelement , insertadjacenthtml , insertadjacenttext 等区别
2007/06/29 Javascript
基于JQUERY的两个ListBox子项互相调整的实现代码
2011/05/07 Javascript
js抽奖实现随机抽奖代码效果
2013/12/02 Javascript
js图片轮播手动切换效果
2015/11/10 Javascript
理解Javascript图片预加载
2016/02/23 Javascript
精通JavaScript的this关键字
2020/05/28 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
jquery动态遍历Json对象的属性和值的方法
2016/07/27 Javascript
原生js代码实现图片放大境效果
2016/10/30 Javascript
js 动态生成html 触发事件传参字符转义的实例
2017/02/14 Javascript
jQuery弹出窗口简单实现代码
2017/03/09 Javascript
JavaScript订单操作小程序完整版
2017/06/23 Javascript
jQuery实现的滑块滑动导航效果示例
2018/06/04 jQuery
node.js中stream流中可读流和可写流的实现与使用方法实例分析
2020/02/13 Javascript
深入分析JavaScript 事件循环(Event Loop)
2020/06/19 Javascript
vue 动态设置img的src地址无效,npm run build 后找不到文件的解决
2020/07/26 Javascript
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
Python干货:分享Python绘制六种可视化图表
2018/08/27 Python
解决pyecharts运行后产生的html文件用浏览器打开空白
2020/03/11 Python
Android Q之气泡弹窗的实现示例
2020/06/23 Python
Python3.9最新版下载与安装图文教程详解(Windows系统为例)
2020/11/28 Python
医药专业应届毕业生求职信范文
2014/01/01 职场文书
初中科学教学反思
2014/01/21 职场文书
小学生母亲节演讲稿
2014/05/07 职场文书
公司运动会策划方案
2014/05/25 职场文书
十佳青年事迹材料
2014/08/21 职场文书
2014离婚协议书范文(3篇)
2014/11/29 职场文书
医院保洁员管理制度
2015/08/05 职场文书
在Java中Collection的一些常用方法总结
2021/06/13 Java/Android
基于Python实现一个春节倒计时脚本
2022/01/22 Python
业余无线电通联Q语
2022/02/18 无线电
Python+OpenCV实现在图像上绘制矩形
2022/03/21 Python
如何优化vue打包文件过大
2022/04/13 Vue.js