【问题标题】:jquery: on vs livejquery: on vs live
【发布时间】:2012-04-09 12:07:15
【问题描述】:

我很好奇为什么当我用.on() 替换.live() 时,我的事件在通过html() 方法插入AJAX 响应后不起作用。假设我有 html 结构:

<div class="a">
   <a href="" class="alert-link">alert</a>
   <a href="" class="ajax-update">update</a>
</div>

和 jquery 代码类似:

$('.alert-link').on("click", function(){
 alert('abc');
 return false;
});

ajax-update 会触发请求,响应会是

警报 更新

我会将其插入parent()。然后再次按下alert-link 将导致重定向到/,但如果我将.on() 更改为.live(),则会再次显示警报。我在这里想念什么?我读过.on().delegate().live() 的替代品。

【问题讨论】:

标签: jquery javascript-events


【解决方案1】:

您对.on() 的特定转换无法正常工作,因为您使用的是.on() 的静态形式而不是.on() 的动态形式。而不是静态形式:

$('.alert-link').on("click", function(){

你需要像这样使用动态表单:

$(someStaticParentObject).on("click", '.alert-link', function(){

这会将事件处理程序绑定到someStaticParentObject,然后对源自与选择器'.alert-link' 匹配的项目的任何子事件使用委托事件处理。您的版本立即绑定到您安装事件处理程序时存在的任何 '.alert-link' 项目(静态绑定),并且没有使用委托事件处理来处理来自尚未创建的对象的事件。

有关.live().on() 以及.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()?

jQuery .live() vs .on() method for adding a click event after loading dynamic html

Why not take Javascript event delegation to the extreme?

简而言之:

$(".item").live('click', fn);

功能等同于:

$(document).on('click', '.item', fn);

.live() 的两个主要缺点是:

  1. 它立即评估选择器".item",这纯粹是浪费循环,因为根本没有使用结果。
  2. .live() 硬连线到文档对象。它使用委托事件处理来处理来来往往的对象,但所有.live() 事件处理程序都分配给文档对象。如果你有很多,这可能是一个很大的性能瓶颈,因为每个冒泡到文档的事件都必须针对所有 .live() 事件处理程序的选择器进行评估。另一方面,.on() 不仅可以绑定到文档对象,还可以绑定到更接近事件实际起源的祖先,并且当有很多委托的事件处理程序时,它可以更有效找到更接近的事件,以便通过.on()选择器只处理接近对象的事件,从而提高性能。例如,上面的处理程序可以这样完成:

    $("#container").on('click', '.item', fn);
    

其中#container 是动态.item 对象的父对象。

【讨论】:

    【解决方案2】:

    .on 组合并替换了 .bind.live.delegate。语法$('selector').on('event', callback)bind 的道德等价物,而不是live

    在您对on 的调用中添加过滤选择器:

    $('container').on('click', 'child-filter', callback);
    

    在这种情况下,

    $('.a').on("click", ".alert-link", function(){
        alert('abc');
        return false;
    });
    

    这一点已更改,因为将委托处理程序附加到更本地化的容器元素比将处理程序附加到 DOM 根的旧 .live 样式更有效。

    换句话说,即使alert-link 元素只会出现在一个小的a div 内部,而使用.live,jQuery 会监听页面上的每个单击事件 并且将其与委托选择器进行比较。由于更具针对性,jQuery 只需处理对a 内元素的点击。

    【讨论】:

    • 我接受了这个答案,而不是 icktoofay 提供的答案,因为额外解释了为什么我的语法不起作用。还有 3 分钟。
    【解决方案3】:

    确实是.delegate.live的替代品,但是还得传入一些额外的参数:

    var container = $('.a').on('click', '.alert-link', function() {
        alert('abc');
        return false;
    }).on('click', '.ajax-update', function() {
        // something that uses AJAX to update .a, like:
        container.load('some-url');
        return false;
    });
    

    欲了解更多信息,see the documentation

    【讨论】:

    • 根据jQuerydocs for .on(),选择器和数据参数是可选的。
    • @Surreal:正确,但如果未提供selector,则其行为类似于bind 而不是delegate
    • 非常有趣,我没有意识到这样改变了行为。谢谢。
    猜你喜欢
    • 2012-03-16
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多