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

时间:2016-11-29 09:30:02

标签: javascript html-table row visibility

我试图通过javascript显示/隐藏HTML表格中的行。选中复选框应显示其他行,取消选中它将隐藏它们。

<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>元素的style属性?

(我首先尝试将有问题的行放在<div>中。这不会产生任何错误,但行始终可见,并且Firebug中不存在<div>,因此它是可能不允许那里。)

3 个答案:

答案 0 :(得分:2)

  • 首先,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>

答案 1 :(得分:2)

使用for ... in循环时遇到问题。这不是你应该为数组或类似数组对象选择的循环,它们只应该用于迭代对象键和属性,因为它们在阵列上的速度非常慢更快的方法。

for ... in也修改了状态,所以你应该有可用的例如。

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

您正在引用循环内外部范围的thing

我认为这是一种更好的方法,因为当你进行迭代时,你没有处理任何外部状态。

&#13;
&#13;
const rows = Array.from(document.getElementsByClassName('switchMe'))
const cbox = document.getElementById('cbox')

function changeHandler() {
  rows.forEach(row => {
    row.style.display = cbox.checked ? 'block' : 'none'
  })
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

如下所示,实现您尝试执行的操作而不创建函数的一种方法就像其他答案一样。

然而,这并不意味着你应该这样做。在实践中肯定使用显示的其他答案。

&#13;
&#13;
<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>
&#13;
&#13;
&#13;