Jak iterować po wierszach i komórkach tabeli w JavaScript?

198

Jeśli mam tabelę HTML ... powiedz

<div id="myTabDiv">
<table name="mytab" id="mytab1">
  <tr> 
    <td>col1 Val1</td>
    <td>col2 Val2</td>
  </tr>
  <tr>
    <td>col1 Val3</td>
    <td>col2 Val4</td>
  </tr>
</table>
</div>

Jak mógłbym iterować przez wszystkie wiersze tabeli (zakładając, że liczba wierszy może się zmieniać za każdym razem, gdy sprawdzam) i pobierać wartości z każdej komórki w każdym wierszu z poziomu JavaScript?

GregH
źródło

Odpowiedzi:

321

Jeśli chcesz przejść przez każdy wiersz ( <tr>), znając / identyfikując wiersz ( <tr>) i iteracyjnie przechodzić przez każdą kolumnę ( <td>) każdego wiersza ( <tr>), to jest droga do zrobienia.

var table = document.getElementById("mytab1");
for (var i = 0, row; row = table.rows[i]; i++) {
   //iterate through rows
   //rows would be accessed using the "row" variable assigned in the for loop
   for (var j = 0, col; col = row.cells[j]; j++) {
     //iterate through columns
     //columns would be accessed using the "col" variable assigned in the for loop
   }  
}

Jeśli chcesz po prostu przejść przez komórki ( <td>), ignorując wiersz, w którym się znajdujesz, to jest droga do zrobienia.

var table = document.getElementById("mytab1");
for (var i = 0, cell; cell = table.cells[i]; i++) {
     //iterate through cells
     //cells would be accessed using the "cell" variable assigned in the for loop
}
John Hartsock
źródło
4
ex2, table.cells nie są kompatybilne z przeglądarkami
EricG,
8
@WilliamRemacle Opublikowałem tę odpowiedź prawie 4 lata temu .. IE 9 nie było wtedy nawet myślą!
John Hartsock,
@JohnHartsock Wiem, ale użyłem twojego rozwiązania i zorientowałem się, że nie działa na IE. To tylko komentarz, aby ostrzec innych ... i tak zagłosowałem za twoją odpowiedzią ;-)
William Remacle,
function itTable () {document.writeln ("itTable"); var table = document.getElementById ("mytab"); for (var i = 0, row; row = table.rows [i]; i ++) {document.writeln (i); for (var j = 0, col; col = row.cells [j]; j ++) {document.writeln (j); }} document.writeln ("end-itTable"); } Dlaczego ten kod nie miałby pozwolić mi przejść przez tabelę podobną do powyższej.
Doug Hauf
Dla tych (przychodzących tutaj przez Google) potrzebujących prostej i małej podkładki table.cells(aby załatać starszy kod / zorientowany na IE), zobacz moją odpowiedź na pytanie : Czy przeglądarka Firefox nie rozpoznaje table.cells?
GitaarLAB
68

Możesz rozważyć użycie jQuery. Dzięki jQuery jest to bardzo łatwe i może wyglądać tak:

$('#mytab1 tr').each(function(){
    $(this).find('td').each(function(){
        //do your stuff, you can use $(this) to get current cell
    })
})
dzida
źródło
3
Nie można używać jquery ... firma na to nie pozwala. Nie pytaj dlaczego.
GregH
21
To szalona polityka. Zawsze możesz po prostu skopiować i wkleić potrzebne funkcje z jQuery do własnego kodu aplikacji. Chyba że istnieje polityka zakazująca używania kodu innych osób w Internecie, ale wtedy nie byłoby cię tutaj.
Clinton
14
@Judy: Nie zgadzam się z „szaloną polityką”… jest wiele powodów, dla których nie należy używać jQuery
Bigjim
JQuery to coś, czego nie używałem od jakiegoś czasu i na pierwszy rzut oka wydaje się, że jest to coś skomplikowanego i niełatwego do obejścia. Ale myślę, że dzieje się tak tylko dlatego, że nie używałem go zbyt często.
Doug Hauf
5
Innym powodem, dla którego warto zabronić korzystania z JQuery, są osadzone witryny internetowe, np. Używam wbudowanego układu WiFi, który ma tylko 250Kb dla całej witryny. To ucisk ze wszystkimi obrazami takimi, jakie są.
Nick
17

var table=document.getElementById("mytab1");
var r=0; //start counting rows in table
while(row=table.rows[r++])
{
  var c=0; //start counting columns in row
  while(cell=row.cells[c++])
  {
    cell.innerHTML='[R'+r+'C'+c+']'; // do sth with cell
  }
}
<table id="mytab1">
  <tr>
    <td>A1</td><td>A2</td><td>A3</td>
  </tr>
  <tr>
    <td>B1</td><td>B2</td><td>B3</td>
  </tr>
  <tr>
    <td>C1</td><td>C2</td><td>C3</td>
  </tr>
</table>

W każdym przejściu, podczas gdy iterator r / c pętli zwiększa się, a nowy obiekt wiersza / komórki z kolekcji jest przypisywany do zmiennych wiersza / komórki. Gdy w kolekcji nie ma już wierszy / komórek, do zmiennej wiersza / komórki przypisywane jest wartości false i przechodzi przez iterację podczas gdy pętla zatrzymuje się (kończy działanie).

