ForEachを使用してgetElementsByTagName("input")
から返されたすべての要素をループしようとしています。 FF、ChromeまたはIEでこれが機能しない理由はありますか?
<html>
<head>
</head>
<body>
<input type="text" value="" />
<input type="text" value="" />
<script>
function ShowResults(value, index, ar) {
alert(index);
}
var input = document.getElementsByTagName("input");
alert(input.length);
input.forEach(ShowResults);
</script>
</body>
</html>
これでノードリストを配列に変換する必要があります:
<html>
<head>
</head>
<body>
<input type="text" value="" />
<input type="text" value="" />
<script>
function ShowResults(value, index, ar) {
alert(index);
}
var input = document.getElementsByTagName("input");
var inputList = Array.prototype.slice.call(input);
alert(inputList.length);
inputList.forEach(ShowResults);
</script>
</body>
</html>
またはforループを使用します。
for(i = 0;i < input.length; i++)
{
ShowResults(input[i].value);
}
showResults関数を次のように変更します。
function ShowResults(value) {
alert(value);
}
イェーイ、ES6:
const children = [...parent.getElementsByTagName('tag')];
children.forEach((child) => { /* Do something; */ });
input
は配列ではないため、 HTMLCollection
for
ループを使用することをお勧めします。
HTMLCollection
sは配列のようなオブジェクトなので、 call
Array#forEach
このように
Array.prototype.forEach.call(input, ShowResults);
入力がhtmlコレクションであるためです。 htmlコレクションにはforEachがありません。
array.prototype.sliceによって簡単に配列に変換できます
例:
function ShowResults(value, index, ar) {
alert(index);
}
var input = document.getElementsByTagName("input");
alert(input.length);
input = Array.prototype.slice.call(input)
input.forEach(ShowResults);
その理由は、「getElementsByTagName」が実際の配列ではなくオブジェクトのような配列を返すためです。あなたが気付いていない場合、ここにそれらの両方がどのように見えるかです:-
var realArray = ['a', 'b', 'c'];
var arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
したがって、配列のようなオブジェクトは「Array.prototype」ではなく「Object.prototype」から継承するため、これは配列のようなオブジェクトが共通の配列プロトタイプにアクセスできないことを意味しますforEach()、Push()、map()、filter()、およびslice()などのメソッド。
お役に立てば幸いです!
getElementsByTagName
は、HTMLCollection
メソッドを持たないforEach
を返します。ただし、中間配列を作成するforEach
withoutで反復できる単純な調整があります:use querySelectorAll
代わりに。 querySelectorAll
はNodeList
を返し、最新のブラウザにはNodeList.prototype.forEach
メソッドがあります:
document.querySelectorAll('input')
.forEach((input) => {
console.log(input.value);
});
<input type="text" value="foo">
<input type="text" value="bar">
querySelectorAll
を使用するもう1つの利点は、カンマ区切りクエリ文字列を受け入れることです。これは、タグ名よりもはるかに柔軟で正確です。たとえば、クエリ文字列
.container1 > span, .container2 > span
container1
またはcontainer2
のクラスを持つ要素の子であるspan
sのみに一致します。
document.querySelectorAll('.container1 > span, .container2 > span')
.forEach((span) => {
span.classList.add('highlight');
});
.highlight {
background-color: yellow;
}
<div class="container1">
<span>foo</span>
<span>bar</span>
</div>
<div class="container2">
<span>baz</span>
</div>
<div class="container3">
<span>buzz</span>
</div>
メソッドが組み込まれていない古代のブラウザでNodeList.prototype.forEach
を使用する場合は、単に polyfill を追加します。次のスニペットはIE11で動作します。
// Polyfill:
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
// Main code:
document.querySelectorAll('.container1 > span, .container2 > span')
.forEach(function(span) {
span.classList.add('highlight');
});
.highlight {
background-color: yellow;
}
<div class="container1">
<span>foo</span>
<span>bar</span>
</div>
<div class="container2">
<span>baz</span>
</div>
<div class="container3">
<span>buzz</span>
</div>
HTMLCollectionsには配列と同じメソッドはありません。ブラウザのjavascriptコンソールでこれを傾けることで、このことを確認できます。
var elements = document.getElementsByClassName('some-class');
'forEach' in elements;
そして、true
(この場合)が呼び出すelements
というメソッドを持っている場合、コンソールはforEach
を返します。
ES6では、spread
演算子を使用して、HtmlCollectionを配列に変換できます。この質問を参照してください Javascript要素のコレクションでArray.forEachを使用できないのはなぜですか?
input = [...input]
input.forEach(ShowResults)
これは私がしました:
HTMLCollection.prototype.map = Array.prototype.map;
すべてのHTMLCollection
でマップを使用できるようになりました。
document.getElementsByTagName("input").map(
input => console.log(input)
);