私はいくつかのDOM要素を繰り返したいのですが、私はこれをやっています:
document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
//do stuff
});
しかし、エラーが発生します:document.getElementsByClassName( "myclass")。forEachは関数ではありません
Firefox 3を使用しているので、getElementsByClassName
とArray.forEach
の両方が存在することがわかります。これはうまくいきます:
[2, 5, 9].forEach( function(element, index, array) {
//do stuff
});
getElementsByClassName
の結果は配列ですか?そうでない場合、それは何ですか?
いいえ。 DOM4で指定 のように、 HTMLCollection
です(少なくとも最新のブラウザでは、古いブラウザは NodeList
を返しました)。
最近のすべてのブラウザー(他のほとんどIE <= 8)では、配列のforEach
メソッドを呼び出して、要素のリスト(HTMLCollection
またはNodeList
)をthis
値として渡すことができます。
var els = document.getElementsByClassName("myclass");
Array.prototype.forEach.call(els, function(el) {
// Do stuff here
console.log(el.tagName);
});
// Or
[].forEach.call(els, function (el) {...});
ES6を使用できるという幸せな立場にいる場合(つまり、Internet Explorerを安全に無視できるか、ES5トランスパイラーを使用している場合)、 Array.from
を使用できます。
Array.from(els).forEach((el) => {
// Do stuff here
console.log(el.tagName);
});
Array.from
を使用して、コレクションを配列に変換できます。これは、Array.prototype.forEach.call
よりもずっとクリーンです。
Array.from(document.getElementsByClassName("myclass")).forEach(
function(element, index, array) {
// do stuff
}
);
Array.from
をサポートしない古いブラウザでは、Babelのようなものを使用する必要があります。
ES6では、次の構文も追加されます。
[...document.getElementsByClassName("myclass")].forEach(
(element, index, array) => {
// do stuff
}
);
...
を使用したレストデストラクチュアリングは、配列自体だけでなく、配列に似たすべてのオブジェクトで機能します。その後、古き良き配列構文を使用して、値から配列を構築します。
代替関数querySelectorAll
(これはgetElementsByClassName
を廃止します)がネイティブにforEach
を持つコレクションを返しますが、map
やfilter
のような他のメソッドが欠落しているため、この構文は依然として有用です:
[...document.querySelectorAll(".myclass")].map(
(element, index, array) => {
// do stuff
}
);
[...document.querySelectorAll(".myclass")].map(element => element.innerHTML);
または NodeList :を返すquerySelectorAll
を使用できます
document.querySelectorAll('.myclass').forEach(...)
最新のブラウザー(Edgeを含むがIEを除く)でサポート:
querySelectorAllを使用できます
NodeList.prototype.forEach()
編集:HTMLの新しいバージョンでは戻り値の型が変更されていますが(Tim Downの更新された回答を参照)、以下のコードは引き続き機能します。
他の人が言ったように、それはNodeListです。以下に、試すことができる完全で実用的な例を示します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
function findTheOddOnes()
{
var theOddOnes = document.getElementsByClassName("odd");
for(var i=0; i<theOddOnes.length; i++)
{
alert(theOddOnes[i].innerHTML);
}
}
</script>
</head>
<body>
<h1>getElementsByClassName Test</h1>
<p class="odd">This is an odd para.</p>
<p>This is an even para.</p>
<p class="odd">This one is also odd.</p>
<p>This one is not odd.</p>
<form>
<input type="button" value="Find the odd ones..." onclick="findTheOddOnes()">
</form>
</body>
</html>
これは、Win 7のIE 9、FF 5、Safari 5、およびChrome 12で機能します。
GetElementsByClassNameの結果は配列ですか?
いや
そうでない場合、それは何ですか?
複数の要素を返すすべてのDOMメソッドと同様に、それはNodeListです。 https://developer.mozilla.org/en/DOM/document.getElementsByClassName を参照してください
getElementsByClassName()
の結果は配列ではなく、配列のようなオブジェクトです。具体的には、HTMLCollection
と呼ばれます。NodeList
と混同しないでください( 独自のforEach()
メソッドがあります )。
ES2015で、まだ言及されていないArray.prototype.forEach()
で使用するために配列のようなオブジェクトを変換する簡単な方法の1つは、スプレッド演算子または スプレッド構文 を使用することです:
const elementsArray = document.getElementsByClassName('myclass');
[...elementsArray].forEach((element, index, array) => {
// do something
});
既に述べたように、getElementsByClassName
は HTMLCollection を返します。
[Exposed=Window]
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
getter Element? namedItem(DOMString name);
};
以前は、一部のブラウザは代わりに NodeList を返しました。
[Exposed=Window]
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
iterable<Node>;
};
DOM4はNodeListsを反復可能として定義するようになったため、違いは重要です。
Web IDL draftによると、
反復可能と宣言されたインターフェースを実装するオブジェクトは、値のシーケンスを取得するために反復されることをサポートします。
注:ECMAScript言語バインディングでは、反復可能なインターフェイスには「エントリ」、「forEach」、「キー」、「値」、および- @@ iterator そのプロパティ インターフェイスプロトタイプオブジェクト 。
つまり、forEach
を使用する場合は、 querySelectorAll
のようなNodeListを返すDOMメソッドを使用できます。
document.querySelectorAll(".myclass").forEach(function(element, index, array) {
// do stuff
});
これはまだ広くサポートされていないことに注意してください。 Node.childNodesのforEachメソッド? も参照してください。
Array
を返すのではなく、 NodeList を返します。
これはより安全な方法です。
var elements = document.getElementsByClassName("myclass");
for (var i = 0; i < elements.length; i++) myFunction(elements[i]);
getElementsByClassName
は、最新のブラウザーではHTMLCollectionを返します。
これは引数に似た配列のようなオブジェクトであり、これはfor...of
ループによって反復可能です MDN docがそれについて言っていることを参照してください:
for ... ofステートメントは、反復可能なオブジェクトを反復処理するループを作成します組み込みのString、Array、Array-likeオブジェクト(例、引数またはNodeList)、TypedArray、Map、Set、およびユーザー定義のイテラブル。オブジェクトの個別のプロパティの値に対して実行されるステートメントを使用して、カスタム反復フックを呼び出します。
例
for (let element of getElementsByClassName("classname")){
element.style.display="none";
}