如何在纯JS中的一行之后插入一组表行

时间:2009-04-15 19:34:07

标签: javascript dom html-table

我有以下问题: 我需要在第X行之后插入N行。我需要插入的行集作为由TR元素组成的HTML块传递给我的函数。我也可以访问TR,之后我需要插入。

这与我之前用另一个TBODY替换TBODY之前所做的略有不同。

我遇到的问题是appendChild需要一个元素,但我必须插入一个集合。

修改:

以下是解决方案

function appendRows(node, html){ 
    var temp = document.createElement("div");
    var tbody = node.parentNode;
    var nextSib = node.nextSibling;

    temp.innerHTML = "<table><tbody>"+html;
    var rows = temp.firstChild.firstChild.childNodes;

    while(rows.length){
        tbody.insertBefore(rows[i], nextSib);
    }
} 

在行动中看到这一点:

http://programmingdrunk.com/test.htm

7 个答案:

答案 0 :(得分:1)

altCognito说的是,只要知道big innerHTML tbody bug,以防你想使用innerHTML一次性替换所有内容,因为你做了很多这样的事情,并且DOM操作结果太慢了。

答案 1 :(得分:1)

IE使用innerHTML插入行时出错,因此不起作用。直接从马的口中:http://www.ericvasilik.com/2006/07/code-karma.html

我建议只更新tbody,但将代码附加到新结构中。

答案 2 :(得分:1)

使用表格对象,您可以在其中插入新行。

var tbl = document.getElementById(tableBodyId); 
var lastRow = tbl.rows.length; 
// if there's no header row in the table, then iteration = lastRow + 1 
var iteration = lastRow; 
var row = tbl.insertRow(lastRow);

它会在表格的末尾插入一行。

答案 3 :(得分:1)

if(node.nextSibling && node.nextSibling.nodeName.toLowerCase() === "tr")

这是为了什么?我认为你不需要它。如果node.nextSibling为null,则无关紧要。你可以将它传递给insertBefore,它的行为与appendChild相同。

除了'tr'之外,tbody中没有其他元素允许。

for(var i = 0; i < rows.length; i++){
    tbody.insertBefore(rows[i], node.nextSibling);

这对多行不起作用。一旦你完成了一个insertBefore,node.nextSibling现在将指向你刚刚插入的行;你最终会以相反的顺序插入所有行。你需要记住原来的nextSibling。

ETA:另外,如果'rows'是一个实时DOM NodeList,每次将其中一行插入新主体时,它会将其从旧主体中删除!因此,当您迭代它时,您正在销毁列表。这是“每隔一个”错误的常见原因:您处理列表的第0项,并将其从列表中删除,将项目1移动到项目0所在的位置。接下来,您将访问新项目1,即原始项目2,原始项目1永远不会被看到。

在正常的非实时“数组”中制作列表的副本,或者,如果您知道它将是实时列表,您实际上可以使用更简单的循环形式:

var parent= node.parentNode;
var next= node.nextSibling;
while (rows.length!=0)
    parent.insertBefore(rows[0], next);
  

我必须插入一套。

通常,当您考虑一次插入一组元素时,您希望使用DocumentFragment。但是,遗憾的是,您无法在DocumentFragment上设置'innerHTML',因此您必须在上表中设置行,然后将它们逐个移动到DocumentFragment中,然后在documentFragment之前插入。虽然理论上这可能比附加到最终目标表更快(由于较少的childNodes列表抨击),但实际上通过我的测试,它实际上并没有明显更快。

另一种方法是insertAdjacentHTML,这是一种仅IE扩展方法。不幸的是,你不能在tbody的子节点上调用insertAdjacentHTML,就像你因为IE bug而无法设置tbody.innerHTML一样。您可以在DocumentFragment中设置它:

var frag= document.createDocumentFragment();
var div= document.createElement(div);
frag.appendChild(div);
div.insertAdjacentHTML('afterEnd', html);
frag.removeChild(div);
node.parentNode.insertBefore(frag, node.nextSibling);

不幸的是,出于某种神秘的原因,insertAdjacentHTML在这种情况下工作得非常慢。对于我来说,上述方法大约是逐个插入速度的一半。 : - (

答案 4 :(得分:1)

当在最后一个位置以外的任何地方插入行时,这对我来说效果更好,

var rowNode = refTable.insertRow(0); var cellNode = rowNode.insertCell();

答案 5 :(得分:0)

你需要逐个追加它们。

答案 6 :(得分:0)

你需要确定行X是否是最后一行......

//determine if lastRow...
//if not, determine row_after_row_x
for(i in n_rows){
  if(lastRow){
    tbodyObj.appendChild(row_i_of_n);
  } else {
    tbodyObj.insertBefore(row_i_of_n, row_after_row_x);
  }
}