且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-22 13:58:52

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

?我不认为你需要它如果node.nextSibling为null,那没关系。您可以将其传递给insertBefore,它将与appendChild相同。

What's this for? I don't think you need it. If node.nextSibling is null, it doesn't matter. You can pass that to insertBefore and it will act the same as appendChild.

无论如何,tbody内部还没有其他元素允许。对于(var i = 0; i< rows.length; i ++){
tbody.insertBefore(rows [i],node)的

And there's no other element allowed inside a tbody than ‘tr’ anyway.

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

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

This won't work for multiple rows. Once you've done one insertBefore, node.nextSibling will now point to the row you just inserted; you'll end up inserting all your rows in reverse order. You'll need to remember the original nextSibling.

ETA:加上,如果'rows'是一个活的DOM NodeList,每次将一行插入到新的身体,它从旧身体去除它!因此,当您重复列表时,您正在摧毁该列表。这是每一个其他错误的常见原因:您处理列表中的项目0,并将其从列表中移除,将项目1移动到项目0的位置。接下来,您可以访问新的项目1,它是原始项目2,原始项目1从未被看到。

ETA: plus, if ‘rows’ is a live DOM NodeList, every time you insert one of the rows into the new body, it removes it from the old body! Thus, you are destroying the list as you iterate over it. This is a common cause of ‘every other one’ errors: you process item 0 of the list, and in doing so remove it from the list, moving item 1 down into where item 0 was. Next you access the new item 1, which is the original item 2, and the original item 1 never gets seen.

-live'Array',或者如果你知道它将是一个实时列表,你可以使用一个更简单的循环形式:

Either make a copy of the list in a normal non-live ‘Array’, or, if you know it's going to be a live list, you can actually use a simpler form of loop:

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




我必须插入一个。

i have to insert a set.

通常当您考虑一次插入一组元素时,您想要使用DocumentFragment。但是,不幸的是,您无法在DocumentFragment上设置'innerHTML',因此您必须在上面的表上设置行,然后将它们逐个移动到DocumentFragment中,然后在documentFragment之前插入。虽然这可能理论上比追加到最终目标表(由于较少的孩子节点列表冲击)更快,但在实际中,我的测试实际上并不可靠地显着加快。

Usually when you think about inserting a set of elements at once, you want to be using a DocumentFragment. However, unfortunately, you can't set ‘innerHTML’ on a DocumentFragment, so you'd have to set the rows on a table like above, then move them one by one into a DocumentFragment, then insertBefore the documentFragment. Whilst this could theoretically be faster than appending into the final target table (due to less childNodes list-bashing), in practice by my testing it isn't actually reliably significantly faster.

另一种方法是insertAdjacentHTML,一个IE只是扩展方法。您不能在tbody的孩子上调用insertAdjacentHTML,不幸的是,由于IE错误,您无法设置tbody.innerHTML的相同方式。您可以将其设置为DocumentFragment:

Another approach is insertAdjacentHTML, an IE only extension method. You can't call insertAdjacentHTML on the child of a tbody, unfortunately, in the same way as you can't set tbody.innerHTML due to the IE bug. You can set it inside a 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在这个上下文中工作非常慢,有些神秘的原因。对于我来说,上述方法大约是一个接一个插入的速度的一半。 : - (

Unfortunately, somehow insertAdjacentHTML works very slowly in this context for some mysterious reason. The above method is about half the speed of the one-by-one insertBefore for me. :-(