【问题标题】:The selector works similarly to /deep/选择器的工作方式类似于 /deep/
【发布时间】:2018-10-02 07:57:28
【问题描述】:

我需要一个选择器来选择 X 类中的所有内容,除了 Y 类对象。也许我的问题会解决选择器 /deep/ 但它不受支持。

我有一个页面结构:

<div class="x">
    <div class="y"></div>
    <div>
        <div>
            <div>
                <span class="y"></span>
                <div>1</div>
                <label class="y"></label>
                <div>
                    <span class="y"></span>
                    <p>2</p>
                </div>
            </div>
        </div>
    </div>
    <div>
        <span class="y"></span>
        <div>3</div>
    </div>
    <div>
        <div>4</div>
        <div>
            <div>5</div>
        </div>
    </div>
    <div>6</div>
</div>

我需要一个选择器或 xpath 来选择:

<div>1</div>
<p>2</p>
<div>3</div>
<div>
    <div>4</div>
    <div>
        <div>5</div>
    </div>
</div>
<div>6</div>

我需要一个通用的解决方案。

【问题讨论】:

  • 如果任何人想帮助你,也许可以举一两个我们需要的例子。
  • 感谢正确的注释,我添加了一个例子。

标签: css xpath css-selectors


【解决方案1】:

这个 XPath,

//div[@class="x"]//*[not(@class="y") and not(.//*[@class="y"])]

将选择所有没有@class="y" 属性并且没有任何具有@class="y" 元素的后代的div[@class="x"] 后代,

<div>1</div>
<p>2</p>
<div>3</div>
<div>
        <div>4</div>
        <div>
            <div>5</div>
        </div>
    </div>
<div>4</div>
<div>
            <div>5</div>
        </div>
<div>5</div>
<div>6</div>

如果我们假设您的示例不完整,则与您的示例匹配。

【讨论】:

  • 谢谢,但这就像指出我写的元素一样。
  • 不客气。如果有帮助,请accept这个答案,并提出一个关于 CSS 的新问题。谢谢。
【解决方案2】:

:has(...) 伪类,但出于性能原因,它不能在样式表中使用。这个限制被嵌入到所有浏览器的 CSS 引擎中,因为每次渲染网页时,它们都会遍历整个 DOM 并应用与现有元素匹配的选择器(因此还没有查看它们的子元素)。相反,这个伪类通常用于专用的选择器引擎,例如 Sizzle(以其开发/用于 jQuery 而闻名)。

如果你想使用那个伪类,那么你可以试试:not(.y):not(:has(.y))。然后为了获得最高的结果,我只选择不匹配的元素的子元素(即:has(.y) &gt; :not(:has(.y)))。如果具有“y”类的元素有子元素,则需要注意一个问题。处理这个问题的唯一方法是重复指定:not(.y) 的伪类,以达到你想要去的尽可能多的层次(我没有这样做)。这是一个活生生的例子:

// The selector
var elements = $('.x > :not(.y):not(:has(.y)), .x :has(.y) > :not(.y):not(:has(.y))');

// Format the HTML
var html = elements.map(function(){
    var dirty = this.outerHTML;

    // Get leading whitespace to remove
    var leading = (dirty.match(/\r?\n *(?= {4})/) || ['\r\n'])[0];
    // Create regex to replace whitespace
    var leading = new RegExp(leading.replace(/\r/,'\\r?').replace(/\n/,'\\n'), 'g');
    // Show newlines, whitespace in HTML
    var cleaned = $('<div>').text(dirty).html().replace(leading, '<br/>').replace(/ /g, '&nbsp;');

    return cleaned;
}).toArray();

// Add the HTML to the page
var results = $('#results');
for(var i=0; i<html.length; i++) {
    results.append($('<li>').html(html[i]));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<!-- Sample HTML -->
<div class="x">
    <div class="y"></div>
    <div>
        <div>
            <div>
                <span class="y"></span>
                <div>1</div>
                <label class="y"></label>
                <div>
                    <span class="y"></span>
                    <p>2</p>
                </div>
            </div>
        </div>
    </div>
    <div>
        <span class="y"></span>
        <div>3</div>
    </div>
    <div>
        <div>4</div>
        <div>
            <div>5</div>
        </div>
    </div>
    <div>6</div>
</div>

<h3>Results</h3>
<ol id="results" class="y"></ol>

【讨论】:

  • 感谢您的贡献,但我想要一个通用的解决方案,以 CSS 选择器本身的形式保存。这里我需要知道结构的深度来构建一个适当复杂的选择器,这不是重点。
  • @KamilTomaszJarmusik 选择器是这个:.x &gt; :not(.y):not(:has(.y)), .x :has(.y) &gt; :not(.y):not(:has(.y))。如果您说具有 .y 类的元素将有孩子,这就是您在深度方面所引用的内容,那么请更新您的问题以显示此类。现在,这完全符合您的要求。
  • “我需要一个通用的解决方案。”我需要一个通用选择器来解决问题,而无需知道结构有多深而没有 javascip
猜你喜欢
  • 2015-01-19
  • 1970-01-01
  • 2019-03-02
  • 2011-11-16
  • 2021-09-23
  • 1970-01-01
  • 2020-06-10
  • 2021-11-05
  • 1970-01-01
相关资源
最近更新 更多