如今的 JavaScript 技术界里最火热的一项技术应该是‘事件委托(event delegation)’了。使用事件委托技术能让你避免对特定的每个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。基本概念非常简单,但仍有很多人不理解事件委托的工作原理。这里我将要解释事件委托是如何工作的,并提供几个纯JavaScript的基本事件委托的例子。

  假定我们有一个UL元素,它有几个子元素:

1
2
3
4
5
6
7
8
<ul id="parent-list">
    <li id="post-1">Item 1</li>
    <li id="post-2">Item 2</li>
    <li id="post-3">Item 3</li>
    <li id="post-4">Item 4</li>
    <li id="post-5">Item 5</li>
    <li id="post-6">Item 6</li>
</ul>

  我们还假设,当每个子元素被点击时,将会有各自不同的事件发生。你可以给每个独立的li元素添加事件监听器,但有时这些li元素可能会被删除,可能会有新增,监听它们的新增或删除事件将会是一场噩梦,尤其是当你的监听事件的代码放在应用的另一个地方时。但是,如果你将监听器安放到它们的父元素上呢?你如何能知道是那个子元素被点击了?

  简单:当子元素的事件冒泡到父ul元素时,你可以检查事件对象的target属性,捕获真正被点击的节点元素的引用。下面是一段很简单的JavaScript代码,演示了事件委托的过程:

1
2
3
4
5
6
7
8
9
// 找到父元素,添加监听器...
document.getElementById("parent-list").addEventListener("click",function(e) {
    // e.target是被点击的元素!
    // 如果被点击的是li元素
    if(e.target && e.target.nodeName == "LI") {
        // 找到目标,输出ID!
        console.log("List item ",e.target.id.replace("post-")," was clicked!");
    }
});

  第一步是给父元素添加事件监听器。当有事件触发监听器时,检查事件的来源,排除非li子元素事件。如果是一个li元素,我们就找到了目标!如果不是一个li元素,事件将被忽略。这个例子非常简单,UL和li是标准的父子搭配。让我们试验一些差异比较大的元素搭配。假设我们有一个父元素div,里面有很多子元素,但我们关心的是里面的一个带有”classA” CSS类的A标记:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 获得父元素DIV, 添加监听器...
document.getElementById("myDiv").addEventListener("click",function(e) {
    // e.target是被点击的元素
    if(e.target && e.target.nodeName == "A") {
        // 获得CSS类名
        var classes = e.target.className.split(" ");
        // 搜索匹配!
        if(classes) {
            // For every CSS class the element has...
            for(var x = 0; x < classes.length; x++) {
                // If it has the CSS class we want...
                if(classes[x] == "classA") {
                    // Bingo!
                    console.log("Anchor element clicked!");
 
                    // Now do something here....
 
                }
            }
        }
 
    }
});

  上面这个例子中不仅比较了标签名,而且比较了CSS类名。虽然稍微复杂了一点,但还是很具代表性的。比如,如果某个A标记里有一个span标记,则这个span将会成为target元素。这个时候,我们需要上溯DOM树结构,找到里面是否有一个 A.classA 的元素。

  因为大部分程序员都会使用jQuery等工具库来处理DOM元素和事件,我建议大家都使用里面的事件委托方法,因为这里工具库里都提供了高级的委托方法和元素甄别方法。

  希望这篇文章能帮助你理解JavaScript事件委托的幕后原理,希望你也感受到了事件委托的强大用处!

  英文出处:davidwalsh

  本文链接:http://www.cnblogs.com/oooweb/p/javascript-event-delegate.html

JavaScript 事件委托的技术原理的更多相关文章

  1. JavaScript事件委托的技术原理

    如今的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)’了.使用事件委托技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器是被添加到它们的父 ...

  2. c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)

    c#封装DBHelper类   public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...

  3. javascript事件委托机制详解

    以个人前端工作面试经历来看,javascript事件委托是问的最多的一类题目之一,熟悉事件委托能够了解你对于javascript的掌握程度. 面试官可能问一下问题,现在有5个li待办事件,需要实现当点 ...

  4. JavaScript 事件委托

    JavaScript事件委托,或者叫事件代理,是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件. 借花献佛的例子(取快递): 有三个同事预计会在周一收到快递.为签收快递,有两种办法 ...

  5. 关于javaScript事件委托的那些事

    今天是第一次写稿,还是有那么一丢丢小鸡冻...回归正题啦... 关于javaScript事件委托不得不说的那些事,为什么要使用事件委托? 我们可以这么说,假设老板要分配一项任务,首先要秘书叫A君来到办 ...

  6. javascript事件委托的原理与实现

    事件委托 事件流 捕获:查找目标元素: 目标:执行目标的事件: 冒泡:依次执行祖先元素的事件. onmouseenter和onmouseleave不支持冒泡: onmouseover和onmouseo ...

  7. javascript事件委托和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  8. javascript 事件委托 和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  9. javascript事件委托和jquery事件委托

    元旦过后,新年第一篇. 初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解 ...

随机推荐

  1. EditPlus添加到右键菜单

    1.Alt+R 键打开“运行” 2.“运行”中输入:regedit 打开注册表    (1.在 "我的电脑HKEY_CLASSES_ROOT*" 下新建项 shell: (2.在 ...

  2. iOS案例:读取指定目录下的文件列表

    // // main.m // 读取指定目录下的文件列表 // // Created by Apple on 15/11/24. // Copyright © 2015年 Apple. All rig ...

  3. Spring的DI(Ioc) - 注入bean 和 基本数据类型

    注入bean有两种方式: 注入其他bean: 方式一 <bean id="orderDao" class="cn.itcast.service.OrderDaoBe ...

  4. Sublime Text 2 一些常用的快捷键

    atrl+F查找后按F3或者ctrl+F3,是查找下一个,shift+F3是查找上一个alt+f3高亮所有的查找的ctrl+h 查找并替换 ctrl+left是向左一个单词跳跃,right同理 ctr ...

  5. poj3714Raid(平面最近点对)

    链接 模板 稍加一点标记 模板 #include <iostream> #include<cstdio> #include<cstring> #include< ...

  6. 转:switch内部的变量定义问题(goto类似)

    自我总结:(之前查过goto和switch的资料但是一直没有搞懂,直到今天看到这个讨论才懂了) 1   int a;    是个描述,而不是个命令,只是说明我需要空间,编译器会保证在相应的作用域之中这 ...

  7. JQuery & Javascript

    Jquery 是一个优秀的javascript框架,是轻量级的js库 jQuery简化了javascript 编程 jQuery很容易学习

  8. mixamo fuse三维角色制作

    软件下载: http://www.cgtsj.com/cg/yj/1302/index.html 资源名称: Mixamo Fuse三维角色制作软件V1.3版 本站编号:  YJ1302 百度网盘:下 ...

  9. HTTP Content-Type的作用

    在用java的 AsyncHttpClient与服务器通信时,忘记设置了 Content-Type的值,开始以为没有问题,使用默认的值就行 后面出现了问题.查资料发现,Content-Type是用在M ...

  10. IE6/IE7下:inline-block解决方案

    IE6/IE7下对display:inline-block的支持性不好. 1.inline元素的display属性设置为inline-block时,所有的浏览器都支持: 2.block元素的displ ...