if(node.nextSibling && node.nextSibling.nodeName.toLowerCase() === "tr")
这是干什么用的?我不认为你需要它。如果 node.nextSibling 为空,那没关系。您可以将其传递给 insertBefore,它的作用与 appendChild 相同。
在 tbody 中除了“tr”之外没有其他元素被允许。
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 list-bashing),但在实践中,通过我的测试,它实际上并没有明显更快。
另一种方法是 insertAdjacentHTML,这是一种仅限 IE 的扩展方法。不幸的是,您不能在 tbody 的子级上调用 insertAdjacentHTML,就像由于 IE 错误而无法设置 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 在这种情况下工作得非常缓慢。上面的方法对我来说大约是一对一 insertBefore 的一半速度。 :-(