使用jQuery动态构建HTML表

时间:2008-09-19 16:31:08

标签: javascript jquery

下面是我用来动态构建HTML表的代码(使用从服务器收到的JSON数据)。

我在加载数据时显示动画的等待(.gif)图形。但是,当JavaScript函数构建表时,图形会冻结。起初,我很高兴能够实现这一目标(显示表格),我想现在我需要努力提高效率。至少我需要阻止动画图形冻结。我可以进入一个静态的“加载”显示,但我宁愿让这个方法有用。

建议我等待显示?和效率?可能是建立桌子的更好方法?或者也许不是一张桌子,而是一些其他的“桌子”,比如显示

var t = eval( "(" + request + ")" ) ;
var myTable = '' ;
myTable += '<table id="myTable" cellspacing=0 cellpadding=2 border=1>' ;
myTable +=  "<thead>" ;
myTable +=   "<tr>";
for (var i = 0; i < t.hdrs.length; i++) {
    myTable +=    "<th>"     + header +       "</th>";
}
myTable +=   "</tr>" ;
myTable +=  "</thead>" ;
myTable +=  "<tbody>" ;

for (var i = 0; i < t.data.length; i++) {
    myTable +=    '<tr>';
    for (var j = 0; j < t.hdrs.length; j++) {
        myTable += '<td>';
        if (t.data[i][t.hdrs[j]] == "") {
            myTable += "&nbsp;" ;
        }
        else {
            myTable += t.data[i][t.hdrs[j]] ;
        }
        myTable += "</td>";
    }
    myTable +=    "</tr>";
}
myTable +=  "</tbody>" ;
myTable += "</table>" ;

$("#result").append(myTable) ;
$("#PleaseWaitGraphic").addClass("hide");
$(".rslt").removeClass("hide") ;

8 个答案:

答案 0 :(得分:26)

你基本上想要设置你的循环,以便它们经常屈服于其他线程。以下是this article中有关运行CPU密集型操作而不冻结UI的主题的示例代码:

function doSomething (progressFn [, additional arguments]) {
    // Initialize a few things here...
    (function () {
        // Do a little bit of work here...
        if (continuation condition) {
            // Inform the application of the progress
            progressFn(value, total);
            // Process next chunk
            setTimeout(arguments.callee, 0);
        }
    })();
}

至于简化脚本中HTML的生成,如果您使用的是jQuery,可以试试我的Simple Templates插件。它通过大幅减少你必须做的连接数来整理整个过程。在我最近做了一些重构导致一个非常大的speed increase之后,它的表现也相当不错。这是一个例子(没有为你做所有工作!):<​​/ p>

var t = eval('(' + request + ')') ;
var templates = {
    tr : '<tr>#{row}</tr>',
    th : '<th>#{header}</th>',
    td : '<td>#{cell}</td>'
};
var table = '<table><thead><tr>';
$.each(t.hdrs, function (key, val) {
    table += $.tmpl(templates.th, {header: val});
});
...

答案 1 :(得分:11)

我一直在使用JTemplates来完成你所描述的内容。 Dave Ward在他的博客here上有一个例子。 JTemplates的主要好处是你的html没有编入你的javascript。你编写一个模板并调用两个函数让jTemplate从你的模板和你的json构建html。

答案 2 :(得分:3)

您正在做的是构建一个字符串,然后在插入时立即解析它。如何创建一个实际的表元素(即$("<table>")),然后依次添加每一行?当你实际将它插入到页面中时,DOM节点都将被构造,所以它不应该是一个大的命中。

答案 3 :(得分:3)

使用innerHTML肯定比使用jQuery的HTML-to-DOM-ifier快得多,后者使用innerHTML但对输入进行了大量处理。

我建议将chain.js作为一种从JavaScript对象快速构建表和其他重复数据结构的方法。它是jQuery的一个非常轻量级的智能数据绑定插件。

答案 4 :(得分:0)

对于初学者来说,查看flydom及其变体,它们将非常有用。你能提供更多背景吗?如果这不在onload中并且只是粘贴在页面中,只需将整个内容包装在$(function(){/ * code * /})中就可以清除遇到问题的所有内容。内联JS立即执行,这意味着表的循环。 onload是一个事件,基本上是“分离的”。

答案 5 :(得分:0)

我的经验是有两个不连续的延迟。一个是将所有这些字符串连接在一起。另一种是当浏览器实际尝试渲染字符串时。通常情况下,IE浏览器的UI冻结最麻烦,部分原因是它在运行javascript时要慢得多。这应该会在IE8中变得更好。

我建议您将操作分解为步骤。比如100行表,首先生成一个有效的10行表。然后将其输出到屏幕并使用setTimeout将控制权返回给浏览器,以便UI停止阻止。当setTimeout返回时,你会执行接下来的10行等等。

正如其他人所说,使用DOM创建表肯定是“更干净”。但是,在性能方面要付出惨重的代价。请参阅有关此主题的优秀quirksmode文章,该文章有一些您可以自行运行的基准测试。

长话短说,即使在现代JS引擎上,innerHTML也比DOM快得多。

答案 6 :(得分:0)

在网络上搜索JavaScript和StringBuilder。拥有JavaScript字符串构建器后,请确保对每个连接使用.append方法。也就是说,您不希望有任何+个连接。之后,搜索JavaScript并替换HTML。使用此功能代替innerHTML

答案 7 :(得分:-2)

您可以逐位将表插入DOM。老实说,我不完全确定这是否有助于解决您的问题,但值得一试。我会大致这样做(未经测试的代码,可以进一步改进):

$("#result").append('<table id="myTable" cellspacing=0 cellpadding=2 border=1></table>');
$('#myTable').append('<thead><tr></tr></thead>');
$('#myTable').append('<tbody></tbody>');

for (var i = 0; i < t.hdrs.length; i++) { 
    $('#myTable thead tr').append('<th>'+header+'</th>');
}

for (var i = 0; i < t.data.length; i++) { 
 myTr =    '<tr>';
 for (var j = 0; j < t.hdrs.length; j++) { 
  myTr += '<td>';
  if (t.data[i][t.hdrs[j]] == "") { 
   myTr += "&nbsp;" ; 
  }
  else { 
   myTr += t.data[i][t.hdrs[j]] ; 
  }
  myTr += "</td>";
  }
 myTr +=    "</tr>";
 $('#myTable tbody').append(myTr);
}

$("#PleaseWaitGraphic").addClass("hide");
$(".rslt").removeClass("hide") ;