使用jQuery快速构建HTML表

时间:2020-03-06 14:26:48  来源:igfitidea点击:

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

加载数据时,我显示动画的pleasewait(.gif)图形。但是,在JavaScript函数构建表时,图形冻结。起初,我很高兴做到这一点(显示表格),我想现在我需要提高效率。至少我需要停止动画图形的冻结。我可以转到静态的"正在加载"显示,但我希望此方法可以正常工作。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

我的等待显示的建议?和效率?可能是建立表格的更好方法吗?也许不是表格,而是其他一些"表格",例如display

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 += " " ;
        }
        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") ;

解决方案

我们正在做的是构建一个字符串,然后在插入时立即解析所有字符串。如何创建一个实际的表格元素(即$(" <table>")`),然后依次向其添加每一行?到我们实际将其插入页面时,所有DOM节点都已构建完毕,因此不会造成太大的影响。

对于初学者,请查看flydom及其变体,它们将为我们提供有益的帮助。我们能否提供更多背景信息?如果这不在onload中,而只是粘贴在页面中,只需将整个内容包装在$(function(){/ * code * /})中,可能会清除我们遇到的所有问题。内联JS立即执行,这意味着该表为循环。 onload是一个事件,本质上是"分离"的。

我们可以将表一点一点地插入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 += " " ; 
  }
  else { 
   myTr += t.data[i][t.hdrs[j]] ; 
  }
  myTr += "</td>";
  }
 myTr +=    "</tr>";
 $('#myTable tbody').append(myTr);
}

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

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

对于情况,我建议将操作分为几步。假设有一个100行的表格,我们首先会生成一个有效的10行的表格。然后,将其输出到屏幕并使用setTimeout将控制权返回给浏览器,以便UI停止阻止。当setTimeout返回时,我们将进行接下来的10行,依此类推。

正如其他人所说,使用DOM创建表肯定是"干净的"。但是,就性能而言,要付出巨大的代价。请参阅有关此主题的出色的quirksmode文章,其中包含一些可以自己运行的基准。

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

我一直在使用JTemplates完成我们描述的内容。 Dave Ward在他的博客上有一个示例。 JTemplates的主要好处是html不会被编织到javascript中。我们编写一个模板并调用两个函数,以让jTemplate从模板和json构建html。

基本上,我们需要设置循环,以使它们如此频繁地屈服于其他线程。以下是本文中有关运行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,则可以尝试使用我的"简单模板"插件。它通过大幅度减少我们必须执行的串联操作数量来整理整个过程。在我最近进行了一些重构之后,它的性能也相当不错,从而导致了相当大的速度提升。这是一个示例(无需为我们做所有工作!):

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});
});
...

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

我建议我们检查chain.js,以从JavaScript对象快速构建表和其他重复数据结构。这是一个非常轻巧的jQuery智能数据绑定插件。

在网络上搜索JavaScript和StringBuilder。一旦有了JavaScript字符串构建器,请确保对每个串联使用.append方法。也就是说,我们不希望有任何" +"串联。之后,搜索JavaScript并替换html。使用此功能代替" innerHTML"。