我想解析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
答案 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只能遍历该标记名称的子项而不是所有子项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)
。