【问题标题】:Client side javascript, creation of several elements and show each asap客户端javascript,创建几个元素并尽快显示每个元素
【发布时间】:2010-03-09 10:31:08
【问题描述】:

客户端javascript代码在一个循环中创建一些元素(大约50-100个):

for (var i = 0; i < list.length; i++) {
   var obj = document.createElement("DIV");
   obj.innerHTML = "<span class=\"itemId\">" + list[i].Id 
                   + "</span><!-- some more simple code --> ";

   mainObj.appendChild(obj);
}

浏览器渲染存在一些问题。例如,IE 只是冻结,直到它完成循环,然后一次显示所有元素。有没有办法在appendChild() 之后立即单独显示每个创建的元素?

【问题讨论】:

  • JavaScript 区分大小写 - 使用长度而不是 'Length'

标签: javascript html document appendchild


【解决方案1】:

这是由于浏览器的单线程特性。在线程空闲之前,渲染不会开始。在这种情况下,这是您的循环完成并且函数退出的时候。解决这个问题的唯一方法是(某种程度上)使用计时器模拟多个线程,如下所示:

var timer,
    i = 0,
    max = list.length;

timer = window.setInterval(function ()
{
    if (i < max)
    {
        var obj = document.createElement("DIV");  
        obj.innerHTML = "<span class=\"itemId\">" + list[i].Id   
                + "</span><!-- some more simple code --> ";  

        mainObj.appendChild(obj);
        i++;
    }
    else
        window.clearInterval(timer);
}, 1);

明显的缺点是,这将使您的循环花费更长的时间来完成,因为它会在每次迭代之间进行渲染。

【讨论】:

    【解决方案2】:

    在添加连续条目之间插入延迟,使用setTimeout()

    function insertEntry(list, ix) {
        if (ix == null) {
            ix = 0;
        }
        else if (ix < list.length) {
            var elt= document.createElement("DIV");
            var attr = document.createAttribute('id');
            attr.value = 'item'+ix;
            elt.setAttributeNode(attr);
            elt.innerHTML = "<span class='itemCls'>" + list[ix].Id + ':&nbsp;' + list[ix].Name +
                "</span><!-- some more simple code -->\n";
            mainObj.appendChild(elt);
            ix++;
        }
        if (ix < list.length) {
            setTimeout(function(){insertEntry(list, ix);}, 20);
        }
    }
    

    开始:

        insertEntry(myList);
    

    myList 是这样的:

    var myList = [
        { Id : '1938377', Name : 'Sven'},
        { Id : '1398737', Name : 'Walt'},
        { Id : '9137387', Name : 'Edie'}
        ...
     };
    

    演示:http://jsbin.com/ehogo/4

    【讨论】:

      【解决方案3】:

      我会使用 jQuery 来代替:

      <!DOCTYPE html>
      <html>
      <head>
          <script src="http://code.jquery.com/jquery-latest.js"></script>
          <script>
              $(document).ready(function() {
                  timer = window.setInterval(function ()
                  {
                      for (var i = 0; i < 100; i++) {
                          $('#container').append('<div>testing</div><br />');
                      }
                  },10);
              });
          </script>
      </head>
      <body>
      <div id="container"></div>
      
      </body>
      </html>
      

      jQuery 的速度如此之快,您甚至无需费心在创建它们时显示它们,但您可以通过添加计时器来使其更流畅,如示例所示。

      【讨论】:

      • jQuery 无法更快地创建 for 循环和 DOM。事实上,jQuery 用于将 HTML 转换为 DOM 节点的正则表达式会使其变慢。
      【解决方案4】:

      您是否有特定的原因希望在每个周期后更新 DOM? 如果在一个 javascript 元素中创建所有元素,并在循环结束时将这一元素添加到 DOM 中,会快很多。

      var holder = document.createElement("DIV");
      for (var i = 0; i < list.Length; i++) {
         var obj = document.createElement("DIV");
         obj.innerHTML = "<span class=\"itemId\">" + list[i].Id 
                         + "</span><!-- some more simple code --> ";
      
         holder.appendChild(obj);
      }
      mainObj.appendChild(holder);
      

      【讨论】:

      • 我想避免浏览器冻结。如果用户将看到添加到页面的行,他将看到进度(在 IE 中甚至进度显示图像冻结)。
      猜你喜欢
      • 2011-11-22
      • 2014-05-02
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      • 2021-09-26
      • 2010-11-06
      • 1970-01-01
      相关资源
      最近更新 更多