on和live或bind有什么区别?


172

在jQuery v1.7中on添加了新方法。从文档中:

'.on()方法将事件处理程序附加到jQuery对象中当前选定的元素集。从jQuery 1.7开始,.on()方法提供了附加事件处理程序所需的所有功能。

live和和有bind什么区别?



在问之前已经找到了类似的东西,但没有成功。谢谢!
迭戈

Answers:


329

on()试图将大多数jQuery的事件绑定功能合并为一个。这具有通过livevs 整理效率低下的额外好处delegate。在将来的jQuery版本中,这些方法将被删除,on并且one只会被保留。

例子:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

在内部,jQuery将所有这些方法速记事件处理程序设置方法映射到该on()方法,进一步表明您从现在开始就应该忽略这些方法,而只需使用on

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

参见https://github.com/jquery/jquery/blob/1.7/src/event.js#L965


正如@JamWaffles所说的那样,这是最容易理解的答案。您能否添加on和委托之间的比较以完成答案?谢谢!
迭戈

大声笑,您在我之前4秒钟添加了jquery源:D btw实时等效上下文是document,而不是document.body
Esailija

1
您可能想要引用1.7标签,否则将来的更改可能会使您的链接无效(而不是指向正确的位置):github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling

3
$(document.body).delegate("click", ".mySelector", fn);应该是$(document.body).delegate(".mySelector", "click", fn);
Sonny

2
@ dsdsdsdsd,off用作unbind,unlive和undelegate的通用替代。
Andy E

12

on在自然界中非常接近delegate。那么为什么不使用委托呢?这是因为on并不孤单。有off,取消绑定事件并one创建仅执行一次的事件。这是新事件的“包”。

主要问题 live是它附加到“窗口”上,迫使页面结构(dom)内部深处的元素上的点击事件(或其他事件)“冒泡”到页面顶部以查找事件经理愿意处理。在每个级别,都必须检查所有事件处理程序,如果您进行深层加密(<body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...),这可以快速加起来

因此,和其他快捷方式事件活页夹bind一样click,和一样直接附加到事件目标。假设您有1000行和100列的表格,并且100'000单元格中的每一个都包含一个复选框,您要处理该单击。附加100'000事件处理程序将花费大量时间加载页面。在表级别创建一个事件,并使用事件委派效率要高几个数量级。事件目标将在事件执行时检索。“ this”将是表格,但“ event.target”将是您平时在表中使用的“ thisclick函数中。现在的好处on是,“ this”将始终是事件目标,而不是它所附加的容器。


委托不附带取消委托吗?
DaveWalley 2014年

1
对。好发现。您每天都在学习;)(自2011年以来,您的文档得到了极大的改进)
roselan 2014年

5

使用.onmethod可以实现.live.delegate.bind具有相同功能,但.live()只能.live()实现(将事件委托给document)。

jQuery("#example").bind( "click", fn ) = jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) = jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) = jQuery( document ).on( "click", "#example", fn )

我可以直接从jQuery来源确认这一点:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

jQuery(this.context)?this.context=== document在大多数情况下


3

(在您更改问题之前,我的开场白更有意义。最初,您说的是“和有什么区别live?”)

on更像是delegate不是很喜欢live,它基本上是统一的形式binddelegate(事实上,该团队表示,其目的是“......统一连接的事件发送到文档的所有方面......”)。

live基本上on(或delegate)附加到整个文档中。从v1.7开始不推荐使用ondelegate。展望未来,我怀疑我们将on仅使用代码,而不是使用binddelegate(或live)。

因此,在实践中,您可以:

  1. on像这样使用bind

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. 使用onlike delegate(事件委托植根于给定元素中):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
  3. 使用onlike live(事件委托植根于文档中):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);

1
在链接的页面中,我说:“如果将新HTML注入页面,请在将新HTML放入页面后选择元素并附加事件处理程序。或者,使用委托事件来附加事件处理程序,如下所述。” 。因此,更可能是绑定,而不是生存。我对吗?
迭戈

@Diego:on是的组合binddelegate,和我说的,不是很喜欢live。您可以使用onlike bind(将处理程序直接附加到元素上),也可以使用onlike delegate(将处理程序附加到元素上,但仅在所单击的实际元素与选择器匹配时,才触发该事件,就好像该元素是那个选择器一样)。事件发生-例如,事件委托),或者您可以像使用它一样livedelegate使用文档作为根)。如果动态添加元素,则事件委托使它很有用。
TJ Crowder

1
旧的live也可以像委托一样使用:$("#id", ".class").live(fn)= $(".class").delegate("#id", fn );实际上,在旧的jQuery源中,他们将live用作一般情况,将委托用作特殊情况,这使您在考虑时更加困惑。
Esailija

@Esailija:足够公平。我不认为这是它广为人知的用途,因为它们delegate很快就添加了,但是仍然可以。:-)
TJ Crowder


2

基本用例没有一个。这两行在功能上是相同的

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on()也可以进行事件委托,因此首选。

.bind()实际上现在只是.on()的别名。这是1.7.1中bind函数的定义

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

添加.on()的想法是创建一个统一的事件API,而不是具有用于绑定事件的多个函数。.on()替换.bind()、. live()和.delegate()。


0

如果要获取与该元素关联的事件处理程序,应该注意一些事项-注意处理程序附加到的元素!

例如,如果您使用:

$('.mySelector').bind('click', fn);

您将使用以下方法获取事件处理程序:

$('.mySelector').data('events');

但是,如果您使用:

$('body').on('click', '.mySelector', fn);

您将使用以下方法获取事件处理程序:

$('body').data('events');

(在最后一种情况下,相关事件对象将具有selector =“。mySelector”)


events仍然没有文档,我认为它在1.9中不再起作用
John Dvorak

对。可以使用_data代替较新版本中的数据。答案是关于“事件所有者”的区别,而不是旧版本或新版本的确切语法。还有其他有关不同JQuery版本的确切语法的文章。例如stackoverflow.com/questions/2518421/…–
亚历山大
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.