【问题标题】:insertBefore not updating rowIndex/nextSibling propertiesinsertBefore 不更新 rowIndex/nextSibling 属性
【发布时间】:2019-05-04 17:44:15
【问题描述】:

对于大多数有经验的用户来说,这可能听起来很愚蠢甚至微不足道,但我几个小时前才开始使用前端 javascript,我必须说我对 insertBefore javascript 函数的行为有点困惑。

我的意图很简单:我有一个带有行和单元格的表格,在每一行中我都有一个带有按钮的单元格,其唯一目的是复制该单元格(及其所有内容)并放置新的复制的单元格紧挨着原始单元格。

我有一个类似这样的javascript函数:

// id -> the id of the table I want the row to be added
// caller -> the object of the element that called the function
function duplicateRow(id, caller)
{
    const table = document.getElementById(id);
    const row   = caller.parentNode.parentNode;  // Caller is always a button inside a cell inside a row
    const clone = row.cloneNode(true);

    table.insertBefore(clone, row.nextElementSibling);
}

这个函数是这样调用的(摘自我的 HTML):

<tr>
    <td>
        <input type="text" name="competence-name">
    </td>
    <td>
        <button name="duplicate-row-button" onclick="duplicateRow( 'competencies-table', this )"></button>
    </td>
</tr>

所以,我的期望是,每次点击重复的行按钮时,它都会创建一个精确的复制行,并在该行之后将其添加到该行之后

强>。

我的问题不在于复制(正如人们所期望的那样,做得恰到好处且顺利),而在于新行的放置位置:

  • 第一次,只有一行时,放在最后(因为nextSiblingnull)。
  • 第二次单击第一行上的按钮(尽管现在后面有一个兄弟),新行再次放在表格的末尾(就像nextSibling for第一行仍然是null)。
  • 依此类推(在将重复项与新添加的行混合时,甚至会发生更奇怪的放置)。

向 DOM 添加新节点时是否应该更新 nextSibling 和/或 rowIndex 属性?有没有办法强制他们更新?我有什么问题?我的代码,我对它应该如何工作的理解?

我当然愿意接受任何可能的解释/解决方案/替代方案来实现我所需要的,并提前感谢大家!

【问题讨论】:

    标签: javascript html dom html-table


    【解决方案1】:

    问题在于初始表格行被包装在tbody 元素中(您可以省略开始和结束标记),这是根据表格的内容模型所必需的。但是,当您以编程方式添加更多行时,它们会插入到 tbody 之外,并且您的初始行是该隐式 tbody 的唯一子行,因此 DOM 树如下所示:

    <table>
      <tbody>
        <tr></tr>
      </tbody>
      <tr></tr>
      <tr></tr>
    </table>
    

    为了解决这个问题,我建议向克隆行的父级添加一个克隆:

    function duplicateRow(caller){
      const row   = caller.parentNode.parentNode;  // Caller is always a button inside a cell inside a row
      const clone = row.cloneNode(true);
    
      row.parentNode.insertBefore(clone, row.nextElementSibling);
    }
    <table id="competencies-table">
      <tr>
        <td>
          <input type="text" name="competence-name">
        </td>
        <td>
          <button name="duplicate-row-button" onclick="duplicateRow( this )">Duplicate</button>
        </td>
      </tr>
    </table>

    【讨论】:

    • 你不仅拯救了我的一天,还让我(再一次)意识到在这个世界上不可能有理所当然的事情;一行的父级并不总是一个表!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多