使用数据表时,IE8长时间运行脚本错误
IE8 long running script error when using DataTables
我有一个应用程序,它使用DataTables jQuery库在我的目标浏览器IE8中呈现内容。问题是当我推一个大数组渲染时,IE8有时会抛出臭名昭著的长时间运行脚本错误。
在分析应用程序之后,似乎是下面代码中对__fnAddData的调用导致了问题:
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'));
}
我正在寻找解决方案,看到Nicholas Zakas在这里写了很多其他的解决方案,如果for循环不在if else if"块"中,这些解决方案就会起作用。当我第一次尝试将它包装在setTimeout函数中时,它当然不起作用,因为if else if的第二部分解析为true。
(oSettings.sAjaxSource === null && oSettings.ajax === null) // true
这个问题有什么好的解决方案?
我想你可以把你的函数分成3个函数:
- if语句之前
- 处理init . aadata
- if语句之后
下面的代码分为三个函数:
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
}
谢谢@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()));
我没有使用私有的_fnAddData函数,而是选择了datatable的公共fnAddData (http://datatables.net/ref#fnAddData)函数。这样,我就能够一次将50行推入存储在tickApp中的表中。$orders对象,我只是引用我的jQuery对象,存储表在内存中:
tickApp.$orders = $('#orders');
在我代码的另一部分。他们的方式仍然是一次推1行,而不是整个50行。
再次感谢。
如果你使用ajax来获取数据,你可以在你的数据表配置对象中覆盖"fnServerData"。这将允许您获取要加载的数据,然后按照您想要的方式处理它。
在我的情况下,我有一个通用的数据表配置对象,我使用我所有的数据表。我覆盖了默认的fnServerData函数,它使用fnAddData和setTimeout将200行的数据传递给数据表,再次调用该函数,直到所有数据都被处理,最后我调用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);
});
}}
我使用的是1.9.4版本的数据表
- 我一直收到的控制台警告是什么?推迟长时间运行的计时器任务以提高滚动的流畅性
- 如何使用 javascript 停止对 asp.net 进行正在进行的回发(长时间运行的执行)
- 如何修复长时间运行的脚本
- 长时间运行的脚本IE与Chrome/Firefox
- 有没有一种方法可以在长时间运行的JavaScript操作之前强制回流
- 我可以/如何显式终止长时间运行的 xhr 请求
- AJAX 可访问的长时间运行的服务任务阻止在启用 ASP.NET 兼容性/会话的环境中的后续 AJAX 服务请求
- JQuery新手:长时间运行的函数需要setTimeout吗
- Javascript:在长时间运行的Javascript函数期间显示Throbber
- 长时间运行的AJAX请求在几分钟后重新提交
- JavaScript和UI响应中的长时间运行循环
- spin.js没有'它不会在长时间运行的任务中显示,但当我逐步通过调试器时会显示
- 谷歌分析是否有一个“;心跳;用于长时间运行的web应用程序的功能
- DOM操作被长时间运行的func阻塞,之后调用
- 如何在长时间运行的事件中更新页面元素
- 使用数据表时,IE8长时间运行脚本错误
- 对长时间运行的函数进行DOM刷新
- 如何在长时间运行的服务器操作期间与用户交互(例如确认对话框)
- Javascript -我希望在长时间运行的函数运行之前显示复选框
- 如何在javascript中分解长时间运行的函数,但保持性能