表.append()一次发生

时间:2011-12-01 15:08:13

标签: javascript jquery

我有一个for循环,我将行追加到table。虽然我在循环中一次追加每个tr一个,但是在循环结束之前,浏览器不会渲染任何一个{。p>

起初,我认为可能浏览器渲染速度太快,让我注意到,但是在将行数增加到10000之后,显着减速,然后整个表格立即显示。

链接: http://jsfiddle.net/xyan/ad2tV/

增加counter以增加行数。

此外,如果您将counter更改为3(或其他较小的数字)并取消注释alert(),则会暂停循环并显示每行添加一行。

HTML:

<div></div>

使用Javascript:

var table = $('<table />').appendTo($('div'));
var counter = 1000;
var html = [];
var j = 0;

for (var i = 1 ; i < (counter + 1) ; i++) {
    html[j++] = '<tr>';
    html[j++] =    '<td>'+i+'-1</td><td>'+i+'-2</td><td>'+i+'-3</td>';
    html[j++] = '<tr>';
    table.append(html.join(''));
    //alert('pause');
    html = [];
    j = 0;
}

CSS:

    table td {
    padding: 3px;
    border: 1px solid red;
}

注意:

我找到了一种强制循环减速的方法,允许一次添加一行。

链接: http://jsfiddle.net/xyan/8SCP9/

var html = '';
var numbertorun = 15;
var delay = 500;

(function loop (i) {          
   setTimeout(function () {   
      html = '<tr><td>'+i+'-1</td><td>'+i+'-2</td></tr>';              
      $('table').append(html);
      if (--i) loop(i);
   }, delay)
})(numbertorun);

所以我想我的问题不是如何这样做,但为什么这些行未在原始for中一次插入一行循环。

3 个答案:

答案 0 :(得分:2)

我猜想要理解这个问题需要一些背景知识。

每次向网页中的表格添加新行时,您的脚本都会在浏览器内存中更改文档的模型。您用于此的API称为DOM(文档对象模型)。

对DOM的单独更新并不一定意味着将重绘页面。当给定的一组DOM更改将导致浏览器重新呈现页面时,由浏览器决定。

我不知道事实,但我猜测浏览器通常会更新视图,大约每秒40-60次。问题是:如果您的表打印时间少于1/60秒,则无法看到部分更新。

通过添加计时器,您当然可以减慢创建表的进度。如您所知,这将允许您在for循环期间看到在不同点重绘的页面。

如果您希望强制浏览器重绘UI,可以尝试应用一些JavaScript黑客攻击。例如,Ajaxian: Forcing a UI redraw from JavaScript中记录了一个这样的黑客攻击。

如果您有理由希望慢慢运行程序并慢慢添加行,比如每秒说一行,同时可能同时使用JavaScript做其他一些事情,则需要运行循环通过某种方式触发新的迭代或使用另一个(JavaScript)线程

使用setTimeout减慢打印速度的示意图示例(每秒打印1行,只调整window.setTimeout中的第二个参数以更改延迟):

var table = $('<table id="table1"/>').appendTo($('div'));
var i = 0;
var counter = 1000;

function addRow() {
    table.append('<tr><td>'+i+'-1</td><td>'+i+'-2</td><td>'+i+'-3</td></tr>');
    i++;
    if(i<counter) {
       window.setTimeout( addRow, 1000 );
    }
}

addRow();

答案 1 :(得分:0)

jQuery append方法类似于javascript appendChild方法。这两个方法都遍历DOM并在父节点的末尾插入元素。此任务需要花费时间,并且在循环内执行此操作将导致DOM结构中的频繁更改,DOM将无法复制。因此,通过使用settimeout插入行,可以为浏览器提供足够的时间来重新加载内容。因此,您会在第二种方法中看到逐行插入行。

答案 2 :(得分:0)

每次向页面添加元素时,浏览器都需要重绘整个页面。在渲染术语中,这是一个非常密集的过程,而且速度很慢。因此,如果您一点一点地进行小的更改,将使页面看起来非常慢。浏览器正在做的是将这些小变化分组为重大变化。最终结果是页面将以更快的速度呈现。

浏览器正在执行此操作:

http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#tip6