如何更改 Javascript 中 table 行的可见性?

How to change the visibility of a table row in Javascript?

我正在尝试 javascript HTML table 中的 show/hide 行。选中该复选框将显示额外的行,取消选中将隐藏它们。

<html><body><form><table>
    <tr>
        <td> This row is always visible. </td>
    </tr>
    <tr>
        <td>
            <input id="cbox" type="checkbox" onchange="for(e in document.getElementsByClassName('switchMe')) e.style.display = document.getElementById('cbox').checked ? 'block' : 'none';"/>
            <label for="cbox">Show more …</label>
        </td>
    </tr>
    <tr class="switchMe" style="display: none; ">
        <td> This row will be shown after the user clicks the check box. </td>
    </tr>
    <tr class="switchMe" style="display: none; ">
        <td> This row too. </td>
    </tr>
    <tr>
        <td> This row is always visible. </td>
    </tr>
</table></form></body></html>

但是,没有任何反应,我在控制台中收到 e.style is undefined 错误。如何正确访问 <tr> 元素的样式属性?

(我首先尝试将有问题的行放在 <div> 中。这不会给出任何错误,但这些行始终可见,并且 [=25] 中不存在 <div> =], 所以那里可能不允许。)

  • 首先,for..in 非常适合迭代对象而不是 NodeList。
  • 其次,在 html 中更改事件侦听器是一种不好的做法。任何人都可以使用开发工具更改标记并操纵系统的行为。你应该使用 .addEventListener
  • 第三,定义一个没有var的变量将使其成为全局变量。

for..in

的输出

var el_list = document.querySelectorAll('.switchMe');
for(var el in el_list){
  console.log(el)
}
<form>
  <table>
    <tr>
      <td>This row is always visible.</td>
    </tr>
    <tr>
      <td>
        <input id="cbox" type="checkbox" />
        <label for="cbox">Show more …</label>
      </td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row will be shown after the user clicks the check box.</td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row too.</td>
    </tr>
    <tr>
      <td>This row is always visible.</td>
    </tr>
  </table>
</form>

样本

JSFiddle

document.querySelector('#cbox').addEventListener('click', function(e) {
  var switchEl = document.querySelectorAll('.switchMe');
  for (var i = 0; i < switchEl.length; i++)
    switchEl[i].style.display = this.checked ? 'block' : 'none';
});
<form>
  <table>
    <tr>
      <td>This row is always visible.</td>
    </tr>
    <tr>
      <td>
        <input id="cbox" type="checkbox" />
        <label for="cbox">Show more …</label>
      </td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row will be shown after the user clicks the check box.</td>
    </tr>
    <tr class="switchMe" style="display: none; ">
      <td>This row too.</td>
    </tr>
    <tr>
      <td>This row is always visible.</td>
    </tr>
  </table>
</form>

您在使用 for...in 循环时遇到问题。这实际上不是您应该为数组或(类似数组的)对象选择的循环,它们应该只用于遍历对象键和属性,因为它们在数组上非常慢,那里有更快的方法可用。

for...in 也会修改状态,因此您应该有可用的状态,例如。

const thing = { one: 1, two: 2 }
for (key in thing) {
  console.log(thing[key])
}

您正在从循环内的外部作用域引用 thing

我认为这是一种更好的方法,因为您在进行迭代时无需处理任何外部状态。

const rows = Array.from(document.getElementsByClassName('switchMe'))
const cbox = document.getElementById('cbox')

function changeHandler() {
  rows.forEach(row => {
    row.style.display = cbox.checked ? 'block' : 'none'
  })
}
<html>

<body>
  <form>
    <table>
      <tr>
        <td>This row is always visible.</td>
      </tr>
      <tr>
        <td>
          <input id="cbox" type="checkbox" onchange="changeHandler()" />
          <label for="cbox">Show more …</label>
        </td>
      </tr>
      <tr class="switchMe" style="display: none; ">
        <td>This row will be shown after the user clicks the check box.</td>
      </tr>
      <tr class="switchMe" style="display: none; ">
        <td>This row too.</td>
      </tr>
      <tr>
        <td>This row is always visible.</td>
      </tr>
    </table>
  </form>
</body>

</html>

在不像其他答案那样创建函数的情况下实现您尝试做的事情的一种方法是如下所示。

但这并不意味着您应该这样做。在实践中 绝对 使用显示的其他答案。

<html>

<body>
  <form>
    <table>
      <tr>
        <td>This row is always visible.</td>
      </tr>
      <tr>
        <td>
          <input id="cbox" type="checkbox" onchange="var arr = document.getElementsByClassName('switchMe'); for(var i = 0; i < arr.length; i++) arr[i].style.display = document.getElementById('cbox').checked ? 'block' : 'none';" />
          <label for="cbox">Show more …</label>
        </td>
      </tr>
      <tr class="switchMe" style="display: none; ">
        <td>This row will be shown after the user clicks the check box.</td>
      </tr>
      <tr class="switchMe" style="display: none; ">
        <td>This row too.</td>
      </tr>
      <tr>
        <td>This row is always visible.</td>
      </tr>
    </table>
  </form>
</body>

</html>