どうすればdocument.querySelectorAllの結果をノードに変換できますか?

投稿者: Anonymous

document.quetySeletorallで同じクラス名を持つ要素の集合を受け取ってそれに対してDOM操作を行いたいです。
しかし、document.querySelectorAllはいわば配列もどきみたいな形で結果を受け取るようなのでTopがDOMノードではないので使えないとエラー出てきます。

配列であればそのまま使えますが、Topは配列そのものではない、つまりDOMノードになっていないのでこのままでは利用できずにDOMノードに変換する必要があると聞きます。

Q1 どんな処理をするとTopをDOMノードに変換できるのでしょうか?

Q2 このTopは配列とはどう違うのでしょうか?

var Top = document.querySelectorAll('.top');

document.querySelector('#js').addEventListener('click', function() {
    Array.prototype.forEach.call(Top,function(x){
        x.parentNode.insertBefore(Top, x);
    });
});

解決

querySelectorAll() の戻り値は NodeList という型です。

https://dom.spec.whatwg.org/#interface-parentnode

[NewObject] NodeList querySelectorAll(DOMString selectors);

https://dom.spec.whatwg.org/#nodelist

interface NodeList {
  getter Node? item(unsigned long index);
  readonly attribute unsigned long length;
  iterable<Node>;
};

おっしゃる通り配列ではありません。length プロパティと index getter があるので、配列のように for でループして各要素にアクセスすることができます。

var top = document.querySelectorAll('.top');
for (var i = 0; i < top.length; ++i) {
  var node = top[i]; // これが Node 型
  ...
}

for (var node of document.querySelectorAll('.top')) {
  ... // node が Node 型
}

また、最近のブラウザなら forEach もそのまま使えます。

document.querySelectorAll('.top').forEach(function(node) {
  ... // node が Node 型
});

Node ではないので、NodeList をそのまま insertBefore() の引数にはできません。

もし '.top' にマッチする要素が1つだけと決まっているなら、querySelectorAll('.top')[0] とするか querySelector('.top')
ノードが手に入ります。

回答者: Anonymous

Leave a Reply

Your email address will not be published.