JavaScript事件冒泡和事件委托

付建宇 - 2 条评论

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

事件冒泡

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

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

CSS

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

HTML

  1. <div id="d1" class="white">
  2. <div id="d2" class="white">
  3. <div id="d3" class="white">
  4. <div id="d4" class="white"></div>
  5. </div>
  6. </div>
  7. </div>
  8. <button id="reset1">重置</button>

Javascript

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

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

事件委托

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

  1. jQuery('#d1').click(function(e){
  2. var t = jQuery(e.target);
  3. var id = t.attr('id');
  4. if (id==='d4'){
  5. t.css('background-color', 'yellow');
  6. } else if (id==='d3') {
  7. t.css('background-color', 'green');
  8. } else if (id==='d2') {
  9. t.css('background-color', 'blue');
  10. } else {
  11. t.css('background-color', 'red');
  12. }
  13. });

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

  1. $('#bind').click(function(){
  2. if ($(this).is(':checked')) {
  3. $('#d4').bind('click', function(e){
  4. e.stopPropagation();
  5. alert('冒泡被阻止,这块将不会改变颜色');
  6. });
  7. } else {
  8. $('#d4').unbind('click');
  9. }
  10. });

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

注意事项

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

但也有些需要注意的。如果用于捕获事件的节点会在某些情况下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. Quartz.NET Windows

    Quartz.NET Windows 服务示例 想必大家在项目中处理简单的后台持续任务或者定时触发任务的时候均使用 Thread 或者 Task 来完成,但是项目中的这种需求一旦多了的话就得将任务调度 ...

  2. Ant学习---第五节:Ant_Junit介绍(基于3的版本)

    Junit3 和 Junit4 有本质上的区别 1.普通java类,代码如下: package learn.junit; public class HelloWorld { public String ...

  3. Android -- 倒计时的实现

    CountDownTimer                                                                      CountDownTimer这个 ...

  4. 四则运算三+psp0级表格

    一.题目 在四则运算二的基础上,选择一个方向进行拓展,我选择的是增加了答题模块 二.设计思路 1.在上次的基础上,增加了答题模块,每出现一道四则运算题目,便提醒输入结果,如果结果错误,就会提示错误 2 ...

  5. xml基础学习笔记04

    今天继续xml学习,主要是:SimpleXML快速解析文档.xml与数组相互转换 .博客中只是简单的做一个学习记录.积累.更加详细的使用方法,可以查看php手册 1.SimpleXML快速解析文档 前 ...

  6. 阿里云服务器mysql修改编码问题

    最近在学习struts+spring+hibernate,强烈推荐新手一本书:陈天河<轻量级web应用开发>,这本书是我见过的国内最好的书,初学者可以买本读读. 不说这个了,来说说我的问题 ...

  7. MVC5 + EF6 入门完整教程 (1)

    第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定" 会让人困惑,而且东西太多容易忘记 ...

  8. Applicationpoolidentity 好有趣哦

    前言: 在服务器上搭建一个网站 Windows Server2008 R2 +IIS7. 应用程序池默认选择ApplicationPoolIdentity.为了适应分布式需求,所以将SqlServer ...

  9. W3C和IE中的事件处理函数

    在上一篇文章中提到了关于传统的JS中注册事件对象的一些缺点和问题,下面是关于DOM2级的现代事件绑定.本文中设计到的HTML文件在文章最后 一.W3C事件处理函数 “DOM2 级事件”定义了两个方法, ...

  10. 【BZOJ】【TJOI2015】线性代数

    网络流/最小割/最大权闭合图 2333好开心,除了一开始把$500^2$算成25000……导致数组没开够RE了一发,可以算是一次AC~ 咳咳还是回归正题来说题解吧: 一拿到这道题,我就想:这是什么鬼玩 ...