【问题标题】:Select element unless it has an ancestor of a given class using just a selector选择元素,除非它仅使用选择器具有给定类的祖先
【发布时间】:2012-12-02 14:28:38
【问题描述】:

假设我有以下 HTML:

<div class="foo">
  <ul>
    <li>One</li>
    <li>Two</li>
  </ul>
</div> <!-- not originally here -->
<div class="bar">
  <ul>
    <li>Three</li>
    <li>Four</li>
  </ul>
</div>

我想选择所有li 元素不是foo 的元素的后代。我知道我可以用一个花哨的filter function 来做到这一点,但我想知道我是否可以只用一个选择器来做到这一点。首先我尝试了:

$(":not(.foo) li")

不幸的是,这不起作用,因为 liother 没有样式的祖先(在本例中为 ul)。以下似乎有效;

$(":not(.foo) :not(.foo) li")

换句话说,选择所有li 元素,这些元素没有具有类foo 或具有自己的类foo 的祖先。也许这是使用选择器的最佳/唯一方法,但我对 :not 选择器的重复并不感到兴奋。有什么更好的想法吗?

fiddle

【问题讨论】:

  • 这里的问题是:not(.foo) li 并不意味着“li 没有具有foo 类的祖先”。这意味着“li 的祖先没有foo 类”。差别看似细微,但实际上差别很大。
  • 没错。第二个表示li,它的祖先没有foo 类,并且没有自己的foo 祖先。我认为这是正确的结果,但到达那里的方式非常丑陋且令人不满意。

标签: jquery jquery-selectors


【解决方案1】:

我觉得这个解决方案看起来更好一些,但是关于速度差异的 API cmets 存在一些争议。

$("li").not(".foo li")

fiddle

【讨论】:

    【解决方案2】:

    你可以这样做

    $("li").not('.foo li')
    

    http://jsfiddle.net/y7s54/

    $("li:not(.foo li)")
    

    http://jsfiddle.net/QpCYY/

    选择所有没有类 foo 的祖先的 li

    【讨论】:

    • 这对我来说似乎是最好的答案,除非有人有相反的论点。
    • 我同意;这比我的 ul > li 答案要好。
    【解决方案3】:

    您可以使用上下文和下面的选择器来完成,

    $('li', $('div:not(.foo)'))
    

    LIve Demo

    $('li', $('div:not(.foo)')).each(function(){
        alert($(this).text());
    });​
    

    【讨论】:

    • +1 - 这避免了将 :not 与非简单选择器一起使用的怪异现象,并且可能比使用纯 CSS 进行查找更有效。
    • 实际上,除非您从:not() 中删除内引号,否则它不会更有效 - 没有必要,并且是无效的CSS,因此不会更快。见stackoverflow.com/questions/12475595/…
    • 如果div.foo 的任何祖先是div:not(.foo),这也会失败。
    【解决方案4】:

    试试li:not(.foo &gt; ul &gt; li);选择所有 lis 减去父级 .foo 两级以上的那些。

    【讨论】:

    • 我不知道为什么 OP:not 选择器的重复并不感到兴奋。你写的在 JQuery/Sizzle 中可能没问题,但是根据 CSS3 规范,:not 选择器只能包含simple selectors
    • @kojiro:可能是因为以符合 CSS3 的doesn't actually work 的方式重复了:not 选择器。使用不依赖标记性质的:not 执行此操作的唯一方法是以jQuery/Sizzle 提供的非标准方式使用它,如this answer中所述。
    • @BoltClock 它工作得很好。这不是您所期望的。
    • 这对我来说不够灵活,因为在实际用例中,foo 类可以在层次结构中的多个级别出现。在我的示例中,它是ul 的直接父级,但不一定是,这就是为什么我要处理任意祖先具有该类的情况。
    【解决方案5】:

    这个怎么样:

    $("li:not(.foo > li)")
    

    如果这不起作用,文档中的 cmets 非常有用:

    http://api.jquery.com/not-selector/

    【讨论】:

    • 这是正确的基本想法,但不起作用,因为 lis 不是 .foo 的直接后代。
    猜你喜欢
    • 1970-01-01
    • 2019-06-10
    • 2021-10-11
    • 2015-02-27
    • 2019-06-22
    • 2015-01-25
    • 2023-03-26
    • 1970-01-01
    • 2011-04-06
    相关资源
    最近更新 更多