上一章节探讨了事件的一些概念,接下来看下jQuery的事件模块。

jQuery对事件的绑定分别有几个API:.bind()/.live()/.delegate()/.on()/click(),

不管是用什么方式绑定,归根到底还是用addEventListener/attachEvent(IE)处理的,正如jQuery的选择器一样不管如何匹配最终还是使用浏览器提供的几个接口处理。

那么现在就有个疑问,事件为什么还要区分那么多不同的处理方案?

这里就要涉及到之前提到的 DOM 事件处理模型了,捕获与冒泡传统的事件处理给某一元素绑定了一个点击事件,传入一个回调句柄处理。element.addEventListener('click',doSomething,false),对比传统事件来存在这些问题

  第一:大量的事件绑定,性能消耗,而且还需要解绑(IE会泄漏);

  第二:绑定的元素必须要存在;

  第三: 后期生成HTML会没有事件绑定,需要重新绑定

  第四: 语法过于繁杂

针对这些问题,因此jQuery引进是采用委托的机制思想来处理。

谈到事件委托来复习下上节提到的事件模型。DOM 有个事件流的特性,也就是说我们在页面上触发节点的时候事件都会上下或者向上传播,称为事件捕捉和事件冒泡。,DOM2.0 模型将事件处理流程分为三个阶段:事件捕获阶段、事件目标阶段、事件起泡阶段

事件传送可以分为3个阶段。
(1)在事件捕捉(Capturing)阶段,事件将沿着DOM树向下转送,目标节点的每一个祖先节点,直至目标节点。例如,若用户单击了一个超链接,则该单击事件将从document节点转送到html元素,body元素以及包含该链接的p元素。在此过程中,浏览器都会检测针对该事件的捕捉事件监听器,并且运行这件事件监听器。
(2)在目标(target)阶段,浏览器在查找到已经指定给目标事件的事件监听器之后,就会运行该事件监听器。目标节点就是触发事件的 DOM 节点。例如,如果用户单击一个超链接,那么该链接就是目标节点(此时的目标节点实际上是超链接内的文本节点)。
(3)在冒泡(Bubbling)阶段,事件将沿着DOM树向上转送,再次逐个访问目标元素的祖先节点到document节点。该过程中的每一步。浏览器都将检测那些不是捕捉事件监听器的事件监听器,并执行它们。

换句话说,事件委托就是事件目标自身不处理事件,而是把处理任务委托给其父元素或者祖先元素,甚至根元素(document),如.live()

对于jQuery中提供多个api来绑定事件:不管你用的是(click / bind / delegate)之中哪个方法,最终都是 jQuery 底层都是调用 on 方法来完成最终的事件绑定。因此从某种角度来讲除了在书写的方便程度及习惯上挑选,不如直接都采用 on 方法来的痛快和直接使用.on()方法事件处理程序到当前选定的 jQuery 对象中的元素。

  在jQuery 1.11中,.on()方法提供绑定事件处理的所有功能、效果不言而喻了,除了性能的差异,通过委托的事件还能很友好的支持动态绑定,只要 on 的delegate 象是 HTML 页面原有的元素,由于是事件的触发是通过Javascript的事件冒泡机制来监测,所以对于所有子元素(包括后期通过JS生成的元素)所有的事件监听均能有效,且由于不用对多个元素进行事件绑定,能够有效的节省内存的损耗。

说了这么多,jQuery提供了这么多绑定的方法,具体有什么区别我们来了解一下:

(1)、.bind()方法:用于直接附加一个事件处理程序到元素上,处理程序附加到 jQuery 对象中当前选中的元素,所以在 .bind() 绑定事件的时候这些元素必须已经存在,很明显就是直接调用没利用委托机制。

(2)、live()方法:将委托的事件处理程序附加到一个页面的 document 元素,从而简化了在页面上动态添加的内容上事件处理的使用。这和delegate() 方法类似,只是把所有事件都委托到document对象上来处理,增加冒泡处理时间。现在已经摒弃该方法了,不推荐使用。还是用例子说明一下:

    $('a').live('click', function() { alert("!")})

jQuery 把 alert 函数绑定到 $(document) 元素上,并使用 ’click’和 ’a’作为参数。任何时候只要有事件冒泡到 document 节点上,它就查看该事件是否是一个 click 事件,以及该事件的目标元素与’a’这一CSS 选择器是否匹配,如果都是的话,则执行函数。由于live缺点太多,这里就不一一赘述了。

(3)、 delegate(): 为了突破单一 .bind() 方法的局限性,实现事件委托,引入了.live()方法。后来,为解决“事件传播链”过长的问题,新版本又支持为 .live() 方法指定上下文对象。而为了解决无谓生成元素集合的问题,之后版本干脆直接引入了一个新方法 .delegate()。

