【问题标题】:jquery .live('click') vs .click()jquery .live('click') 与 .click()
【发布时间】:2011-02-09 11:33:34
【问题描述】:

我想知道是否有任何情况下使用.click(function {...}); 而不是.live('click', function {...}); 更好?

从我收集的信息来看,live 选项似乎是一个更好的选择,因此我几乎在所有情况下都使用它而不是普通的 .click(),尤其是考虑到我的很多代码都是异步加载的。

编辑: 这个问题的另一部分。如果我异步加载所有 javascript,.click 仍然会拾取 dom 中已经存在的所有元素。对吧?

【问题讨论】:

  • 注意:live() 现已贬值。
  • 不,它已被弃用;)
  • live() 方法在 jQuery 1.7 版中被弃用,并在 1.9 版中被删除。

标签: jquery live


【解决方案1】:

有时您可能明确希望只将点击处理程序分配给已存在的对象,并以不同的方式处理新对象。但更常见的是,直播并不总是有效。它不适用于链式 jQuery 语句,例如:

$(this).children().live('click',doSomething);

由于事件在 DOM 树中冒泡的方式,它需要一个选择器才能正常工作。

编辑:有人刚刚对此投了赞成票,所以显然人们仍在关注它。我应该指出livebind 都是deprecated。您可以使用.on() 执行这两种操作,IMO 的语法更清晰。替换bind:

$(selector).on('click', function () {
    ...
});

并替换live:

$(document).on('click', selector, function () {
    ...
});

除了使用$(document),您可以使用任何包含您正在监视点击的所有元素的jQuery 对象,但在调用它时相应的元素必须存在。

【讨论】:

  • 附注:从 jQuery 1.7 开始,它们已被弃用。从 jQuery 1.4.3 开始,以前的版本应该使用委托而不是 live。如果较低,则使用实时。
  • +1 用于更新 2 年前的答案,这将使大量的人朝着正确的方向前进,而不是做错事。
【解决方案2】:

(Note 29/08/2017: live 在许多版本之前已被弃用,并在 v1.9 中被删除。delegate 在 v3.0 中被弃用。在这两种情况下,请使用委托on 的签名而不是[也包括在下面]。)


live 的发生是在事件从 DOM 一直冒泡到文档根目录时捕获事件,然后查看源元素。 click 通过捕获元素本身的事件而发生。因此,如果您使用live,并且其中一个祖先元素直接挂钩事件(并防止它继续冒泡),您将永远不会在您的元素上看到该事件。而通常情况下,最接近事件(点击或其他)的元素会首先被抓住,live 和非live 事件的混合可以以微妙的方式改变这一点。

例如:

