【问题标题】:jQuery select descendants, including the parentjQuery选择后代,包括父母
【发布时间】:2010-09-26 18:14:02
【问题描述】:

考虑以下 HTML:

<div class="foo" id="obj">
   I should be changed red
   <div class="bar" style="color:black;">
      I should not be changed red.
      <div class="foo">I should be changed red.</div>
   </div>
</div>

给定一个 DOM 元素 obj 和一个表达式,我该如何选择任何子元素以及可能的 obj?我正在寻找类似于“选择后代”的内容,但如果它与表达式匹配,也包括父代。

var obj = $("#obj")[0];

//wrong, may include siblings of 'obj'
$(".foo", $(obj).parent()).css("color", "red");

//wrong -- excludes 'obj'
$(".foo", obj).css("color", "red");

//correct way, but it's annoying
var matches = $(".foo", obj);
if ($(obj).is(".foo")) matches = matches.add(obj);
matches.css("color", "red");

有没有更优雅的解决方案?

【问题讨论】:

  • +1:好问题。今天刚好碰到这种情况。已采纳 Andrew 的回答和您的评论,并添加了一个简单的 jQuery findAndSelf 扩展,正如您建议的那样供大家使用。干杯。

标签: jquery jquery-selectors parent descendant


【解决方案1】:

如果我理解正确的话:

$(currentDiv).contents().addBack('.foo').css('color','red');

为了清楚起见,我将“div”重命名为“currentDiv”。这会选择当前元素及其包含的所有元素,然后过滤掉没有类 foo 的元素并将样式应用于其余部分,即具有类 foo 的元素。

编辑轻微优化

$(currentDiv).find('.foo').addBack('.foo').css('color','red');

编辑

此答案已更新以包含更新的 jQuery 方法。原来是

$(currentDiv).find('.foo').andSelf().filter('.foo').css('color','red');

1.8 之前的 jQuery 仍然需要它

【讨论】:

  • 啊,谢谢...“andSelf()”是我所缺少的。不幸的是,这种方法效率低下......所有的孩子都被找到,然后所有的孩子都被遍历过滤,而不仅仅是一次通过。
  • 这仍然比addback(JQ 1.8 以后)的效率略低,因为它在后代上第二次运行filter,即使它们都已经匹配了。
  • Note: This function has been deprecated and is now an alias for .addBack(), which should be used with jQuery 1.8 and later
【解决方案2】:

jQuery 1.8 引入了.addBack(),它接受一个选择器,支持 .andSelf()。因此 tvanfosson 的代码变得更加高效

$(currentDiv).find(".foo").addBack(".foo").css("color", "red");

如果你没有那个,我认为

$(currentDiv).find(".foo").add(currentDiv.filter(".foo")).css("color", "red");

即使不是很漂亮,也会很有效。

【讨论】:

  • 绝对是 jQuery 1.8 的首选。已将您的建议添加为下面的 jQuery findAndSelf 扩展方法。使用addBack 结果非常干净,感谢您。干杯:)
【解决方案3】:

Andrew's 答案非常有用,也是所有答案中最有效的(从 jQuery 1.8 开始),所以我按照Sam 的建议做了,并将其变成了一个简单的 jQuery 扩展方法供大家使用:

扩展代码:

jQuery.fn.findAndSelf = function (selector){
    return this.find(selector).addBack(selector);
};

这样使用:

$(function(){
    $('#obj').findAndSelf('.foo').css('color', 'red');
});

JSFiddle:http://jsfiddle.net/BfEwK/

完全感谢 Andrew 建议 addBack() 作为最佳选择(截至目前)。相应地支持他并建议每个人都这样做。

【讨论】:

  • 似乎没有人注意到这一点。你应该得到一个拥抱和一个高五。
  • @TheDembinski:感谢接受拥抱(但我不做高 5):)
【解决方案4】:

除非有更好的解决方案,否则我创建了一个新函数并使用它来代替 $:

var _$ = function(expr, parent){ 
   return $(parent).is(expr) ? $(expr, parent).add(parent) : $(expr, parent); 
}

【讨论】:

  • 我想我会使用它并扩展 jQuery 使其成为“findAndSelf()”或类似的东西。
  • 已将您的 findAndSelf 建议(好名字)应用到 Andrew 的答案中,并张贴供所有人剪切和粘贴。
【解决方案5】:

如果我没记错的话,你能不能不做以下事情?

$("#obj").css("color", "red").find(".foo").css("color", "red");

找到预期的对象/元素应用 CSS,然后使用所述选择器找到所述对象/元素内的所有对象/元素,然后也将 CSS 应用到 is?

【讨论】:

  • 没有。他们只希望选择父元素如果它也有.foo,但你的只是包含它。
【解决方案6】:

选择所有子元素的更短的方法,包括父元素:

$('*', '#parent').addBack();

等同于:

$('#parent').find('*').addBack();

$('*', '#parent').addBack().css('border', '1px solid #f00');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
  <span>Child</span>
  <span>Another child</span>
</div>

当然,您可以将通用选择器更改为所需的元素。

$('.foo', '#parent').addBack();

$('#parent').find('.foo').addBack();

【讨论】:

    【解决方案7】:

    这不是你想要的吗(除非我误解了......)

    $(document).ready(function(){
        $("div.foo").css("color", "red");
    });
    

    【讨论】:

    • 这将“有效”,只是因为在示例中它们恰好都是divs。问题是如何包含初始元素(如果匹配)以及任何后代(也匹配)。如果在#obj 之外还有更多.foos 怎么办?它们也将被包括在内(这不是所需的行为)。
    【解决方案8】:
     $('div.foo, div.foo > *').css('color','red');
    

    主要思想是你可以用逗号分隔不同的规则来匹配。就像在 css 中一样。据我所知,here 的所有内容都由 jquery 支持,并且可以通过逗号分隔“或”。

    【讨论】:

    • 这将选择文档中的所有 .foo 以及 .foo 的所有子级
    • 对...我以为你是这个意思。
    • 啊,对不起,我已经澄清了这个问题。
    • 好吧,现在答案是:foo 类的所有 div 及其所有子级。满意吗?
    • 答案是“[some object] 的所有子节点匹配 [expression] 以及 [some object] 如果匹配 [expression]”
    猜你喜欢
    • 2011-03-31
    • 2014-05-15
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多