337

いくつかの 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配列ですか? そうでない場合、それは何ですか?

4

11 に答える 11

528

いいえ。 DOM4で指定されているように、これはHTMLCollection(少なくとも最新のブラウザーでは。古いブラウザーは a を返しましたNodeList) です。

最新のすべてのブラウザー (ほとんどすべての IE <= 8) では、Array のforEachメソッドを呼び出して、要素のリスト ( itHTMLCollectionまたは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);
});
于 2010-10-06T10:36:11.987 に答える
115

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持っているコレクションを返しますが、またはのような他のメソッドが欠落しているため、この構文は引き続き役立ちます。forEachmapfilter

[...document.querySelectorAll(".myclass")].map(
    (element, index, array) => {
        // do stuff
    }
);

[...document.querySelectorAll(".myclass")].map(element => element.innerHTML);
于 2016-06-21T10:22:38.993 に答える
44

または、NodeListquerySelectorAllを返す whichを使用できます。

document.querySelectorAll('.myclass').forEach(...)

最新のブラウザー (Edge を含むが IE を除く) でサポートされています:
querySelectorAll
NodeList.prototype.forEach()を使用できますか?

MDN: Document.querySelectorAll()

于 2017-05-13T08:10:20.330 に答える
15

編集:新しいバージョンの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>

これは、Win7のIE9、FF 5、Safari 5、およびChrome12で機能します。

于 2011-06-29T15:51:06.963 に答える
4

getElementsByClassName の結果は配列ですか?

いいえ

そうでない場合、それは何ですか?

複数の要素を返すすべての DOM メソッドと同様に、これは NodeList です。https: //developer.mozilla.org/en/DOM/document.getElementsByClassName を参照してください。

于 2010-10-06T10:31:03.370 に答える
3

すでに述べたように、次のように定義されたHTMLCollectiongetElementsByClassNameを返します。

[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 はNodeListを iterable として定義するようになったため、この違いは重要です。

Web IDLドラフトによると、

反復可能であると宣言されたインターフェースを実装するオブジェクトは、一連の値を取得するために反復されることをサポートします。

注: ECMAScript 言語バインディングでは、反復可能なインターフェイスは、そのインターフェイス プロトタイプ オブジェクトに「エントリ」、「forEach」、「キー」、「値」、および @@iteratorプロパティを持ちます。

つまり、 を使用したい場合は、 のようにNodeListforEachを返す DOM メソッドを使用できます。querySelectorAll

document.querySelectorAll(".myclass").forEach(function(element, index, array) {
  // do stuff
});

これはまだ広くサポートされていないことに注意してください。Node.childNodes の forEach メソッドも参照してください。

于 2016-04-23T09:30:28.610 に答える
1

jsperf で作成したテストを次に示します: https://jsperf.com/vanillajs-loop-through-elements-of-class

Chrome と Firefox で最もパフォーマンスの高いバージョンは、document.getElementsByClassName と組み合わせた古き良き for ループです。

var elements = document.getElementsByClassName('testClass'), elLength = elements.length;
for (var i = 0; i < elLength; i++) {
    elements.item(i).textContent = 'Tested';
};

Safari では、このバリアントが勝者です。

var elements = document.querySelectorAll('.testClass');
elements.forEach((element) => {
    element.textContent = 'Tested';
});

すべてのブラウザで最もパフォーマンスの高いバリアントが必要な場合は、次のようになります。

var elements = document.getElementsByClassName('testClass');
Array.from(elements).map(
    (element) => {
        return element.textContent = 'Tested';
    }
);
于 2019-09-10T13:07:43.607 に答える
0

を返すのではなく、 NodeListArrayを返します。

于 2010-10-06T10:30:56.247 に答える