【问题标题】:Element in div gets removed as a child but can't be used againdiv 中的元素作为孩子被删除但不能再次使用
【发布时间】:2019-01-16 02:38:16
【问题描述】:

我试图在 div 中显示一个隐藏的表格,然后使用 display: none/block 切换再次隐藏它。有用。但是,一旦我切换到 display: none 来隐藏它,我就无法让它再次出现。

HTML: HTML 有一个 id = tableContainer 的空 div。

在它旁边,我有一个表格,上面有每个单元格中动物科的名称,还有一个按钮。单击该按钮时,它会从该特定单元格中获取动物家族的名称,找到具有该名称的动物物种表,然后从 display: none 切换到 display:block 并在 div 内显示它。然后,如果我再次单击该按钮,它会将显示切换回显示:无。

当我单击另一个单元格中的按钮时,它会清除 div 并显示新表格。

一切都好。

但是,如果我单击以前使用的按钮,则现在已消失的表不再可用。

我在 removeChild 和所有这些方面都经历了各种各样的麻烦,但没有运气。我目前正在使用 innerHTML 来清除 div,但我缺少类名的内容。

控制台错误说:tabletest2.html:523 Uncaught TypeError: Cannot read property 'classList' of null 在切换 (tabletest2.html:523) 在 HTMLButtonElement.onclick (tabletest2.html:72)

所以,在我看来,它不能再切换了,因为表现在不再存在,或者我可能错了,因为我没有删除子元素(我认为)。

     <body>
<table>
  <tbody>
    <tr>
      <td>Genus</td>
      <td>Benthobatis
        <button onclick="toggle(this, parentNode.firstChild)">Click me</button></td>
    </tr>
    <tr>
      <td>Genus</td>
      <td>Diplobatis
        <button onclick="toggle(this, parentNode.firstChild)">Click me</button></td>
    </tr>
  </tbody>
</table>
<!-- <======== div display container here ================>-->  
<div id="tableContainer"></div>

     <table id="Benthobatis" class="hide">
    <tbody>
      <tr>
        <th>Genus</th>
        <th>Benthobatis</th>
      </tr>
      <tr>
        <td>Benthobatis kreffti</td>
        <td>Brazilian Blind Electric Ray</td>
      </tr>
    </tbody>
  </table>
    <!-- <==================================-->
     <table id="Diplobatis" class="hide">
    <tbody>
      <tr>
        <th>Genus</th>
        <th> Diplobatis </th>
      </tr>
      <tr>
        <td>Diplobatis colombiensis</td>
        <td>Colombian electric ray</td>
      </tr>
    </tbody>
  </table>
    </body>

    <script>
function toggle(ele, tableName) {
var myTableDisplayDiv = document.getElementById("tableContainer").childNodes;
    if (myTableDisplayDiv.length != 0) {
        document.getElementById("tableContainer").innerHTML = "";
    }
        var myTableName = tableName.textContent;
        var myTable = document.getElementById(myTableName);
        myTable.classList.toggle("hide");
        document.getElementById("tableContainer").appendChild(
        document.getElementById(myTableName)        
            );
    }   

      </script>


    <style>
          .hide  {
display: none;
    }

【问题讨论】:

  • #tableContainer 是哪个元素?我假设比&lt;table&gt;高一级?
  • tableContainer 是我放置表格的空 div。所以它是 html:body:tableContainer。这些表都与 tableContainer 处于同一级别/层次结构,但在按钮单击时切换到 div。

标签: javascript


【解决方案1】:

说明

“如果我只更改显示选项而不删除子节点,为什么我的表会被删除?”。

这会破坏内部的一切:

document.getElementById("tableContainer").innerHTML = "";

选中的表移动到#tableContainer

