getElementsByTagName(“td”)不返回所选行的所有td子节点

时间:2016-03-28 14:20:07

标签: javascript dom

我创建了一个反转表格行和列的javascript函数。这是代码:

function rotate(){
            var table = document.getElementById("table");
            var newtable = document.createElement("table");

            var tablebody = table.getElementsByTagName("tbody")[0];
            var newtablebody = document.createElement("tbody");
            newtable.appendChild(newtablebody);

            var rows = tablebody.getElementsByTagName("tr");

            var heads = tablebody.getElementsByTagName("th");

            var i;
            for(i = 0; i < rows.length; i++)
            {
                var cells = rows[i].getElementsByTagName("td");
                var j;
                for(j = 0; j < heads.length; j++)
                {
                    if(newtablebody.getElementsByTagName("tr")[j] == undefined)
                    {
                        var newrow = document.createElement("tr");
                        newtablebody.appendChild(newrow);
                    }
                    if(cells[j] == undefined)
                    {
                        var newcell = document.createElement("td");
                        newtablebody.getElementsByTagName("tr")[j].appendChild(newcell);
                    }
                    else
                    {
                        var newcell = cells[j];
                        var nbspan = cells[j].getAttribute("colspan");
                        newcell.setAttribute("rowspan", nbspan);
                        newcell.setAttribute("colspan", 1);
                        newtablebody.getElementsByTagName("tr")[j].appendChild(newcell);
                    }
                }
            }
            table.innerHTML = newtable.innerHTML;
        };

问题在于,当我尝试为当前行获取标签名称为“td”的所有子节点时,我得到了许多未定义的单元格,而我可以从控制台日志中看到这些单元格存在并包含数据(I在日志中显示innerHTML。

我真的输了,所以任何帮助都会受到赞赏。谢谢!

1 个答案:

答案 0 :(得分:2)

当您将现有单元格附加到新表格行时,您隐式从旧表格行中删除;一个单元格一次只能在DOM中的一个位置。 getElementsByTagName()返回的节点列表是实时,这意味着从表格行中删除该单元格会立即将其从cells中删除阵列。这意味着cells[j]处的单元格突然消失,cells[j]因此成为(旧)表格行中的 next 单元格。但是,你的循环仍然会增加j,所以只要发生这种情况就会跳过一个单元格。

解决问题的一种简单方法是在开始循环之前将节点列表复制到数组中:

   var cells = rows[i].getElementsByTagName("td");
   cells = [].map.call(cells, Object); 

现在你已经有了一个简单的数组,元素不会从中神奇地消失。