使用 .delegate(),前面的例子可以这样写:

  $('#element).delegate('a', 'click', function() { alert("!!!") });

jQuery 查找(‘#element’),并将click 事件和’a’这一CSS选择器作为参数把 alert 函数绑定到(‘#element)上。

事件监听原理是:任何时候只要有事件冒泡到$(‘#element)上,它就查看该事件事件类型是否是click事件,以及该事件的目标元素(curTarget)是否与CCS选择器相匹配。如果都满足就执行函数。可以注意到,这一过程与.live()类似,但是其把处理程序绑定到具体的元素而非document这一根上,从而大大减少事件传播过程(事件冒泡过程)。

由此可见.delegate() 方法是一个相对完美的解决方案。但在DOM结构简单的情况下,也可以使用.live()。

(4)、on方法:其实 .bind(), .live(), .delegate()都是通过.on()来实现的,.unbind(), .die(), .undelegate()也是一样的都是通过.off()来实现的,该接口只是提供了一种统一绑定事件的方法

总得来说,虽然bind/delegate/live这三个方法都能实现DOM节点事件绑定,但是可以用 .on() 来代替上述的 3 种方法

说了这么多,具体使用过程中该用那个方法呢?

下面来总结一下:

1. 为DOM中的很多元素绑定相同事件;
2. 为DOM中尚不存在的元素绑定事件;
3. 用.bind()的代价是非常大的,它会把相同的一个事件处理程序hook到所有匹配的DOM元素上
4. 不要再用.live()了,它已经不再被推荐了,而且还有许多问题
5. .delegate()会提供很好的方法来提高效率,同时我们可以添加一事件处理方法到动态添加的元素上 实际运用中,事件委托机制(基于事件冒泡)仍存在不足之处:
1. 并非所有的事件都能冒泡,如load, change, submit, focus, blur
2. 加大管理复杂
3. 不好模拟用户触发事件
4. 如何取舍就看项目实际中运用了。
 

jquery源码分析(七)——事件模块 event(二)的更多相关文章

  1. jQuery 源码分析(十七) 事件系统模块 实例方法和便捷方法 详解

    实例方法和便捷方法是指jQuery可以直接通过链接操作的方法,是通过调用$.event上的方法(上一节介绍的底层方法)来实现的,常用的如下: on(types,selector,data,fn,one ...

  2. jQuery 源码分析(十一) 队列模块 Queue详解

    队列是常用的数据结构之一,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队).特点是先进先出,最先插入的元素最先被删除. 在jQuery内部,队列模块为动画模块提供基 ...

  3. 一个普通的 Zepto 源码分析(三) - event 模块

    一个普通的 Zepto 源码分析(三) - event 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块, ...

  4. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  5. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  6. [转] jQuery源码分析-如何做jQuery源码分析

    jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...

  7. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  8. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

  9. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

随机推荐

  1. Application.StartupPath获取执行文件路径substring()取特定长度字符串取得根目录

    Application.StartupPath获取执行文件路径substring()取特定长度字符串取得根目录 2012-07-20 10:48 257人阅读 评论(0) 收藏 举报 path usi ...

  2. E20170624-ts

    stateless adj. 无国家的,无国籍的; groupware 群件 cookie  n. 饼干; 小甜点; 吸引人的年轻妇女; 甜面包; session  n. 开会,会议; (法庭的) 开 ...

  3. codevs1005生日礼物(dfs)

    1005 生日礼物  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description 9月12日是小松的朋友小寒的生日.小松知道小寒特别 ...

  4. codevs1312连续自然数和

    1312 连续自然数和  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold       题目描述 Description 对于一个自然数M,求出所有的连续的自然数段 ...

  5. Akka源码分析-ask模式

    在我之前的博文中,已经介绍过要慎用Actor的ask.这里我们要分析一下ask的源码,看看它究竟是怎么实现的. 开发时,如果要使用ask方法,必须要引入akka.pattern._,这样才能使用ask ...

  6. HTML-ul分分钟理解

    在HTML中,列表有三种,如图分别是有序.无序和自定义列表.上面是我在网络上找到的一张图片很明了就看以看出来,今天要分享的就是其中的无序列表Ul(unordered list),给大家整理了一下我所知 ...

  7. BZOJ 2178 Simpson积分

    思路: 我发现能用Simpson积分水的题  好像都是裸题诶233333 //By SiriusRen #include <bits/stdc++.h> using namespace s ...

  8. 【USACO2006 Mar】滑雪缆车 skilift

    [USACO2006 Mar] 滑雪缆车 skilift Time Limit 1000 msMemory Limit 131072 KBytes Description 科罗拉多州的罗恩打算为奶牛建 ...

  9. ClouderaManager与CDH

    * ClouderaManager与CDH 集群简述 对于企业而言,一般的集群大小规模大概是如下映射关系: 集群大小 小:10~30节点 中:100~300节点 大:1000+节点 对应所需的zook ...

  10. 我正在学英语是用learning english还是用studying english?

    学一门语言用 learn. study 表示深入研究,一般指在大学里.如果大学里的专业是英语,就可以说 study English. 1. If you study hard, you will le ...