2008-09-05 8 views
8

次のコードのように、DOMオブジェクトの配列を逆にすることで問題が発生する可能性があります。DOMオブジェクトのJavascriptコレクション - なぜArray.reverse()を使用して逆転できないのですか?

var imagesArr = new Array(); 
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img"); 
imagesArr.reverse(); 

Firefox 3では、reverse()メソッドを呼び出すと、スクリプトは実行を停止し、 Web Developer Toolbar:

imagesArr.reverse is not a function 
imagesArr forループで imagesArr変数を繰り返し、 imagesArr[i]などの要素にアクセスできるため、 reverse()メソッドを呼び出すときに配列として認識されないのはなぜですか?

答えて

13

getElementsByTag nameは実際にNodeList構造体を返すためです。構文上の利便性のために類似した配列のような配列を持っていますが、配列はではなくです。たとえば、エントリのセットは実際には常に動的に更新されています。myDivHolderIdの下に新しいimgタグを追加すると自動的にimagesArrに表示されます。

http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177を参照してください。

1

あなたの最初の行は、変数への代入を強制しないので、javascriptは逆の働きをします。 imagesArrは型Array()ではなく、getElementsByTagName( "img")の戻り値の型が何であっても型Arrayです。この場合、Firefox 3のHtmlCollectionです。

このオブジェクトの唯一のメソッドはインデクサーと長さです。逆に作業するには、逆方向に繰り返します。

8

getElementsByTag()は、配列の代わりにNodeListを返します。 NodeListを配列に変換することはできますが、配列は別のオブジェクトになりますので、逆にしてもDOMノードの位置には影響しません。

var listNodes = document.getElementById("myDivHolderId").getElementsByTagName("img"); 
var arrayNodes = Array.slice.call(listNodes, 0); 
arrayNodes.reverse(); 

位置を変更するには、DOMノードを削除して、それらをすべて正しい位置に再度追加する必要があります。

Array.prototype.slice.call(arrayLike, 0)は、配列のような配列を配列に変換するのに最適ですが、JavaScriptライブラリを使用している場合は、実際にはより良い/より速い方法で実行できます。たとえば、jQueryは$.makeArray(arrayLike)です。

また、NodeListの上で直接アレイ方式を使用することができます。

Array.prototype.reverse.call(listNodes); 
+2

いいえ、そのインデックスが書き込み不能であるため、メソッドを 'NodeList'で直接呼び出すことはできません。エラーが発生するはずです。 – Bergi

+1

ES6: 'arrayNodes = Array.from(listNodes)' – cregox

1

getElementsByTag()配列の代わりのNodeListを返します。 NodeListを配列に変換して逆にする必要があります。

var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse(); 
2

私はこの質問は古いです知っているが、私はそれがW3Cの定義を変更して、ここで古いされている回答の一部として明確化のビットを必要だと思い、これらの方法の結果として、戻り値getElementsByTagName()getElementsByClassName()

これらの方法は、HTMLCollectionではなく、NodeListのオブジェクトを返します。

それが唯一の要素で構成し、テキストやコメントノードを除くなのでタイプHTMLCollectionのオブジェクトを返すプロパティchildrenの差のようなものだ、それはテキストのような他のノードタイプを含むことができるので、型NodeListのオブジェクトを返すchildNodesコメントも同様です。

注:私はここに接線に行くと、それは排他的に文書と他には何の要素のノード上で動作しますので、querySelectorAll()方法は、現在NodeListなくHTMLCollectionを返す理由について洞察力の私の欠如を表明したいです。

おそらく、他のノードタイプの潜在的なカバレッジと将来的に関係しており、実際に分かっている将来の証明ソリューションに向かうでしょうか? :)

編集:querySelectorAll()の場合はNodeListを選択し、HTMLCollectionを選択しないというこの決定の背後には根拠があると思います。

HTMLCollectionが独占的かつ完全に生存しているため、この方法ではこのライブ機能が必要ないため、経済的かつ効率的にその目的を最も良く果たすためにNodeListの実装を決定しました。