JavaScript事件冒泡和事件委托

付建宇 - 2 条评论

接触JavaScript不久,学的东西也不是特别多。小雨就是习惯把平时学到的东西拿出来分享。一方面加强自己的印象,一方面可以让自己的经验为他人答疑解惑。我们知道JavaScript可以监控页面上元素的各种事件,常用的事件有很多,例如点击,鼠标移入、移出,元素改变等等。这次主要说一下事件冒泡及其一个比较酷的应用,事件委托。不做特殊说明,以下都在jQuery框架内执行。

事件冒泡

什么是“事件冒泡”呢?假设这里有一杯水,水被用某种神奇的方式分成不同颜色的几层。这时,从最底层冒出了一个气泡,气泡会一层一层地上升,直到最顶层。而你不管在水的哪一层观察都可以看到并捕捉到这个气泡。好了,把“水”改成“DOM”,把“气泡”改成“事件”。这就是“事件冒泡”。

为了可以直观地观察到这一现象,我写了一个小程序。这个页面中一共有4个嵌套的正方形。最大的那个在最顶层,最小的那个在最底层。我为每一层都单独绑定了一个点击事件,当这一层被点击时,会为这层涂色。试试看,点击最小的正方形会发生什么?点击其他的又会发生什么呢? (点击这里查看demo)

CSS