sbrbot
źródło
w poprzednim poście: while (cell = row [r] .cells [c ++] powinno być row.cells [c ++], row to bieżący obiekt, a przykład dla kodu sth: mycoldata = cell.innerHTML
fib Littul
12

Próbować

for (let row of mytab1.rows) 
{
    for(let cell of row.cells) 
    {
       let val = cell.innerText; // your code below
    }
}

Kamil Kiełczewski
źródło
2
czysty, powiedziałbym
Shobi
4

Lepsze rozwiązanie: użyj natywnego języka JavaScript Array.from()i przekonwertuj obiekt HTMLCollection na tablicę, po czym możesz użyć standardowych funkcji tablicowych.

var t = document.getElementById('mytab1');
if(t) {
    Array.from(t.rows).forEach((tr, row_ind) => {
        Array.from(tr.cells).forEach((cell, col_ind) => {
            console.log('Value at row/col [' + row_ind + ',' + col_ind + '] = ' + cell.textContent);
        });
    });
}

Możesz także odwołać się tr.rowIndexi cell.colIndexzamiast używać row_indi col_ind.

Wolę to podejście na szczyt najwyższej głosowało 2 odpowiedzi, ponieważ nie zaśmiecać swój kod ze zmiennych globalnych i, j, rowicol , a zatem zapewnia czystą, modułowy kod, który nie będzie miał żadnych skutków ubocznych (lub podnieść szarpie / ostrzeżenia kompilatora) ... bez innych bibliotek (np. jquery).

Jeśli potrzebujesz tego do działania w starej wersji (przed ES2015) Javascript, Array.frommożna to wypełnić.

mwag
źródło
3

To rozwiązanie działało idealnie dla mnie

var table = document.getElementById("myTable").rows;
var y;
for(i = 0; i < # of rows; i++)
{    for(j = 0; j < # of columns; j++)
     {
         y = table[i].cells;
         //do something with cells in a row
         y[j].innerHTML = "";
     }
}
Karim O.
źródło
Czy to w ogóle JavaScript? Ponieważ twoja pętla for wygląda trochę jak PHP.
aravk33
2
Wiele języków jest zaskakująco podobnych, jeśli wiesz, czego szukać. PHP użyłby znaku $ przed każdą zmienną, ale tak się nie dzieje. var jest również słowem kluczowym używanym przez JavaScript, a nie PHP, chociaż gdyby go dodali, mogłem go przegapić. - edit- gah bez wprowadzania nowej linii ... Jak mówię: Logika jest uniwersalna. Umiejętność transkrypcji tego na inne języki jest niezwykle przydatną umiejętnością, której nie jest trudno się nauczyć - jesteśmy istotami intelektualnymi o doskonałych zdolnościach dopasowywania wzorców. Zidentyfikuj zmiany między każdym językiem lub po prostu użyj definicji języka
leksera
3

Jeśli chcesz mieć funkcjonalny styl, taki jak ten:

    const table = document.getElementById("mytab1");
    const cells = table.rows.toArray()
                  .flatMap(row => row.cells.toArray())
                  .map(cell => cell.innerHTML); //["col1 Val1", "col2 Val2", "col1 Val3", "col2 Val4"]

Możesz zmodyfikować prototypowy obiekt HTMLCollection (pozwalając na użycie w sposób podobny do metod rozszerzających w C #) i osadzić w nim funkcję, która konwertuje kolekcję na tablicę, pozwalając na użycie funkcji wyższego rzędu z powyższym stylem (rodzaj stylu linq w DO#):

    Object.defineProperty(HTMLCollection.prototype, "toArray", {
        value: function toArray() {
            return Array.prototype.slice.call(this, 0);
        },
        writable: true,
        configurable: true
    });
l30_4l3X
źródło
Uncaught TypeError: Cannot read property 'toArray' of undefined -> Oto, co otrzymałem, kiedy wypróbowałem to rozwiązanie.
Vineela Thonupunuri
Dziwne. Spróbowałem ponownie i zadziałało. Nie mogłem jednak odtworzyć wskazanego przez Ciebie błędu. Może problemem jest przeglądarka. Testowałem przy użyciu Edge i IE i oba nie działały. Chrome, Firefox i Safari działały zgodnie z oczekiwaniami.
l30_4l3X
Ja też użyłem chromu.
Vineela Thonupunuri
U mnie to też działa. Object.definePropertyOczywiście musi iść przed resztą kodu, ale to działa. @Vineela Thonupunuri czy próbowałeś tego z kodem we właściwej kolejności?
FlippingBinary
1

Możesz użyć, .querySelectorAll()aby zaznaczyć wszystkie tdelementy, a następnie zapętlić je za pomocą .forEach(). Ich wartości można pobrać za pomocą .innerHTML:

const cells = document.querySelectorAll('td');
cells.forEach(function(cell) {
  console.log(cell.innerHTML);
})
<table name="mytab" id="mytab1">
  <tr> 
    <td>col1 Val1</td>
    <td>col2 Val2</td>
  </tr>
  <tr>
    <td>col1 Val3</td>
    <td>col2 Val4</td>
  </tr>
</table>

Jeśli chcesz wybrać tylko kolumny z określonego wiersza, możesz użyć pseudoklasy, :nth-child()aby wybrać konkretną tr, opcjonalnie w połączeniu z kombinatorem potomnym ( >) (co może być przydatne, jeśli masz tabelę w tabeli):

Wiek obsydianu
źródło
1

Używanie pojedynczej pętli for:

var table = document.getElementById('tableID');  
var count = table.rows.length;  
for(var i=0; i<count; i++) {    
    console.log(table.rows[i]);    
}
Foram Shah
źródło