Javascript 使用DataTables时IE8长时间运行脚本错误
我有一个应用程序,它使用DataTables jQuery库在我的目标浏览器IE8中呈现内容。问题是,当我推动一个大数组进行渲染时,IE8有时会抛出臭名昭著的长时间运行脚本错误 分析应用程序后,以下代码中对_fnAddData的调用似乎是导致问题的原因:Javascript 使用DataTables时IE8长时间运行脚本错误,javascript,performance,Javascript,Performance,我有一个应用程序,它使用DataTables jQuery库在我的目标浏览器IE8中呈现内容。问题是,当我推动一个大数组进行渲染时,IE8有时会抛出臭名昭著的长时间运行脚本错误 分析应用程序后,以下代码中对_fnAddData的调用似乎是导致问题的原因: if (bUsePassedData) { for (var i = 0, len = oInit.aaData.length; i < len; i++) { _fnAddData(oSettings, oInit.aa
if (bUsePassedData) {
for (var i = 0, len = oInit.aaData.length; i < len; i++) {
_fnAddData(oSettings, oInit.aaData[i]);
}
} else if (oSettings.bDeferLoading ||
(oSettings.sAjaxSource === null && oSettings.ajax === null)) {
_fnAddTr(oSettings, $(oSettings.nTBody).children('tr'));
}
解决这个问题的好办法是什么?提前感谢。我想您可以将您的功能分为3个功能:
function beforeIf(){
if (bUsePassedData) {
procesData(oSettings,oInit.aaData.concat());
} else if (oSettings.bDeferLoading ||
(oSettings.sAjaxSource === null && oSettings.ajax === null)) {
_fnAddTr(oSettings, $(oSettings.nTBody).children('tr'));
}
afterIF();
}
function processData(oSettings,arr){
//process in chuncks of 50;
// setTimeout takes a long time in IE
// it'll noticibly slow donw your script when
// only processing one item at the time
var tmp=arr.splice(0,50);
for (var i = 0, len = tmp.length; i < len; i++) {
_fnAddData(oSettings, tmp[i]);
}
if(arr.length!==0){
setTimeout(function(){
processData(oSettings,arr);
},0);
return;
}
afterIf();
}
function afterIf(){
//continue processing
}
function beforeIf(){
if (bUsePassedData) {
procesData(oSettings,oInit.aaData.concat());
} else if (oSettings.bDeferLoading ||
(oSettings.sAjaxSource === null && oSettings.ajax === null)) {
_fnAddTr(oSettings, $(oSettings.nTBody).children('tr'));
}
afterIF();
}
function processData(oSettings,arr){
//process in chuncks of 50;
// setTimeout takes a long time in IE
// it'll noticibly slow donw your script when
// only processing one item at the time
var tmp=arr.splice(0,50);
for (var i = 0, len = tmp.length; i < len; i++) {
_fnAddData(oSettings, tmp[i]);
}
if(arr.length!==0){
setTimeout(function(){
processData(oSettings,arr);
},0);
return;
}
afterIf();
}
function afterIf(){
//continue processing
}
函数beforeIf(){
if(总线组装数据){
procesData(oSettings,oInit.aaData.concat());
}else if(oSettings.bdeferload||
(oSettings.sAjaxSource==null&&oSettings.ajax==null)){
_fnAddTr(oSettings,$(oSettings.nTBody).children('tr');
}
afterIF();
}
函数processData(oSettings,arr){
//工艺流程:50台;
//在IE中设置超时需要很长时间
//它会明显减慢你的脚本时
//一次只处理一个项目
var tmp=阵列拼接(0,50);
对于(变量i=0,len=tmp.length;i谢谢@HMR。你帮助我更接近我的目标。为了解决这个问题,我把我的代码一直写到现在:
(function processData(oSettings, arr) {
var tmp = arr.splice(0, 50);
tickApp.$orders.dataTable().fnAddData(tmp);
if (arr.length !== 0) {
setTimeout(function () {
processData(oSettings, arr);
}, 0);
}
}(oSettings, oInit.aaData.concat()));
我没有使用private _fnAddData函数,而是选择了DataTables public fnAddData()函数。通过这种方式,我可以一次将50行推入存储在tickApp中的表中。$orders对象,我只是对存储在内存中的jQuery对象的引用:
tickApp.$orders = $('#orders');
在我代码的另一部分。按照你的方式,它仍然是一次推一排,而不是整个50排
再次感谢。如果您使用ajax获取数据,您可以覆盖datatables配置对象中的“fnServerData”。这将允许您获取要加载的数据,然后根据需要对其进行处理
在我的例子中,我有一个通用的datatables配置对象,用于所有datatables。我用一个函数覆盖默认的fnServerData函数,该函数使用fnAddData和setTimeout将行以200行为一组传递到datatable,以再次调用该函数,直到所有数据都已处理完毕,最后我调用fnDraw来绘制该表
var DEFAULT_CHUNK_SIZE = 200;
function feedDataToDataTableInChunks(startIndex, data, oSettings) {
var chunk = data.slice(startIndex, DEFAULT_CHUNK_SIZE);
oSettings.oInstance.fnAddData(chunk, false);
if((startIndex += DEFAULT_CHUNK_SIZE) < data.length) {
setTimeout(function () {
feedDataToDataTableInChunks(startIndex, data, oSettings);
});
} else {
oSettings.oApi._fnInitComplete(oSettings, data);
oSettings.oInstance.fnDraw();
}
}
var config = {fnServerData: function(){
oSettings.jqXHR = $.getJSON(sSource, aoData)
.done(function (result) {
feedDataToDataTableInChunks(0, result || [], oSettings);
});
}}
var DEFAULT\u CHUNK\u SIZE=200;
函数FeedDataToDataTableInChunk(起始索引、数据、oSettings){
var chunk=data.slice(startIndex,默认块大小);
oSettings.oInstance.fnAddData(chunk,false);
if((startIndex+=默认块大小)
我使用的是datatables 1.9.4版请注意,fnAddData方法有一个可选的第2个参数。此参数表示是否重新绘制表。默认值为true。因此,如果在没有第二个参数的情况下调用fnAddData 50次,它将重新绘制表50次。对于大表或大插入,这可能非常慢。谢谢@bumptiousqbangshilt!我想知道。。。由于我使用的数据表具有不同的行高,因此我没有明确设置css值,因此重新绘制该表不是很理想吗?它的运行速度非常快,但我会将其更改为更快。您在哪里定义传递给_fnInitComplete的json变量?抱歉,我在意识到忘记包含它后添加了对fnInitComplete的调用,我已更新了我的答案以正确使用它。