Obecnie pracuję nad projektem i muszę wypełnić inną kolumnę stołu, ponieważ używam .nextSibling, ale linie mogą być bardzo długie, jeśli celowo, powiedzmy czwartą kolumnę:

firstTd.nextSibling.nextSibling.nextSibling.nextSibling.innerHTML = "example";

Więc zastanawiałem się, czy nie było bardziej elegancki sposób na to, że nie wymaga pisania .nextSibling za każdym razem?

1
Angel 2 czerwiec 2018, 16:57

3 odpowiedzi

Najlepsza odpowiedź

Po prostu wykonaj mały pomocnik:

 const sibling = (el, count) => count ? sibling(el.nextSibling, count - 1) : el;

Który może być używany jako

sibling(firstTd, 5).innerHTML = "example";
3
Jonas Wilms 2 czerwiec 2018, 13:59

Zamiast polegać na konkretnej sytuacji, która jest z natury kruchy (co jeśli dodasz nową kolumnę?), Sugerowałbym, że twój cel td jakiś rodzaj znaku identyfikacyjnego, jak nazwa klasy lub {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{} Atrybut x1}}. Następnie użyłbyś:

tr.querySelector(".the-class").innerHTML = "example";

Jeśli nie masz przydatnych tr, możesz uzyskać z firstTd.parentNode.

Naturalnie, ponieważ querySelector nie wygląda tylko na dzieci, ale wszystkie potomkowie, będziesz chciał tego zaplanować.

Przykład na żywo:

// In a real situation I'd use a delegated handler, but the goal here is to
// show that the same code works regardless of the starting point
document.querySelectorAll("td:not(.x)").forEach(el => {
  el.addEventListener("click", function() {
    this.parentNode.querySelector(".ex").innerHTML = Math.random();
  });
});
table {
  border-collapse: collapse;
  border: 1px solid #aaa;
}
td {
  border: 1px solid #aaa;
  padding: 4px;
}
<table>
  <tbody>
    <tr>
      <td>Click me</td>
      <td>Or me</td>
      <td>Or me</td>
      <td class="ex"></td>
    </tr>
  </tbody>
</table>

Alternatywnie, daj sobie funkcję "Znajdź mój następny pasujący rodzeństwo", który akceptuje selektor:

const findNext = (el, selector) => {
    let sib = el.nextElementSibling;
    while (sib && !sib.matches(selector)) {
        sib = sib.nextElementSibling;
    }
    return sib;
};

Następnie

findNext(firstTd, ".the-class").innerHTML = "example";

Przykład na żywo:

const findNext = (el, selector) => {
    let sib = el.nextElementSibling;
    while (sib && !sib.matches(selector)) {
        sib = sib.nextElementSibling;
    }
    return sib;
};

// In a real situation I'd use a delegated handler, but the goal here is to
// show that the same code works regardless of the starting point
document.querySelectorAll("td:not(.x)").forEach(el => {
  el.addEventListener("click", function() {
    findNext(this, ".ex").innerHTML = Math.random();
  });
});
table {
  border-collapse: collapse;
  border: 1px solid #aaa;
}
td {
  border: 1px solid #aaa;
  padding: 4px;
}
<table>
  <tbody>
    <tr>
      <td>Click me</td>
      <td>Or me</td>
      <td>Or me</td>
      <td class="ex"></td>
    </tr>
  </tbody>
</table>
3
T.J. Crowder 2 czerwiec 2018, 14:13

Dostęp do rzędów stołowych i komórek można uzyskać przez Indeks:

table1.rows[2].cells[2].innerText = 42
<table id=table1>
  <tr> <th> A </th> <th> B </th> <th> C </th> </tr>
  <tr> <td> 1 </td> <td> 2 </td> <td> 3 </td> </tr>
  <tr> <td> 4 </td> <td> 5 </td> <td> 6 </td> </tr>
</table>
1
Slai 2 czerwiec 2018, 14:16