以块为单位向DOM添加项目

时间:2018-03-11 09:55:53

标签: javascript html dom

我有一个来自服务器的大量集合,我需要为集合中的每一行创建DOM个元素。

如果我尝试使用for循环将项目附加到DOM,我的浏览器会挂起一段时间。为了避免这种情况,我尝试使用setTimeout以块的形式添加项目,但是在处理完所有块之后,这些项目不会出现在UI中。

如果我在代码中添加了一个dubugger,对于每次迭代,我都会看到它出现在DOM中。

我已经创建了一个样本来模拟这个。



var longArray = [];
for (var i = 0; i < 10000; i++) {
  var item = {
    "Name": "item" + i,
    "Id": i
  };
  longArray.push(item);
}
var chunks = _.chunk(longArray, 2);
for (var i = 0; i < chunks.length; i++) {
  (function(index) {
    setTimeout(addItem(chunks[index]), 1000);
  })(i);
}

function addItem(items) {
  _.forEach(items, function(item) {
    $("<li />").html(item.Id + " : " + item.Name).appendTo("ul");
  });

}
&#13;
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>

<ul></ul>
&#13;
&#13;
&#13;

对于demo,我添加了1秒的延迟,我期待在下一次执行该功能之前,先前添加的项目出现在屏幕上。

当前项目仅在处理完所有项目时出现在屏幕上。

1 个答案:

答案 0 :(得分:2)

我不会详细说明,因为您将在此处获得许多相关主题。只是要理解你的代码中存在一个逻辑问题,基本上你的所有setTimeout都在1000ms后一起运行。例如,如下更改您的代码,它可以预期工作。

var longArray = [];
for (var i = 0; i < 10000; i++) {
    var item = {
      "Name": "item" + i,
      "Id": i
    };
    longArray.push(item);
 }
var chunks = _.chunk(longArray, 2);

function addItem() {
    var items = chunks.pop();
    _.forEach(items, function(item) {
      $("<li />").html(item.Id + " : " + item.Name).appendTo("ul");
    });

   if (chunks.length) {
     setTimeout(addItem, 1000);
   }
}

addItem();

此外,您可以使用requestAnimationFrame代替setTimeout,这将解决您的冻结问题,并且比setTimeout更好用