以下哪种技术更好用户体验?
在这两个示例中,假设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时更新?
答案 0 :(得分:10)
A)只需+ =使用thumbContainer.innerHTML
从不这样做。这必须将所有内容序列化为HTML,向其中添加一个字符串,然后将其全部解析。它很慢(在循环中执行它是特别糟糕的新闻)并且它将丢失所有JavaScript引用,事件处理程序等等
IE的insertAdjacentHTML
将更有效地完成此操作。它也是HTML5的一部分,但尚未在其他地方广泛实施。
使用appendChild?
是的,没关系。如果你有一个很多的拇指,它将开始变慢(但不会像每次重新分析innerHTML那样糟糕)。在某些情况下,使DocumentFragment一次将多个元素插入容器子节点列表可能会有所帮助。将DocumentFragment与Range结合起来可以做得更多,但是由于IE的Range实现是如此StRange,因此难以兼容地编写。
无论哪种方式,因为您似乎没有对单个shell节点做任何事情,为什么不在解析之前简单地将所有thumbernail HTML字符串连接在一起?
for(shell.childNodes中的var child){
不要在序列类型上使用for..in
,它不会按照您的想法执行。它仅用于对抗用作映射的Object
。迭代Array或NodeList的正确方法是普通的for (var i= 0; i<sequence.length; i++)
。
答案 1 :(得分: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;