jQuery(function($) {

  $('span').live('click', function() {
    display("<tt>live</tt> caught a click!");
  });

  $('#catcher').click(function() {
    display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<div>
  <span>Click me</span>
  <span>or me</span>
  <span>or me</span>
  <div>
    <span>I'm two levels in</span>
    <span>so am I</span>
  </div>
  <div id='catcher'>
    <span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span>me too</span>
  </div>
</div>
<!-- Using an old version because `live` was removed in v1.9 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</script>

我建议尽可能使用delegate 而不是live,这样您就可以更彻底地控制范围;使用delegate,您可以控制捕获冒泡事件的根元素(例如,live 基本上是delegate,使用文档根作为根)。此外,建议避免(在可能的情况下)让delegatelive 与非委托、非实时事件处理进行交互。


几年后,您不会使用livedelegate;您将使用on 的委托签名,但概念仍然相同:该事件与您调用on 的元素挂钩,但仅当后代匹配事件名称后给出的选择器时才触发:

jQuery(function($) {

  $(document).on('click', 'span', function() {
    display("<tt>live</tt> caught a click!");
  });

  $('#catcher').click(function() {
    display("Catcher caught a click and prevented <tt>live</tt> from seeing it.");
    return false;
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

});
<div>
  <span>Click me</span>
  <span>or me</span>
  <span>or me</span>
  <div>
    <span>I'm two levels in</span>
    <span>so am I</span>
  </div>
  <div id='catcher'>
    <span>I'm two levels in AND my parent interferes with <tt>live</tt></span>
    <span>me too</span>
  </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

【讨论】:

    【解决方案3】:

    在您设置事件时,与 .click 关联的所有对象都必须存在。

    示例:(在伪代码中)附加可以是 $("body").append() 例如

    append('<div id="foo" class="something">...</div>');
    $("div.something").click(function(){...});
    append('<div id="bar" class="something">...</div>');
    

    Click 对 foo 有效,但对 bar 无效

    示例2:

    append('<div id="foo" class="something">...</div>');
    $("div.something").live("click",function(){...});
    append('<div id="bar" class="something">...</div>');
    

    click 对 foo 和 bar 都有效

    使用 .live('click'... 您可以在创建事件后动态添加更多对象,并且点击事件仍然有效。

    【讨论】:

    • 酷,这就是我使用 .live 的原因。我很想知道反过来是否有任何好处。
    • 不会投反对票,但这并不是真正被问到的问题。不过很好的解释。
    • 实际上这正好回答了导致我来到这里的问题。我现在明白为什么我的 .click 失败并且我的 .live("click",...) 有效 - 我有一个排序问题,我没有创建 .click 在调用它时需要的元素,因此我的事件没有被调用,而 .live 不关心排序,因此可以工作。
    【解决方案4】:

    动态生成代码时需要“live”。 看看下面的例子:

    $("#div1").find('button').click(function() {
        $('<button />')
         .text('BUTTON')
         .appendTo('#div1')
    })
    $("#div2").find('button').live("click", function() {
        $('<button />')
         .text('BUTTON')
         .appendTo('#div2')
    })
    button {
      margin: 5px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
    <div id="div1">
      <button>Click</button>
    </div>
    <div id="div2">
      <button>Live</button>
    </div>

    没有“live”,点击事件仅在您点击第一个按钮时发生,“live”点击事件也发生在动态生成的按钮上

    【讨论】:

    • 很棒的例子来解释!
    【解决方案5】:

    如果您不动态添加元素,请始终使用click

    live 通过向文档根目录添加事件侦听器并侦听冒泡事件来工作。另一种方法是delegate,它的工作原理相同,但将事件处理程序绑定到指定元素。
    这样,事件就不必冒泡整个 DOM 并且更早地被捕获。

    【讨论】:

      【解决方案6】:
      如果在初始页面加载后添加元素,则使用

      .live()。假设您有一个在页面加载后由 AJAX 调用添加的按钮。使用 .click() 将无法访问这个新按钮,因此您必须使用 .live('click')

      【讨论】:

      • .live() - 不推荐使用的版本:1.7,删除:1.9!使用.on()
      【解决方案7】:

      据我了解,主要区别在于 live() 会密切关注与您正在处理的选择器匹配的新 DOM 元素,而 click()(或 bind('click'))附加事件挂钩并完成了。

      鉴于您的很多代码都是异步加载的,使用 live() 将使您的生活更轻松。如果您不确切知道要加载的代码,但您知道要收听什么样的元素,那么使用此功能非常有意义。

      就性能提升而言,使用 live() 的一种替代方法是实现 AJAX 回调函数来重新绑定事件挂钩。

      var ajaxCallback = function(){
       $('*').unbind('click');
       $('.something').bind('click', someFunction);
       $('.somethingElse').bind('click', someOtherFunction);
      }
      

      您需要正确跟踪您的事件挂钩,并确保此函数重新绑定正确的事件。

      附言Ajax 方法 .get()、.post()、.load() 和 .ajax() 都允许您指定回调函数。

      【讨论】:

        【解决方案8】:

        由于“实时”将处理与当前选择器匹配的未来元素的事件,您可以选择点击,因为您不希望发生这种情况 - 您只想处理当前选定的元素。

        另外,我怀疑(虽然没有证据)使用“点击”而不是“实时”会产生轻微的效率。

        【讨论】:

          【解决方案9】:

          如果您需要简化代码,那么在大多数情况下,live 会更好。 如果您需要获得最佳性能,那么委托总是比现场更好。绑定(点击)与委托不是那么简单的问题(如果你有很多类似的项目,那么委托会更好)。

          【讨论】:

            【解决方案10】:

            记住“live”的使用是针对“jQuery 1.3”或更高版本的

            在“jQuery 1.4.3”或更高版本中使用“委托”

            并且“启用”使用“jQuery 1.7 +”或更高版本

            $( selector ).live( events, data, handler ); // jQuery 1.3+
            $( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
            $( document ).on( events, selector, data, handler ); // jQuery 1.7+
            

            从 jQuery 1.7 开始,.live() 方法已被弃用。

            查看http://api.jquery.com/live/

            问候, 费尔南多

            【讨论】:

            • ...而现在,从 jQuery 版本 1.9.x 开始,.live 方法已被删除。
            【解决方案11】:

            除了T.J. Crowders answer,我还添加了一些处理程序——包括新的.on(...) 处理程序到sn-p,这样你就可以看到哪些事件被隐藏了,哪些没有。

            我还发现.live() 不仅已被弃用,而且自 jQuery 1.9.x 以来已被删除。但是其他的,即
            .click.delegate/.undelegate.on/.off
            还在。

            另外注意有更多关于这个话题的讨论here on Stackoverflow

            如果你需要修复依赖 .live 的遗留代码,但你需要使用新版本的 jQuery (> 1.8.3),你可以使用这个 sn-p 修复它:

            // fix if legacy code uses .live, but you want to user newer jQuery library
            if (!$.fn.live) {
                // in this case .live does not exist, emulate .live by calling .on
                $.fn.live = function(events, handler) {
                  $(this).on(events, null, {}, handler);
                };
            }
            

            下面的 sn-p 是 TJ 脚本的扩展,它的目的是您可以立即自己尝试如果绑定多个处理程序会发生什么 - 所以请运行 sn-p 并单击以下文字:

            jQuery(function($) {
            
              // .live connects function with all spans
              $('span').live('click', function() {
                display("<tt>live</tt> caught a click!");
              });
            
              // --- catcher1 events ---
            
              // .click connects function with id='catcher1'
              $('#catcher1').click(function() {
                display("Click Catcher1 caught a click and prevented <tt>live</tt> from seeing it.");
                return false;
              });
            
              // --- catcher2 events ---
            
              // .click connects function with id='catcher2'
              $('#catcher2').click(function() {
                display("Click Catcher2 caught a click and prevented <tt>live</tt>, <tt>delegate</tt> and <tt>on</tt> from seeing it.");
                return false;
              });
            
              // .delegate connects function with id='catcher2'
              $(document).delegate('#catcher2', 'click', function() {
                display("Delegate Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
                return false;
              });
            
              // .on connects function with id='catcher2'
              $(document).on('click', '#catcher2', {}, function() {
                display("On Catcher2 caught a click and prevented <tt>live</tt> from seeing it.");
                return false;
              });
            
              // --- catcher3 events ---
            
              // .delegate connects function with id='catcher3'
              $(document).delegate('#catcher3', 'click', function() {
                display("Delegate Catcher3 caught a click and <tt>live</tt> and <tt>on</tt> can see it.");
                return false;
              });
            
              // .on connects function with id='catcher3'
              $(document).on('click', '#catcher3', {}, function() {
                display("On Catcher3 caught a click and and <tt>live</tt> and <tt>delegate</tt> can see it.");
                return false;
              });
            
              function display(msg) {
                $("<p>").html(msg).appendTo(document.body);
              }
            
            });
            <!-- with JQuery 1.8.3 it still works, but .live was removed since 1.9.0 -->
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
            </script>
            
            <style>
            span.frame {
                line-height: 170%; border-style: groove;
            }
            </style>
            
            <div>
              <span class="frame">Click me</span>
              <span class="frame">or me</span>
              <span class="frame">or me</span>
              <div>
                <span class="frame">I'm two levels in</span>
                <span class="frame">so am I</span>
              </div>
              <div id='catcher1'>
                <span class="frame">#1 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
                <span class="frame">me too</span>
              </div>
              <div id='catcher2'>
                <span class="frame">#2 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
                <span class="frame">me too</span>
              </div>
              <div id='catcher3'>
                <span class="frame">#3 - I'm two levels in AND my parent interferes with <tt>live</tt></span>
                <span class="frame">me too</span>
              </div>
            </div>

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多