102

要素の内部テキストを変更するための短いスクリプトを作成していましたが、メソッドがないこと<abbr>がわかりました。から継承していないことは知っていますが、持っていると便利な方法ではないでしょうか。に追加できない、私が気付いていない特定の実装の問題はありますか?nodelistforEachnodelistArrayforEachforEachnodelist

注:DojoとjQueryはどちらもforEach、ノードリストに何らかの形で含まれていることを認識しています。制限のためどちらも使用できません。

4

10 に答える 10

105

NodeListには、すべての主要なブラウザーでforEach()が含まれるようになりました

MDNのnodeListforEach()を参照してください。

元の回答

これらの回答はいずれも、 NodeListがArrayから継承しない理由forEachを説明していないため、残りのすべてを継承できます。

答えはこのes-discussスレッドにあります。要するに、それはウェブを壊します:

問題は、インスタンスがArray.prototype.concatと組み合わせた配列であることを意味するinstanceofを誤って想定したコードでした。

Googleのクロージャーライブラリにバグがあり、これが原因でほとんどすべてのGoogleのアプリが失敗しました。これが見つかるとすぐにライブラリが更新されましたが、concatと組み合わせて同じ誤った仮定を行うコードがまだ存在する可能性があります。

つまり、いくつかのコードは次のようなことをしました

if (x instanceof Array) {
  otherArray.concat(x);
} else {
  doSomethingElseWith(x);
}

ただし、concat「実際の」配列(Arrayのinstanceではない)は他のオブジェクトとは異なる方法で処理されます。

[1, 2, 3].concat([4, 5, 6]) // [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat(4) // [1, 2, 3, 4]

つまり、上記のコードはxNodeListの場合に壊れました。これは、パスをたどる前はdoSomethingElseWith(x)パスをたどったのに対し、その後はパスをたどったためです。これは、実際の配列ではないため、otherArray.concat(x)奇妙なことをしました。x

しばらくの間Elements、Arrayの実際のサブクラスであり、「新しいNodeList」として使用されるクラスの提案がありました。ただし、技術的および仕様に関連するさまざまな理由でまだ実装できなかったため、少なくとも現時点では、これはDOM標準から削除されました。

于 2014-11-19T18:25:16.593 に答える
62

できるよ

Array.prototype.forEach.call (nodeList, function (node) {

    // Your code here.

} );
于 2014-03-14T22:07:34.883 に答える
34

ノードの新しい配列を作成することを検討できます。

  var nodeList = document.getElementsByTagName('div'),

      nodes = Array.prototype.slice.call(nodeList,0); 

  // nodes is an array now.
  nodes.forEach(function(node){ 

       // do your stuff here.  

  });

注:これは、ここで作成しているノード参照のリスト/配列であり、重複するノードはありません。

  nodes[0] === nodeList[0] // will be true
于 2013-03-13T22:58:38.340 に答える
20

決して言わないでください、それは2016年であり、NodeListオブジェクトはforEach最新のchrome(v52.0.2743.116)でメソッドを実装しています。

他のブラウザはまだこれをサポートしていないため(FF 49でテスト済み)、本番環境で使用するには時期尚早ですが、これはまもなく標準化されると思います。

于 2016-08-24T21:25:09.793 に答える
19

つまり、そのメソッドを実装するための設計上の矛盾です。

MDNから:

ノードリストでforEachまたはマップを使用できないのはなぜですか?

NodeListは配列と非常によく似ており、Array.prototypeメソッドを使用したくなるでしょう。ただし、これは不可能です。

JavaScriptには、プロトタイプに基づく継承メカニズムがあります。配列インスタンスは、プロトタイプチェーンが次のようになっているため、配列メソッド(forEachやmapなど)を継承します。

myArray --> Array.prototype --> Object.prototype --> null(オブジェクトのプロトタイプチェーンは、Object.getPrototypeOfを数回呼び出すことで取得できます)

forEach、mapなどは、Array.prototypeオブジェクトの独自のプロパティです。

配列とは異なり、NodeListプロトタイプチェーンは次のようになります。

myNodeList --> NodeList.prototype --> Object.prototype --> null

NodeList.prototypeにはitemメソッドが含まれていますが、Array.prototypeメソッドは含まれていないため、NodeListsでは使用できません。

出典:https ://developer.mozilla.org/en-US/docs/DOM/NodeList( 「forEachまたはNodeListのマップを使用できないのはなぜですか?」までスクロールダウンしてください)

于 2012-11-17T19:10:05.657 に答える
15

NodeListでforEachを使用する場合は、その関数を配列からコピーするだけです。

NodeList.prototype.forEach = Array.prototype.forEach;

これで、Arrayの場合と同じように使用できます。

document.querySelectorAll('td').forEach(function(o){
   o.innerHTML = 'text';
});
于 2014-05-31T18:30:24.273 に答える
9

ES2015では、nodeListのメソッドを使用できるforEachようになりました。

document.querySelectorAll('abbr').forEach( el => console.log(el));

MDNリンクを参照してください

ただし、HTMLコレクションまたはその他の配列のようなオブジェクトを使用する場合は、es2015でメソッドを使用できますArray.from()。このメソッドは、配列のようなオブジェクトまたは反復可能なオブジェクト(nodeList、HTMLコレクション、文字列などを含む)を受け取り、新しい配列インスタンスを返します。次のように使用できます。

const elements = document.getElementsByTagName('abbr');
Array.from(elements).forEach( el => console.log(el));

メソッドはシマブルなのでArray.from()、次のようなes5コードで使用できます

var elements = document.getElementsByTagName('abbr');
Array.from(elements).forEach( function(el) {
    console.log(el);
});

詳細については、MDNページを参照してください。

現在のブラウザサポートを確認するには。

また

別のes2015の方法は、スプレッド演算子を使用することです。

[...document.querySelectorAll('abbr')].forEach( el => console.log(el));

MDNスプレッド演算子

SpreadOperator-ブラウザサポート

于 2018-06-15T05:31:17.103 に答える
1

私の解決策:

//foreach for nodeList
NodeList.prototype.forEach = Array.prototype.forEach;
//foreach for HTML collection(getElementsByClassName etc.)
HTMLCollection.prototype.forEach = Array.prototype.forEach;
于 2017-11-12T19:14:46.287 に答える
0

NodeListはDOMAPIの一部です。JavaScriptにも適用されるECMAScriptバインディングを見てください。http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html。nodeListと、ノードを返すための読み取り専用の長さプロパティおよびitem(index)関数。

答えは、繰り返す必要があるということです。代替手段はありません。Foreachは機能しません。私はJavaDOMAPIバインディングを使用していますが、同じ問題があります。

于 2012-11-17T19:14:27.310 に答える
0

NodeList.forEach仕様のMDNを確認してください。

NodeList.forEach(function(item, index, nodeList) {
    // code block here
});

IEでは、akuhnの答えを使用してください:

[].forEach.call(NodeList, function(item, index, array) {
    // code block here
});
于 2018-10-01T23:04:52.953 に答える