JavaScript:向元素添加子元素

9
以下哪种技术更有良好的用户体验?
在两个示例中,假设 `thumbContainer` 被设置为 `document.getElementById('thumbContainer')` 的返回值,并且 `new Thumbnail(thumb).toXMLString()` 返回一个带有 XHTML 标记的字符串。
A) 仅使用 `thumbContainer.innerHTML +=` :
for (thumb in thumbnails) {
    thumbContainer.innerHTML += new Thumbnail(thumb).toXMLString();
} 

B)或将new Thumbnail(thumb).toXMLString()转换为DOM元素,并使用appendChild
for (thumb in thumbnails) {
    var shell = document.createElement('div');
    shell.innerHTML = new Thumbnail(thumb).toXMLString();
    for (i = 0; i < shell.childElementCount; i++) {
        thumbContainer.appendChild(shell.children[i]);
    }
}

我曾经使用过两种浏览器,但是在Firefox中会收到“您运行的脚本时间较长,是否要停止它?”的投诉?

哪个循环更松散,可以允许UI在向DOM添加新元素时更新?

2个回答

10

A) 只需使用 thumbContainer.innerHTML +=

绝不要这样做。这会将所有内容序列化为HTML,添加字符串,并全部解析回来。它很慢(在循环中执行尤其糟糕),并且会失去所有JavaScript引用、事件处理程序等。

IE的insertAdjacentHTML可以更高效地完成此操作。它也是HTML5的一部分,但其他浏览器尚未广泛实现。

使用appendChild?

是的,那没问题。如果你有很多缩略图,它会开始变慢(但不像每次重新解析innerHTML那么糟糕)。在某些情况下,制作一个DocumentFragment以一次性插入多个元素到容器子节点列表中可以帮助提高性能。将DocumentFragment与Range结合使用可以做更多的事情,但编写兼容性代码会更困难,因为IE的Range实现非常复杂。

无论哪种方式,既然您似乎没有对各个shell节点做任何操作,为什么不在解析之前将所有缩略图HTML字符串连接起来呢?

for (var child in shell.childNodes) {

不要对序列类型使用for..in,它会产生你意想不到的结果。它只适用于作为映射使用的Object。正确的方法是使用普通的for (var i= 0; i<sequence.length; i++)来迭代Array或NodeList。


感谢您提供 insertAdjacentHTML。这正是我所需要的。 - w35l3y

6
我个人更喜欢第二种方法(使用appendChild),因为它向文档树中添加新元素而不影响旧元素。
当使用innerHTML += 新内容时,会影响旧内容,因为所有HTML都必须被重新赋值(替换为包含旧代码和一些新代码的新HTML)。
但是,如果您想提高性能,我建议使用DocumentFragments。使用它们,您可以仅通过对文档树上的一个appendChild调用来附加整个节点集。值得一读:“DOM DocumentFragments” by John Resig,但这并不适合您的问题,因为您按字符串格式获取内容,必须先将其转换为DOM节点。
我第二个建议是创建HTML代码字符串,然后在临时容器上使用innerHTML将其转换为DOM节点。
var htmlCode = "";
for (thumb in thumbnails) {
    htmlCode += new Thumbnail(thumb).toXMLString();
}
var element = document.createElement(htmlCode);
element.innerHTML = htmlCode; // ... and append all the elements to document, or thumbContainer.innerHTML += htmlCode;

我认为你的示例不起作用,因为Thumbnail#toXMLString返回一个带有XHTML标记的字符串。因此,在document.createElement(htmlCode)中提供的标记名称不是有效的名称。 - yckart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接