2013-10-11 27 views
22

sto cercando di scorrere tutti gli elementi retruned da getElementsByTagName("input") utilizzando foreach. Qualche idea sul perché questo non funziona in FF, Chrome o IE?JavaScript: ciclo tra tutti gli elementi restituiti da getElementsByTagName

<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> 
+0

Razionale perché nessuno 'forEach': http://stackoverflow.com/questions/13433799/why-doesnt-nodelist-have-foreach –

risposta

48

è necessario convertire il nodelist per array con questo:

<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> 

o utilizzare per ciclo.

for(i = 0;i < input.length; i++) 
{ 
    ShowResults(input[i].value); 
} 

e cambiare ShowResults funzionano per:

function ShowResults(value) { 
    alert(value); 
} 
+0

stavo cercando di usare questo: http://msdn.microsoft. it/it/us/library/ie/ff679980% 28v = vs.94% 29.aspx – slayernoah

+0

vedere la mia modifica. 2 opzioni. – Dvir

+0

Ho> 1000 campi di input nascosti nel modulo. Quale opzione sarebbe la più efficiente in questo caso? – slayernoah

4

E 'becauseinput è la raccolta HTML. la raccolta html non ha per ogni utente.

si può facilmente conver ad array Array.prototype.slice

esempio:

function ShowResults(value, index, ar) { 
      alert(index); 
     } 
     var input = document.getElementsByTagName("input"); 
     alert(input.length); 
input = Array.prototype.slice.call(input) 
     input.forEach(ShowResults); 

http://jsfiddle.net/fPuKt/1/

5

Perché input non è un array, è HTMLCollection utilizzare un ciclo for sarebbe essere migliore.

E poiché HTMLCollection s sono oggetti array come si può callArray#forEach su di esso come questo

Array.prototype.forEach.call(input, ShowResults); 
2

HTMLCollections non ha gli stessi metodi come array. Puoi controllare questa cosa segnalando questo nella console javascript del tuo browser.

var elements = document.getElementsByClassName('some-class'); 
'forEach' in elements; 

e la console tornerà true se elements (in questo caso) ha un metodo chiamato forEach da chiamare.

3

La ragione, questo non funziona è perché 'getElementsByTagName' restituisce un array - come oggetto piuttosto che un matrice reale. Nel caso in cui non sono a conoscenza, ecco come ciascuno di essi assomigliano: -

var realArray = ['a', 'b', 'c']; 
var arrayLike = { 
    0: 'a', 
    1: 'b', 
    2: 'c', 
    length: 3 
}; 

Così, dal momento che gli oggetti Array simile ereditano da 'Object.prototype' invece di 'Array.prototype', questo significa che gli oggetti tipo array non possono accedere ai metodi di prototipo di array comuni come forEach(), push(), map(), filter() e slice().

Spero che questo aiuti!

+0

Questa è una spiegazione molto buona – Dvir

0

ho fatto questo:

HTMLCollection.prototype.map = Array.prototype.map; 

È ora possibile utilizzare mappa su ogni HTMLCollection.

document.getElementsByTagName("input").map(
    input => console.log(input) 
);