document.getElementById("tableContainer").appendChild(
    document.getElementById(myTableName)

所以在点击三下后就什么都没有了。当然,这是如果表格可以正确识别,但它不是。 .parentNode.firstChild.textContent 引用丢失了,因为 this 引用的是全局上下文而不是按钮。这就是不鼓励使用事件属性(以及其他各种原因)的原因。虽然不像前面提到的那样是关键问题,但您应该认真地对名称进行一些更改:

tableName myTableName myTable myTableDisplayDiv tableContainer

我很确定这种命名方案不利于调试。


解决方案

  • 在将表放入 #tableContainer 并销毁之前,请使用 .cloneNode() 制作副本。

  • 删除onclick 属性并使用onclick 属性(如在演示中)或.addEventListener()

  • 注册两个按钮的祖先元素(即tbody),从那里可以单击并使用event.target轻松隔离和引用两个按钮。

  • 现在可以引用单击的按钮 (event.target):

var tableName = event.target.parentNode.firstChild.textContent
  • 然后表格终于可以被引用了:
var table = document.getElementById(tableName)

演示

document.querySelector('tbody').onclick = toggle;

function toggle(event) {

  var clicked = event.target;

  if (clicked.tagName === 'BUTTON') {

    var genus = clicked.parentNode.firstChild.textContent;

    var table = document.querySelector('#' + genus);

    var display = document.getElementById("display");

    display.innerHTML = "";

    var clone = table.cloneNode(true);

    display.appendChild(clone);

    clone.classList.toggle('hide');
  }
}
.hide {
  display: none;
}
<table>
  <tbody>
    <tr>
      <td>Genus</td>
      <td>Benthobatis
        <button>Click me</button></td>
    </tr>
    <tr>
      <td>Genus</td>
      <td>Diplobatis
        <button>Click me</button></td>
    </tr>
  </tbody>
</table>
<!-- <======== div display container here ================>-->
<div id="display"></div>

<table id="Benthobatis" class="hide">
  <tbody>
    <tr>
      <th>Genus</th>
      <th>Benthobatis</th>
    </tr>
    <tr>
      <td>Benthobatis kreffti</td>
      <td>Brazilian Blind Electric Ray</td>
    </tr>
  </tbody>
</table>
<!-- <==================================-->
<table id="Diplobatis" class="hide">
  <tbody>
    <tr>
      <th>Genus</th>
      <th> Diplobatis </th>
    </tr>
    <tr>
      <td>Diplobatis colombiensis</td>
      <td>Colombian electric ray</td>
    </tr>
  </tbody>
</table>

【讨论】:

  • 感谢您的建议。但是,这并不像我的页面应该那样工作,并且避免了一个棘手的问题,“如果我只是更改显示选项,而不是删除子节点,为什么我的表会被删除?”。
  • 当这种情况发生时,里面的所有东西都被抹杀了:document.getElementById("tableContainer").innerHTML = ""; 然后appendChild() 会将你的桌子移动你的桌子进入那个深渊,你没有逻辑去把所有桌子都拿出来。
  • 非常感谢您的解释。而且我认为“.innerHTML”是一只毛茸茸的小猫,而不是毁灭者萨格。我对 javascript 很陌生,所以这是一个巨大的学习曲线。我正在阅读您脚本的每一行并研究我不理解的任何内容,因此非常感谢您的帮助。我意识到按钮上的“onclick”很顽皮,但没有意识到它会导致这么多问题。我今天发现父级不是 td,而是包含整个页面内容的包装器 div,所以我猜这个按钮正在走向全球,正如你所说。
  • 另外,我喜欢克隆的使用,它会被破坏,但保留原件用于其他用途。
【解决方案2】:

您的代码有点难以理解,但如果您只想切换表格,我认为这是最好的方法。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>

  <style>
    .hide {
      display: none;
    }
  </style>
</head>

<body>
<div class="table-container">
    <button class="toggle-btn">Click me</button>
  <table>
    <tr>
      <td>Genus</td>
      <td>Benthobatis</td>
    </tr>
    <tr>
      <td>Genus</td>
      <td>Diplobatis</td>
    </tr>
  </table>
</div>

  <script>
 const table = document.querySelector('table'),
       btn = document.querySelector('.toggle-btn');
       btn.addEventListener("click", () => {
         table.classList.toggle("hide")
       })
 

  </script>


</body>

</html>

【讨论】:

  • 谢谢,但问题不在于切换。切换有效,但只有一次。之后,控制台中的错误似乎表明该表已被删除,当我只是切换显示:无显示:块,而不是从 div 父级删除表子级。
  • 你能粘贴整个代码吗,因为你的代码没有帮助,例如tableContainer在哪里。
猜你喜欢
  • 1970-01-01
  • 2020-11-17
  • 2012-04-09
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
相关资源
最近更新 更多