【问题标题】:jQuery .on does not work but .live doesjQuery .on 不起作用,但 .live 可以
【发布时间】:2012-04-02 23:13:44
【问题描述】:

由于 live() 方法在 1.7 版已被弃用,我开始检查我的源代码并将所有实时事件处理程序转换为 on()。我的印象是改变会很简单,一切都会像以前一样工作。但是,我遇到了一些行为不正常的代码。

我有下面的 jQuery select 来绑定一个表格标签的点击事件...

$('table.accordion-header').live("click", function ($e) {
  // gobs of code
}

... 它工作得很好(即 ​​- 即使在页面上发生异步回发之后也会引发我的表格标签点击事件)。但是如果我将代码更改为以下

$('table.accordion-header').on("click", function ($e) {
  // gobs of code
}

然后在页面上发生任何异步回发后不再引发 click 事件。请注意 - click 事件对任何异步回发都有效,但之后不再有效。那么我在这里错过了什么?

【问题讨论】:

  • 检查你是否把它放在一个“$(document).ready()”函数类型中,或者你之前没有调用它并返回false。有一种检查方法:$('table.accordion-header').trigger('click');

标签: jquery


【解决方案1】:

这样的问题已经得到了很多很多次的回答,因为人们不太了解.on() 的动态版本的工作原理似乎相当普遍。您正在使用 .on() 的静态形式,当您可能打算像这样使用 .on() 的动态形式时,对象必须存在于您调用 .on() 时:

$(someStaticParentObject).on("click", 'table.accordion-header', function ($e) {
  // code
}

.live().on() 替换,因为.on() 允许您通过指定动态对象的静态父对象来附加事件处理程序来获得更好的性能,这比将其附加到document 更有效.live() 所做的对象。我建议您阅读这些以前的答案(全部由我撰写)以了解有关如何最好地使用.on() 的更多信息。这些答案还包括 cmets 关于使用 .on() 的最有效方式以及其工作原理的简要说明:

jquery: on vs live

Does jQuery.on() work for elements that are added after the event handler is created?

How does jQuery's new on() method compare to the live() method in performance?

What's the difference between jQuery.bind() and jQuery.on()?

Why not take Javascript event delegation to the extreme?

【讨论】:

  • 您提到附加到静态元素比文档更好。但是,如果您不知道具体的父母,使用 $('body').on$(document).on 有什么优势?
  • @PaulAlexander - 首先,您应该将$(document.body)$(document) 进行比较。我总是尽可能选择 DOM 层次结构中最低的(在本例中为 document.body),但实际上这两者之间可能没有太大区别。
  • @jfriend00,在许多情况下,附加到document 是唯一的可能性,因为在加载(页面加载)时,DOM 中不存在其他对象。
  • @md1337 - 通常,您应该在页面加载之后设置事件处理程序,而不是在加载之前。在文档上放置大量事件处理程序在运行时效率低下。
  • @md1337 答案是隐藏控件并让它们在页面加载后出现。
【解决方案2】:

相当于

$('table.accordion-header').live("click", function ($e) {
  // gobs of code
} );

$(document).on("click", 'table.accordion-header', function ($e) {
  // gobs of code
} );

【讨论】:

  • 但是,如果您真的了解.on() 的工作原理以及应该如何使用它,那么使用它的方法比使用$(document).on() 更有效。 .live() 被替换的一个主要原因是让人们可以比这更有效地使用它。我在下面的回答提供了更多细节。
  • 是的,确实......我只是在使用 OP 提供的东西......还有.delegate() 用于更精细的控制......
  • 如果您正在为您单击的元素使用 id,请添加到语法 "#" $(document).on("click", '#id_of_the_element', function ($e) { // 大量代码 });
【解决方案3】:

在 jQuery 1.7.2 源代码中,“live”几乎指向“on”,所以这个问题可能与“on”功能无关。这需要排除。 on 的选择器可能是个问题。

jQuery 源码:

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

【讨论】:

  • 如果您更仔细地查看此代码并阅读其他答案,您会发现问题是他们将选择器 'table.accordion-header' 放在了 .live() 等效于 @987654324 的错误位置@.
  • 我在这里要说的是,“live”和“on”是相同的,“live”指向“on”。这是一个选择器问题,不是实时也不是。
  • 为什么你必须在原始问题中将我的答案标记为无用,发布者认为将 live 更改为 on 是问题所在。我不得不指出,on==live,这更像是一个建议,以排除他最初对两者的误解。
  • 在我看来,你没有回答他们的问题。您提供了一个可以查看的地方的想法,甚至对于 OP 应该实际查看的内容也非常模糊。您说“on 的选择器可能是个问题”。他们需要更改选择器吗?他们应该如何解决?这充其量只能作为评论,因为它不是答案。你,你自己甚至不确定这是基于你写作的基调的正确方向,你没有告诉他们如何解决它。
  • 对不起丹尼斯。我不认为我们需要把它变成更多的意见分歧。不是问题的实际答案的评论(甚至是非常有用的评论)应该作为 cmets 而不是作为答案发布。这就是 SO 想要的样子,也是他们认为 Q&A 格式最有效的方式。如果您更具体地了解他们应该如何将选择器放在不同的位置(例如 Gaby 的回答),我会认为这是一个有效的答案。
【解决方案4】:

我在尝试将我的 live() 更新为 on() 时也遇到了麻烦,但当有人向我展示第一个父级或上下文选择器的工作原理时,我终于得到了它。关键是确保第一个元素在文档对象模型中。

$(this) 与 .on() 的工作方式也不明显。

$(document).on("click", 'table.accordion-header', function ($e) {
  // gobs of code
} );

在上面给出的示例中,函数代码中的 $(this) 将引用 $('table.accordion-header') 而不是您可能期望的 $(document)。

这里进一步解释:.on() with $(this)

【讨论】:

    【解决方案5】:

    我可以这样说的最佳方式就像jQuery 中关于.live().on() 功能的文档所说:

    1. 在您的选择器“$(selector)”中添加一个随页面加载的具体元素 - 不是动态加载。
    2. 然后将辅助选择器放入指示“选择器”的方法中 - 这个可以动态创建。
    //so this..
        $('table.accordion-header').live("click", function ($e) {
      // gobs of code
    });
    
    //becomes this..   
        $('table').on("click",'.accordion-header', function ($e) {
      // gobs of code
    });
    

    假设“table”当然是与页面一起加载的。

    【讨论】:

      猜你喜欢
      • 2017-03-23
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-06
      • 2013-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多