web-dev-qa-db-ja.com

DOMコレクションで `querySelectorAll`を使用する子セレクター

ネストされた子リストを持つリストがあると仮定しましょう。

_<ul>
    <li></li>
    <li>
        <ul>
            <li></li>
            <li></li>
        </ul>
    </li>
    <li></li>
</ul>
_

そしてdocument.querySelectorAll()を使用して選択を行います:

_var ul = document.querySelectorAll("ul");
_

ulコレクションを使用して直接の子要素を取得するにはどうすればよいですか?

_ul.querySelectorAll("> li"); 
// Gives 'Error: An invalid or illegal string was specified'
_

ulが何らかの方法でキャッシュされていると仮定しましょう(そうでない場合、_ul > li_を直接実行することができます)。

JQueryではこれはうまくいきます:

_$("ul").find("> li");
_

ただし、ネイティブquerySelectorAllにはありません。解決策はありますか?

24
Husky

現在の要素に「ルート」されたセレクターを書き込む正しい方法は、 :scope

ul.querySelectorAll(":scope > li");

説明と堅牢なクロスブラウザソリューションについては、ここで私の回答を参照してください。 https://stackoverflow.com/a/21126966/117072

41
lazd

返されるulはNodeListであるため、jQueryコレクションのようにその内容を暗黙的にループしません。 ul[0].querySelectorAll()を使用するか、querySelector()ulを選択する必要があります。

その上、querySelectorAll()>を取得せず、現在のコンテキストから機能します。ただし、 lazd's answer (ただし、ブラウザーの互換性を確認してください)、またはこれらの回避策(ブラウザーの問題がないはず)を使用して機能させることができます...

[].filter.call(ul.querySelectorAll("li"), function(element){
     return element.parentNode == ul;
}); 

jsFiddle

これにより、liの子孫であるすべてのul要素が選択され、直接の子孫ではない要素が削除されます。

または、すべてのchildNodesを取得して、それらをフィルター処理することもできます...

[].filter.call(ul.childNodes, function(node) {
    return node.nodeType == 1 && node.tagName.toLowerCase() == 'li';
});

jsFiddle

13
alex

document.querySelectorAll()によって返されたNodeListを反復処理し、そのリストの各要素に対してelement.querySelectorAll()を呼び出す必要があります。

0
Alnitak