解析Json的最佳方法?

时间:2010-12-04 13:09:02

标签: javascript json parsing

我想解析json中的数据并将其替换为表格。我正在使用以下代码

var obj=$.parseJSON(data);
data=obj.data;
totalRecord=obj.totalCount;
$.each(data,function(i,obj){
  for(var j in obj){
    switch(j){
            case 'priority':
                $("#td_"+i+"_"+j).find('.priority').val(obj[j]);
                $("#td_"+i+"_"+j).find('.hidden').val(obj['id']);
                break;
            case 'chkbox':
                $("#td_"+i+"_"+j).find('.chkbox').val(obj['id']);
                break;
            case 'status':
                var val=(this.j)?'active.gif':'deactive.gif';
                $("#td_"+i+"_"+j).find('img').attr('src','<?= base_url() ?>assets/grid/images/'+val);
                $("#td_"+i+"_"+j).find('img').attr('onClick','updateStatus(\''+obj['id']+'\',\''+obj[j]+'\')');
                break;
            case 'edit':
                $("#td_"+i+"_"+j).find('a').attr('href','index.php/main/edit/'+obj[j]);
                break;
            default:
                $("#td_"+i+"_"+j).html(obj[j])
                break;
            }
  }
});

但我认为它有点慢。还有其他更好的方法来实现它吗?

KrishNik

4 个答案:

答案 0 :(得分:2)

首先,通过对$.parseJSON()的调用,您的JSON被解析,我敢打赌 。我敢打赌, 慢的是解释数据结构和更新DOM的代码。

您需要做的第一件事就是在内部循环中隐藏jQuery查找。那会有所帮助:

   for (var j in obj) {
     var cell = $('#td_' + i + '_' + j);

现在你可以使用“cell”而不是重复那个jQuery查找。 (不会帮助那个,但它确实存在。)

要在(可能很大的)表格中设置事件处理程序,当您想要处理的是单个单元格上的点击(或其他)时,使用jQuery {{ 会更好1}}功能:

.delegate()

请注意,每次在数据中收到“status”消息时,您当前的代码都会重新附加“onClick”处理程序。您可以添加一个检查,以确保您不会不必要地重新注册:

  case 'status':
    $('table').delegate('#td_' + i + '_' + j, 'click', function() {
      updateStatus(obj['id'], obj[j]);
    });
    break;

无论你如何滚动它,迭代一个大数据结构并更新大表中的大量单元格可能会非常慢,这取决于你的CSS等,特别是在旧浏览器(IE6)中。

答案 1 :(得分:1)

我不确定解析是否会减慢你的速度。可能是你在很多对象上运行了很多jQuery选择器,这可能需要时间。

编辑:看见@ pointy的回答。我甚至没有注意到你通过DOM属性进行事件委托。 Yeeaah,这可能会很慢。

事实上,使用live事件委派而不是将click事件分配给每个元素可能会运行得更快。首先,不要给它点击事件,而是使用jQuery的data函数为元素提供对相关对象的引用。

case 'status':
    // Note that I switched it to this[j], since I suspect
    // using this.j was unintentional
    var val=(this[j])?'active.gif':'deactive.gif';
    $('#td_'+i+'_'+j).find('img').attr('src', '<?= base_url() ?>assets/grid/images/'+val).
        data('status_obj', obj);

然后,在整个脚本中运行以下一次(显然,未经测试)。

$('td.status img').live('click', function () {
    var obj = $(this).data('status_obj');
    updateStatus(obj.id, obj.status);
});

这意味着img元素中的任何td.status(是的,我为你组成了一个新的类名)将会在被点击后运行updateStatus存储在其中的status_obj数据。

一些较小的优化:

  • 在查找子项时指定标记名称,例如find('span.priority'),因为jQuery只能遍历该标记名称的子项而不是所有子项
  • 或者,实际上,为这些孩子提供他们自己唯一的ID来查找,因为getElementById几乎肯定会比循环孩子更快地运行。

答案 2 :(得分:1)

您正在为循环中的每次迭代定位每个元素。找到单元格并将结果放在循环外的变量中。

var obj = $.parseJSON(data);
var parsedData = obj.data;
var totalRecord = obj.totalCount;
$.each(parsedData, function(i, item) {
  for(var j in item) {
    var element = $("#td_"+i+"_"+j);
    switch(j) {
      case 'priority':
        element.find('.priority').val(item[j]);
        element.find('.hidden').val(item['id']);
        break;
      case 'chkbox':
        element.find('.chkbox').val(item['id']);
        break;
      case 'status':
        var val=(this.j)?'active.gif':'deactive.gif';
        element.find('img')
          .attr('src','<?= base_url() ?>assets/grid/images/'+val)
          .attr('onClick','updateStatus(\''+item['id']+'\',\''+item[j]+'\')');
        break;
      case 'edit':
        element.find('a').attr('href','index.php/main/edit/'+item[j]);
        break;
      default:
        element.html(item[j])
        break;
      }
    }
  });

请注意,我重命名了一些变量。您正在为不同的事情重用变量名称,例如重用包含JSON字符串的data变量来包含已解析的数据,以及包含解析结果的obj变量以包含数据中的单个项目。

我注意到您在代码中的某个位置使用this.j。这与item[j]item['j']不同,这可能不是预期的。

答案 3 :(得分:0)

你可以做的一件事就是在你的for循环开始时将$("#td_"+i+"_"+j)放在它自己的变量中:

for(var j in obj){
   var tdElem = $("#td_"+i+"_"+j);

并在任何地方使用tdElem代替$("#td_"+i+"_"+j)