.white{background-color:#fff;}
#d1{width:400px;height:400px;border:1px solid #000;margin:50px 50px;}
#d2{width:300px;height:300px;border:1px solid #000;margin:50px 50px;}
#d3{width:200px;height:200px;border:1px solid #000;margin:50px 50px;}
#d4{width:100px;height:100px;border:1px solid #000;margin:50px 50px;}

HTML

<div id="d1" class="white">
<div id="d2" class="white">
<div id="d3" class="white">
<div id="d4" class="white"></div>
</div>
</div>
</div>
<button id="reset1">重置</button>

Javascript

jQuery('#d4').click(function(){jQuery(this).css('background-color', 'yellow')});
jQuery('#d3').click(function(){jQuery(this).css('background-color', 'green')});
jQuery('#d2').click(function(){jQuery(this).css('background-color', 'blue')});
jQuery('#d1').click(function(){jQuery(this).css('background-color', 'red')});
jQuery('#reset1').click(function(){jQuery('.white').css('background-color', '#fff')});

没错,点击最小的那个,外面所有的都会被上色。你会发现,点击里层的正方形,外层所有的正方形都会被上色。因为它们也都捕捉到了点击事件。看,他们抓到“气泡”了!

事件委托

上一节的例子我们做一点小小的修改。气泡带上了某种信息,会告诉其经过的每一层自己是在哪一层产生的。JavaScript的事件确实会带着这个属性。当程序捕获一个事件的时候,它会知道这个事件来自于页面上哪个元素。修改上面的程序,使用事件委托来处理点击事件。当最顶层捕获点击事件时,查看事件来源于哪一层,然后只将那一层涂色。再次点击每一层,查看实际效果。只有当前点击的正方形变色了,其他的都毫无反应。(点击这里查看demo)

jQuery('#d1').click(function(e){
var t = jQuery(e.target);
var id = t.attr('id');
if (id==='d4'){
t.css('background-color', 'yellow');
} else if (id==='d3') {
t.css('background-color', 'green');
} else if (id==='d2') {
t.css('background-color', 'blue');
} else {
t.css('background-color', 'red');
}
});

当然,如果你有这样嵌套的页面元素,使用了事件委托,委托到了最顶层,这时需要注意:如果其中某个元素,你不希望它的事件冒泡,那么可以使用某种方式阻止事件的冒泡。在jQuery框架中,可以使用stopPropagation()方法来实现而不必关心浏览器兼容性。

$('#bind').click(function(){
if ($(this).is(':checked')) {
$('#d4').bind('click', function(e){
e.stopPropagation();
alert('冒泡被阻止,这块将不会改变颜色');
});
} else {
$('#d4').unbind('click');
}
});

重置后选中“阻止最小的方块的事件冒泡”,再点击最小的方块,看是否变色。显然是不会变色,阻止了冒泡,父层将无法接收到点击事件。

注意事项

事件委托是事件冒泡的一个应用,可以减少绑定元素的个数,也不必担心子节点被替换后可能需要进行重新的事件绑定。因为事件的捕获和后续代码的执行已经完全委托给了其父节点。如果页面中含有大量元素需要绑定事件,这样做会减少事件绑定数量,为浏览器减负,无疑会提高页面性能。

但也有些需要注意的。如果用于捕获事件的节点会在某些情况下return false,而你的一个点击事件未委托给父节点,那么,你可能需要阻止这个节点的事件冒泡来达到正确的目的。例如:我在一个div里面有一些按钮和其他元素。利用事件委托来处理这些按钮的点击,如果不是按钮则return false。这时,错误就出现了。如果其他元素中含有链接,那么链接的点击事件也会被委托给div。然而点击链接,会没有任何反应。解决办法一是在委托的代码中对链接进行处理,二是阻止链接的事件冒泡。

转载:http://www.pureweber.com/article/event-delegation/

JavaScript事件冒泡和事件委托的更多相关文章

  1. javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。

    首先,弄明白js 当中,什么是事件,事件模型在js中是如何设计的.什么是事件冒泡? 什么是“事件冒泡”呢?假设这里有一杯水,水被用某种神奇的方式分成不同颜色的几层.这时,从最底层冒出了一个气泡,气泡会 ...

  2. 【JavaScript】事件捕获、事件冒泡与事件委托

    2018年12月18日 最近在学习js时,遇到了三个名词:事件捕获.事件冒泡.事件委托. 一.事件捕获和事件冒泡 事件捕获和事件冒泡是为了解决网页中的事件流(事件发生的顺序)而提出的概念. 事件捕获是 ...

  3. 事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流

    一.事件冒泡定义 事件冒泡是指在一个对象触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那 ...

  4. JavaScript中的事件冒泡?事件传播的解释

    注:本文来源  可译网 事件冒泡是你在学习javaScript旅途中遇到的一个术语,它涉及到当一个元素被另一个元素嵌套时调用事件处理的顺序,并且两个元素注册了同一个事件(例如,点击事件). 但是事件冒 ...

  5. javascript中的事件冒泡、事件捕获和事件执行顺序

    谈起JavaScript的 事件,事件冒泡.事件捕获.阻止默认事件这三个话题,无论是面试还是在平时的工作中,都很难避免. DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有 ...

  6. javascript --- 事件冒泡与事件捕获

    事件冒泡与事件捕获 事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题.考虑下面这段代码,就不写html->head,body之类的代码了,自行 ...

  7. JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获

    先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...

  8. JS中的事件绑定,事件捕获,事件冒泡以及事件委托,兼容IE

    转载请注明出处:http://www.cnblogs.com/zhangmingze/p/4864367.html   ● 事件分为三个阶段:   事件捕获 -->  事件目标 -->   ...

  9. javascript 事件冒泡和事件代理

    事件冒泡 简单的讲,当子元素的事件处理函数被触发(如onclick),该事件会从事件源(当前子元素)逐级向上层元素传递,触发祖先元素的 onclik 事件,一直到最外层 html 根元素. 这可能会带 ...

随机推荐

  1. Python实现ID3(信息增益)

    Python实现ID3(信息增益) 运行环境 Pyhton3 treePlotter模块(画图所需,不画图可不必) matplotlib(如果使用上面的模块必须) 计算过程 st=>start: ...

  2. homework-02 二维的,好喝的(二维数组的各种子数组)

    1)输入部分 对于输入部分,我定义的输入格式是这样的 前两行为列数和行数 如果文件无法打开,或者输入文件格式不对,均会提示出错并退出 2)二维数组的最大矩形子数组 首先,我使用最最简单的暴力算法,直接 ...

  3. Valuable site on github

    https://thegrid.io/?utm_source=adwords&utm_medium=cpc&utm_campaign=thegrid-display-english&a ...

  4. 宣讲ppt的技巧

    这是一个L运营商的项目,项目规模比较大,中兴的客户群体定位主要是电信运营商,运营商的项目做起来非常累,不是一般的小公司能玩的,一般项目要经过这几个过程,前期信息获得——技术交流引导——实验局测试——投 ...

  5. cacti手册选译(1)

    第一章 系统需求 Cacti需要你的系统安装一下软件: RRDTool版本1.0.49及以上,推荐1.4+ MYSQL5.x及以上版本 PHP5.1及以上 支持PHP的web Server如Apach ...

  6. Elasticseach部分语法总结

    索引 在Elasticsearch中,文档归属于一种类型(type),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统关系型数据库 Relational DB -> D ...

  7. selenium--下拉列表选择

    html 代码: <select name="ColumnId" id="columnOrd"> <option value="2& ...

  8. MySQL中表格各页面的注意和操作项

  9. 计算器软件的代码实现 (策略模式+asp.net)

    一 策略模式代码的编写 using System; using System.Collections.Generic; using System.Linq; using System.Web; /// ...

  10. hdu 5691 Sitting in Line 状压dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5691 题解: 和tsp用的状压差不多,就是固定了一些访问顺序. dp[i][j]表示前cnt个点中布 ...