【问题标题】:Prevent "bubbling"? [duplicate]防止“冒泡”? [复制]
【发布时间】:2011-08-26 17:18:53
【问题描述】:

我不确定这是否真的在冒泡,我会解释一下。

我有这个:

<div>
  <div>
    text here
  </div>
</div>

如何绑定点击事件,使其仅影响封闭的 div?如果我这样设置:

jQuery('div').bind('click', function() {
  jQuery(this).css('background','blue');
});

它使所有的 div 变成蓝色。如果我将 false 作为第三个参数(防止冒泡)添加到绑定函数,它什么也不做。

我该如何解决这个问题?

【问题讨论】:

  • 您是否在处理程序中尝试过stopPropagation()?如果没有环境捕获处理程序,那应该没问题,因为它可以防止事件到达任何环境冒泡处理程序。

标签: javascript jquery


【解决方案1】:

http://api.jquery.com/event.stopPropagation/

在hander中添加event.stopPropagation();

(不过,为嵌套的 DIV 分配一个 ID 或类可能会更好,这样您就可以确定它是唯一受影响的。)

【讨论】:

  • 如果您不确定自己有多少个 div,这是最好的方法
【解决方案2】:

您确实应该使用 ID 或类等标识符,但对于您的示例,您可以这样做:

jQuery('div > div').bind('click', function() {
  jQuery(this).css('background','blue');
});

...它将处理程序绑定到任何div,它是另一个div 的直接后代。

因此,要么针对要影响的元素进行初始选择,要么使用事件委托,将处理程序放置在祖先上,然后测试所需的元素。

委托示例: http://jsbin.com/ehemac/edit#javascript,live

<div id="container">
    <div class="outer">
      <div>
        text here
      </div>
    </div>
    <div class="outer">
      <div>
        text here
      </div>
    </div>
</div>
jQuery('#container').delegate( '.outer > div', 'click', function() {
    jQuery(this).css('background','blue');
});

这使用delegate()[docs] 方法将处理程序放置在ID 为#container 的祖先上。

.delegate() 的第一个参数是一个选择器。在#container 中单击的任何元素都会将该选择器与单击的元素进行比较。如果选择器匹配,将调用处理程序。

【讨论】:

  • 同样,如果您的 div 嵌套多于元素向下(例如&lt;div&gt;&lt;div&gt;&lt;div&gt;here&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;),这将不起作用,这将始终将背景设置在第二个元素上(jsbin.com/ehemac/2/edit)。
  • 来自我的回答:“你真的应该使用 ID 或类之类的标识符......但对于你的例子,你可以这样做......”。我没有说第一个代码示例适用于其他情况。我的主要答案是正确识别页面上的元素。
  • 这很有趣,通常我会回答对方的要求,而不是他们想要的。在这里,角色互换了。不过,我仍然坚信应该有一个元素 id 或类名来处理。
  • 是的,当我们看到一个问题说 “我有这个:” &lt;div&gt;&lt;div&gt;text here&lt;/div&gt;&lt;/div&gt; 时,它总是一个判断电话。在我的脑海里,我在想……真的吗?那是你的标记? ;)
  • 哈哈哈......我会请你喝一杯让我发笑
【解决方案3】:

http://jsfiddle.net/vol7ron/WzSkj/

以最后一个后代为目标


感谢Patrick DW:

jQuery('div:not(:has(div))').bind('click', function() {
   jQuery(this).css('background','blue');
});

这应该是您所需要的,因为它将查看所​​有 div 并找到那些没有子 div 的(因此,它们将是该元素类型的最后一个后代。您可以进一步过滤以确保如果您想排除那些独立的 divs,它们的父级是 div。



旧答案:

这绝不是一个完整/强大的插件。它仅作为如何定位链中最后一个元素的示例。查看修订历史以了解不使用插件的方法。如果您希望将其用于生产,则应对其进行修改。

插件:

(function($){
   $.fn.lastDescendant = function(el){
      var found = jQuery(el + ':first').siblings(el).andSelf();
      var prev, curr;
      var stack = this;
      for (var i=0,n=found.length; i<n; i++){
         curr = found.eq(i).find(el);
         while (curr.length){
            prev = curr;
            curr = curr.find(el);
         }         
         stack = stack.add(prev);
      }
      return stack;
   };
})( jQuery );

示例调用:

jQuery.fn.lastDescendant('div')
      .click(function(){
         jQuery(this).css("background","#09c");
      });

注意:

  • 这不会选择第一个(祖先)元素。如果您也想选择它,您可以将整个内容包装在一个新的div 中,然后执行上述操作。
  • 如果我要把它做成一个生产插件,我会检查参数,并允许你传入一个对象和一个起点(这样就不会选择兄弟姐妹)

【讨论】:

  • +1 为插件,虽然我们可以通过 $('div:not(:has(div))') 或更一般地 @ 987654330@ 定位任何没有嵌套元素的元素。
  • 不错的帕特里克,这会起作用,并且可能是一个更好的选择。我正在尝试更新它以传入字符串、对象和 jQuery 对象。
【解决方案4】:

要解决这个问题,只需使用更具体的选择器

jQuery('div > div').bind('click', function() {
  jQuery(this).css('background','blue');
})

【讨论】:

    【解决方案5】:

    解决此问题的最佳方法是为您的内部 div 提供可识别的特征,例如类,例如 &lt;div class="inner"&gt;&lt;/div&gt;

    或者,更改您的选择器:

    $('div > div').click(function() {
        $(this).css('background', 'blue');
    }
    

    【讨论】:

      【解决方案6】:

      尝试给内部 div 一个 id 标签并引用它...

      <div><div id=foo>text goes here</div></div>
      
      
      ...
      
      $('#foo').bind('click', function() {
        $(this).css('background','blue');
      });
      

      HTH -- 乔

      【讨论】:

        猜你喜欢
        • 2019-07-03
        • 2012-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多