【问题标题】:Jquery - Bind delegate to all "a" tagsJquery - 将委托绑定到所有“a”标签
【发布时间】:2011-10-13 08:38:17
【问题描述】:

当您单击 div 中的链接时,我会尝试阻止 jq click()

HTML

<div id="all">
    <div id="test">
        <a href="http://google.de">google</a>
    </div>
</div>

JS

$('#test').click(function() { alert('only when i click the div');  });

$('a').click(function(e) {
    e.stopPropagation();
    e.preventDefault();
    $('body').append(e.target.href);
});       

这段代码很好用,但我的内容是动态的,所以我需要一个delegate() 解决方案。

下面的代码不起作用。但为什么?有什么问题?

$('#all').delegate("a", "click", function(e)
{
    e.stopPropagation();
    e.preventDefault();
    $('body').append(e.target.href);
});

示例
http://jsfiddle.net/Lf3hL/13/

【问题讨论】:

标签: jquery event-delegation


【解决方案1】:

stopPropagation 不适用于委托 - http://api.jquery.com/event.stopPropagation/

由于 .live() 方法在事件传播到文档顶部后处理事件,因此无法停止实时事件的传播。同样,由 .delegate() 处理的事件将传播到它们被委托的元素;在调用委托的事件处理程序时,绑定在 DOM 树中它下面的任何元素上的事件处理程序将已经执行。因此,这些处理程序可能会阻止委托处理程序通过调用 event.stopPropagation() 或返回 false 来触发。

现在,如果您将测试点击更改为使用委托并使用stopImmediatePropagation,它将起作用

$('#all').delegate('#test', 'click' ,function() {
    alert('only when i click on the div');
});    

$('#all').delegate("a", "click", function(e)
{
    e.stopImmediatePropagation();
    e.preventDefault();
    $('body').append(e.target.href);
}); 

http://jsfiddle.net/Lf3hL/14/

【讨论】:

    【解决方案2】:

    因为delegate() 的工作原理是让事件冒泡,然后在祖先元素上处理它们(在您的示例中为#all)。

    因此,由于事件已经冒泡,您无法阻止它们在源头传播(因为它们必须传播才能工作)。

    【讨论】:

      【解决方案3】:

      来自jQuery .delegate() doc

      因为 .live() 方法在事件传播到 文档的顶部,不可能停止传播 现场活动。同样,由 .delegate() 处理的事件将传播 分配给它们的元素;绑定的事件处理程序 DOM 树中它下面的任何元素都已经被执行 到调用委托的事件处理程序时。

      一种可能的解决方案是不在a 上附加事件处理程序,而是在#test 上附加,然后检查event.target

      我用这个方法updated your Fiddle

         $('#test').click(function(e) {
              if ($(e.target).is('a')) {
                  alert('link was clicked');
              }
              else {
                  alert('only when i click on the div');
              }
      
              e.preventDefault(); //just to cancel the link's default action
          });
      

      【讨论】:

        【解决方案4】:

        live 和 delegate 函数无法像“正常”事件那样处理 e.stopPropagation(); 调用。来自代表docs -

        因为 .live() 方法在事件传播到 文档的顶部,不可能停止传播 现场活动。同样,由 .delegate() 处理的事件将传播 到他们被委派的元素;绑定的事件处理程序 DOM 树中它下面的任何元素都已经被执行 到调用委托的事件处理程序时。这些处理程序, 因此,可能会阻止委托处理程序触发 调用 event.stopPropagation() 或返回 false。

        【讨论】:

          【解决方案5】:

          为什么不使用

          .live()
          

          功能?

           $('a').live('click', function() {
               // Live handler called.
           });
          

          这将为正文完全加载后添加的所有标签添加点击功能。

          【讨论】:

          • live()delegate() 本质上是相同的,只是在内部处理方式上有一些细微差别。
          猜你喜欢
          • 1970-01-01
          • 2017-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-06
          • 1970-01-01
          相关资源
          最近更新 更多