jQuery事件:bind、delegate、on的区别
最近在AngularJS的开发中,遇到一个神奇的事情:我们用到livebox来预览评论列表中的图片, 然而评论列表是由Angular Resource动态载入的。不可思议的是,点击这些动态载入的图片仍然会触发lightbox的图片预览。 难道lightbox使用先进的MutationObserver技术监听了DOM的变化?观察lightbox源码才发现,原来只是jQuery的.on()
方法:
$('body').on('click', 'a[rel^=lightbox], ...', function(event){});
本文便来详解各种jQuery事件绑定方法:on
,bind
,delegate
,live
,unbind
,trigger
。 同时总结一下常用的jQuery事件技术:如何阻止事件冒泡、阻止浏览器默认行为、解绑事件处理函数、自定义事件。
什么是 jQuery 事件
jQuery事件是DOM事件的封装,同时支持自定义的扩展。在程序设计中,事件和代理有着相似的作用: 它们提供了一种机制,使得行为的实现方式和调用时机可以分离。
不谈jQuery,DOM本身就提供了一系列的javascript事件,例如click
,keyup
,submit
。 未实现相关业务逻辑,通常会为这些事件定义一系列的处理函数,处理函数定义了业务的实现方式,而浏览器知道这些业务的调用时机。 Javascript事件就是这样一种机制,使得行为的实现方式和调用时机可以动态地绑定。
jQuery事件是通过封装javascript事件来实现的,例如.keyup()
便是onkeyup
的封装:
.keyup()
: Bind an event handler to the “keyup” JavaScript event, or trigger that event on an element.
除了封装大多数的javascript事件,jQuery提供了统一的事件绑定和触发机制:
- 绑定事件:
bind
、on
、live
、delegate
、keyup(<function>)
; - 触发事件:
trigger('keyup')
、keyup()
; - 解绑事件:
unbind
、off
、die
、undelegate
。
事件绑定:bind
使用javascript绑定一个事件很简单,只需要在HTML中设置onxxx
属性, 并且在javascript中定义相关的处理函数便可以完成。
<div onclick="func()"></div>
<script>
function func(){
console.log('clicked!');
}
</script>
上述是基本的javascript事件处理方式,而jQuery提供了更加方便的方式:.bind()
函数。
.bind()
:Attach a handler to an event for the elements.
<div id='foo'></div>
<script>
$('#foo').click(function(){
console.log('clicked!');
});
</script>
.click(<function>)
等效于.bind('click', <function>)
。另外还可以通过unbind
来解绑事件:
$('#foo').unbind('click');
如果
unbind
参数为空,则解绑匹配元素的所有事件处理函数。 在我的理解中,我们还是不要off
,unbind
,die
吧。即使不谈效率,它们也使得软件更难理解了。 如果你感觉有需要,下面的.on()
应该会满足你~
.bind
将会给所有匹配的元素都绑定一次事件,当元素很多时性能会变差。 而且后来动态新增的元素不会被绑定。
事件冒泡与默认行为
在DOM中默认情况下,事件是会冒泡的,即同样的事件会沿着DOM树逐级触发。 有时这是我们不希望的行为,可以在事件处理函数中阻止它。
// 事件处理函数的第一个参数是一个事件对象
$('#foo').click(function(event){
event.stopPropagation();
// do sth.
});
浏览器对用户事件的默认行为是另一个需要考虑的事情,尤其是<a>
标签的click
事件。 当用户点击<a>
标签时,首先调用所有的事件处理函数,然后执行默认行为:页面跳转或者定位。 同样地,我们可以阻止它:
$('a').click(function(event){
event.preventDefault();
// do sth.
});
在实践中,我们常常让事件处理函数return false
来阻止冒泡和默认行为, 可以认为return false
做了三件事情:
stopPropagation()
;preventDefault()
;- 立即结束当前函数并返回。
$('a').click(function(event){
// do sth.
return false;
});
自定义事件
jQuery事件是基于DOM事件的,但jQuery提供了更加普遍的事件机制。 这使得我们可以方便地自定义事件,只需要给一个尚不存在的事件名即可:
<div id='foo'></div>
<script>
$('#foo').bind('fucked', function(){
console.log("I'm fucked.");
});
$('#foo').trigger('fucked');
</script>
这里定义了一个叫fucked
的事件并绑定了处理函数,然后使用trigger
来触发该事件。 在真实的场景中,通常用其他的事件来触发自定义事件:
var he = 'man';
$('#foo').click(function(){
if(he === 'man') $(this).trigger('fucked');
});
Delegate
.delegate
是另一种绑定事件的方式。它将事件处理函数绑定在指定的根元素上, 由于事件会冒泡,它用来处理指定的子元素上的事件。
.delegate()
:Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.
<div id="root">
<a>Alice</a>
<a>Bob</a>
</div>
<script>
$('#root').delegate('a', 'click', function(){
console.log('clicked');
});
</script>
它的使用方式比bind
稍显复杂,但它的功能非常强大:
- 自动绑定动态添加的元素。因为事件处理函数绑定在
#root
上,新加的子元素事件也会冒泡到#root
。 - 性能好于
.bind()
。只绑定一个事件处理函数,绑定速度相当快。
如果你在使用AngularJS等动态操作DOM的工具,那么
.delegate()
将会非常实用,它能对新增的DOM元素自动绑定。
On
事实上,.on()
才是jQuery事件的提供者。其他的事件绑定方法都是通过.on()
来实现的,请看jQuery1.8.2的源码:
bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},
unbind: function( types, fn ) {
return this.off( types, null, fn );
},
live: function( types, data, fn ) {
jQuery( this.context ).on( types, this.selector, data, fn );
return this;
},
die: function( types, fn ) {
jQuery( this.context ).off( types, this.selector || "**", fn );
return this;
},
delegate: function( selector, types, data, fn ) {
return this.on( types, selector, data, fn );
},
undelegate: function( selector, types, fn ) {
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
},
既然.on
是最通用的jQuery事件机制,那么上述的所有例子都可以用.on()
来实现:
// bind
$( "#foo" ).bind( "click", function( e ) {} );
$( "#foo" ).on( "click", function( e ) {} );
// delegate
$( "#root" ).delegate( "a", "click", function( e ) {} );
$( "#root" ).on( "click", "a", function( e ) {} );
我们看到上面还有一个
.live()
方法,它与delegate
是类似的, 不过它强制指定了root
是document
(即this.context
),因而性能略差。 自jQuery1.7起已经不推荐使用了。参见: https://api.jquery.com/category/deprecated/deprecated-1.7/
jQuery事件:bind、delegate、on的区别的更多相关文章
- Jquery中bind和live的区别
Jquery中绑定事件有三种方法:以click事件为例 (1)target.click(function(){}); (2)target.bind("click",function ...
- jQuery 事件 - bind() 方法
定义和用法 bind() 方法为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数. 实例1(一个事件) 记得把js引用地址换掉 当点击鼠标时,隐藏或显示 p 元素: <html&g ...
- jquery中bind和on的区别
1.首先,来看看bind和on的语法. bind的用法: $('a').bind('click',[data],function(){}) 其事件的绑定者是固定的,就是a,第一个参数是事件,第二个参数 ...
- jQuery的.bind()、.live()和.delegate()的区别
参考:http://kb.cnblogs.com/page/94469/ 摘要:jQuery的.bind()..live()和.delegate()之间的区别并非总是那么明显的,然而,如果我们对所有的 ...
- jQuery的.bind()、.live()和.delegate()之间区别
摘要:jQuery的.bind()..live()和.delegate()之间的区别并非总是那么明显的,然而,如果我们对所有的不同之处都有清晰的理解的话,那么这将会有助于我们编写出更加简洁的代码,以及 ...
- jQuery的.bind()、.live()和.delegate(),on之间区别
基本要素 51CTO推荐专题:jQuery从入门到精通 DOM树 首先,可视化一个HMTL文档的DOM树是很有帮助的.一个简单的HTML页面看起来就像是这个样子: 事件冒泡(又称事件传播) 当我们点击 ...
- Jquery中bind和live.one,delegate的区别
Jquery中绑定事件有三种方法:以click事件为例 (1)target.click(function(){}); (2)target.bind("click",function ...
- jQuery事件绑定—on()、bind()与delegate()
啃了一段日子的js相关了,学的过程中发现在jQuery中绑定事件时,有人用bind(),有人用on(),有人用delegate(),还有人用live(),看代码的时候觉得都实现功能了也就掀过去了,只是 ...
- Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
简介 最近了解到很多网页开发者对jquery中的 .bind() .live() .delegate() 和 .on() 方法存在很多的疑惑.这些疑惑通常是关于它们之间真正的区别是什么啊,什么时候该使 ...
随机推荐
- 【java】初始化一个指定大小的list,在指定位置set存入元素,下标越界
List使用过程中,出现这样的问题,出现异常:java.lang.IndexOutOfBoundsException: Index: 1, Size: 0 List<String> lis ...
- MNI模板和Talairach 模板的对比
The MNI brain and the Talairach atlas SPM 96 and later use standard brains from the Montreal Neurolo ...
- EventBus (一) 使用详解——初步使用EventBus
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 前言:EventBus是上周项目中用到的,网上的文章大都一样,或者过时,有用的没几篇,经过琢磨,请教他人,也终于弄清楚点眉目,记 ...
- 7.volatile关键字
volatile:一个线程修改了某一个共享变量的值,其他线程也是否能够立即知道这个修改的 1.主要是让该“变量”在多个线程中可见,在java中每一个线程都有一块自己的工作区,其中就存放着所有线程“共享 ...
- ThreadLocal实现session中用户信息 的线程间共享
转载自:http://blog.sina.com.cn/s/blog_4b5bc01101013gok.html ThreadLocal并不难理解,我总结的最简单的理解就是: ThreadLocal像 ...
- LinuxMint19/LMDE3安装后的设置
LinuxMint 安装后进行一些设置. 1.设置主板时间为本地时间,默认为UTC时间,与Windows不同,如果双系统,时间有时差. sudo timedatectl set-local-rtc t ...
- crm2013安装和部署语言包
步骤 1:安装语言包 假设具有执行 Microsoft Dynamics CRM for Microsoft Office Outlook 的用户,除了在执行 Microsoft Dynamics C ...
- 推荐大家一个CSS书写规范
CSS书写顺序 1.位置属性(position, top, right, z-index, display, float等) 2.大小(width, height, padding, margin) ...
- 创建组件“AxLicenseControl”失败
打开以前的程序,准备来添加一个功能,打开主程序就报错: 我未曾改变过版本,原来是由于破解测试需要,修改了系统时间,时间对不了,ArcGIS的问题,改过来就正常了.
- java对象的强引用,软引用,弱引用和虚引用
1.强引用 以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用.如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它.当内存空 间不足,Java虚拟机宁愿抛出Out ...