4

次のマークアップのセレクターを見つけようとしています。blockquote を含むノードを除くすべてのノードが必要です。は<blockquote>常に、タグ<div>の直接の子になる a の直接の子になります。<body>

HTML の例:

<ul>
    <!-- Lots of HTML -->
</ul>
<div>
    <p>
        <!-- Lots of other HTML -->
    </p>
</div>
<div>
    <blockquote>Some text I don't care about</blockquote>
</div>

期待される結果:

<ul><!-- Lots of HTML --></ul>
<div><p><!-- Lots of other HTML --></p></div>

試みられたセレクター:

document.querySelectorAll("body > :not(div > blockquote)")

上記を試しましたが、セレクター内に直接の子セレクターを配置できません:not()。これは、失敗した試みのフィドルです。

私は現在 jQuery を使用しておらず、jQuery を使用することもできません。

4

1 に答える 1

4

これをネイティブに行うことはできません。現在のセレクタ仕様では、要素を子でフィルタリングする方法はありません。(ただし、これは将来のセレクタ仕様に含まれる可能性があります。)

したがって、自分でフィルタリングを行う必要があります。これは特に難しいことではありません。1 つの方法は、関連するすべての要素を選択してから、不要なものを除外することです。

Array.prototype.slice.call(document.querySelectorAll("body > *"))
    .filter(function(el) {
        return !el.querySelector(':scope > blockquote');
    })

(jsフィドル)

これにより、選択範囲が配列に変換され、Array#filterメソッドを使用して要素を含むすべてのblockquote要素が削除されます。

明らかに、これはネイティブ セレクターよりもパフォーマンスがはるかに劣りますが、現在の JS で必要なことを実行するには、これが唯一の方法です。

BoltClock が正しく指摘しているように、:scopeまだ正式な標準ではありません。Chromeがそれをサポートしているという事実によって、私は誤った安心感に陥りました。他のブラウザーはまだサポートしていません。任意のレベルの要素を含むトップ レベルの要素を除外する場合、blockquoteこれを行う最善の方法は次のとおりです。

return !el.querySelector('blockquote');
于 2013-11-11T16:13:26.510 に答える