在IE10中,cloneNode()似乎已被破坏

时间:2016-03-11 12:44:52

标签: javascript html dom

在开发动态修改表格的代码时,我发现IE10和FireFox(v38)的工作方式似乎并不相同。

我有一张桌子,里面有一些复选框。我还有一个触发javascript动态操作表行的按钮。

javascript删除行,然后将其添加回来。

点击其中一个或两个复选框,然后按下按钮。

在IE中,复选框将恢复为原始设置,而在FireFox中,它们会保留新设置。

我希望他们保留新设置,我希望能够保持代码独立于浏览器。

我应该如何复制表格行的当前状态?

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <title>RemoveAppend.html</title>
        <script type="text/javascript">
            function testSort() {
                var rows = [];
                var table = document.getElementById("myTable");
                var trows = table.rows;
                var rowslength = table.rows.length;
                for (var i = 0; i < rowslength; i++) {
                    // We'll need to clone these since the references
                    // will be removed when we empty the table.
                    rows.push(table.rows[i].cloneNode(true));
                }
                while (table.firstChild) {
                    table.removeChild(table.firstChild);
                }

                //for (var i = rowslength - 1; i >= 0; i=i-1) 
                for (var i = 0; i < rowslength; i++) {
                        table.appendChild(rows[i]);
                }
                return;
            }
        </script>
    </head>
    <body>
        <form action="foo.action" method="post" name="form1" >
            <table id="myTable" border="0" cellpadding="0" cellspacing="0">
            <thead>
                <tr>
                    <th align="left" width="1%" nowrap="nowrap">Column header</th>
                    <th align="left">Data</th>
                </tr>
            </thead>
            <tbody>
                <tr class="pyjamas">
                <td align="right" nowrap="nowrap">
                    <input type="checkbox" name="dd_19675" id="dd_19675" />
                    <input type="hidden" name="d_19675" id="d_19675" />
                </td>
                <td nowrap="nowrap">
                    <label for="dd_19675" style="width:100%;display:block">First</label>
                </td>
                </tr>
                <tr class="">
                <td align="right" nowrap="nowrap">
                    <input type="checkbox" name="dd_19676" id="dd_19676" checked="checked" />
                    <input type="hidden" name="d_19676" id="d_19676" checked="checked" />
                </td>
                <td nowrap="nowrap">
                    <label for="dd_19676" style="width:100%;display:block">Second</label>
                </td>
                </tr>
            </tbody>
            </table>
            <input type="button" value="Sort" onclick="testSort()" />
        </form>
    </body>
</html>

上面的代码只是html和javascript,因此很容易在浏览器中尝试。

注意:不要被代码中的排序引用误导。我在发布之前已从代码中删除了排序,因为它与我的问题无关。

更新

我已经在IE11上测试了代码,它的工作方式与FireFox类似,因此问题似乎与IE10有关。

更新2:

似乎在简化代码时犯了一个错误。我的例子错过了实际问题。

实际问题是,当我复制节点时,复选框的已发布值会从默认on更改为空。这只发生在IE10中,而不是IE11或FireFox。

2 个答案:

答案 0 :(得分:3)

这里有几点:

  • 您不需要删除行 - 如果您重新排序它们并只是追加它们,它们就会被移动
  • 即使你删除它们,如果在行数组中有引用,也不需要克隆它们 - 一旦你持有任何引用,DOM节点就不会被删除(参见{{ 3}})
  • 在您的示例中,您要删除theadtbody,不确定这是否是故意的

我已经在这里简化了您的代码,删除了cloneNode,根本没有删除table中的行,而是定位tbody而不是{{1} }}。为了说明,我每次单击时都会反转行:

&#13;
&#13;
table
&#13;
function testSort() {
  var rows = [];
  var tbody = document.getElementById("data");
  var rowslength = tbody.rows.length;
  
  // reversing rows to illustrate
  for (var i = 0; i < rowslength; i++) {
    rows.unshift(tbody.rows[i]);
  }
  
  for (var i = 0; i < rowslength; i++) {
    tbody.appendChild(rows[i]);
  }
  return;
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这个答案描述了我如何解决实际问题(如问题的更新2中所述)。

在servlet中我更改了代码,以便我不再关心复选框的值。我需要的所有信息都在名称中。仅存在该键表示已选中该复选框:

Enumeration<String> parameters = request.getParameterNames();
while (parameters.hasMoreElements()) {
    String pName = (String) parameters.nextElement();
    if (pName.startsWith("dd_")) {
        // Checked checkbox! (I let all checkbox names start with dd_ on this page)

我还添加了一个指责IE10的评论。