在今天的采访中我被问到一个问题:
如何撤消
<li>
列表 有效?
例如,如果有列表:
<ul id="list">
<li>1</li>
<li>2</li>
...
<li>10000</li>
</ul>
然后在反向之后,列表看起来像:
<ul id="list">
<li>10000</li>
...
<li>2</li>
<li>1</li>
</ul>
我能提出的最有效的代码是:
function reverse(){
var list = document.getElementById("list");
var node_list = list.childNodes;
var fragment = document.createDocumentFragment();
for(var i=node_list.length-1; i>=0; i--){
fragment.appendChild(node_list[i]);
}
list.appendChild(fragment);
}
但它仍然非常慢(在Chrome中需要大约10秒)。有什么想法吗?
更新:
我认为我的Chrome出了问题...我安装了Chromium并测试了上面的代码,花了不到一秒钟。
答案 0 :(得分:2)
我认为面试问题的重点基本上是innerHTML
是way faster而不是每个浏览器中的任何DOM操作。所以,不要使用DocumentFragment
,而是使用简单的字符串:
var ul = document.getElementById("list");
var lstLi = ul.childNodes;
var str = '';
for (var i=lstLi.length - 1; i >= 0; i--) {
str += '<li>' + lstLi[i].innerHTML + '</li>';
}
ul.innerHTML = str;
答案 1 :(得分:1)
DOM的工作方式,您无需重新创建区域。您需要做的就是将元素移动到已存在的ul中。最佳解决方案就是:
var ul = document.getElementById("lstLi");
var lstLi = ul.childNodes;
for (var i=0, c = lstLi.length; i < c; i++) {
ul.insertBefore(lstLi[i], ul.firstChild);
}
基本上它的作用是它迭代每个元素并将它们放在第一位。最后,您的列表将被颠倒。
答案 2 :(得分:1)
你可以这样做:
var list = document.getElementsByTagName("ul")[0],
items = list.childNodes,
itemsLen = items.length;
while (itemsLen--) {
list.appendChild(items[itemsLen]);
}
测试:http://jsbin.com/ohegu4/2/edit
如果你的问题是你不想阻止浏览器,你可以这样做:
var list = document.getElementsByTagName("ul")[0],
items = list.childNodes,
itemsLen = items.length;
(function reversePart() {
var iterations = 10; // Number of processed elements every 100ms
window.setTimeout(function(){
while (iterations-- && itemsLen--) {
list.appendChild(items[itemsLen]);
}
if (itemsLen) {
reversePart();
}
}, 100); // Delay between each process : 100ms
})();
测试( 100000 li,是啊!):http://jsbin.com/ubugi3/2/edit
答案 3 :(得分:0)
Pumbaa80的基于字符串的方法是我发现反转列表的最快方法。但是,如果你真的想要使用DOM方法来反转它(例如你不想丢失列表项的属性),你可以这样做:
function reverseDom(){
var list = document.getElementById('list');
var items = list.childNodes;
var length = items.length;
var item0 = items[0];
var i;
list.style.display = 'none';
for(i = 0; i < length - 1; i++)
{
list.insertBefore(list.lastChild, item0);
}
list.style.display = 'block';
}
在Linux中的Google Chrome中,上述方法花费了大约一秒来反转10,000个项目列表。但Pumbaa80的方法更快。如果您转到此链接,您可以在同一列表上并排比较这两种方法: http://jsbin.com/ubugi3/6