在 IE 中显示长 运行 循环的进度条
showing Progress bar on long running for loops in IE
我有一个包含大约 2000 条记录的 JSON 数组,我需要构建一个 table 来显示来自这些 records.As 的数据,处理可能会导致大量数据浏览器 freeze.So 我被要求显示一个指示进度的进度条。 Javascript 是单线程我必须使用 Setinterval 来显示 progress.But 在 IE 版本中进度未正确显示,具体取决于数组中的记录数。
请帮助
var g_arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
$("#btn").click(function() {
var Loop = 1000;
$("#tbl tbody td").remove();
$("#divProgress").progressbar({
value: 0
});
//window.setTimeout(function(){
for (var i = 0; i < Loop; i++) {
var TR = $("<tr>");
$.each(g_arr, function(index, val) {
var TD = $("<td>");
TD.append(val);
TR.append(TD);
});
window.setTimeout(function() {
$("#divProgress").progressbar({
value: (i / Loop) * 100
});
}, 3000);
$("#tbl tbody").append(TR);
}
//},0);
});
td,
th,
table {
border-color: black;
border-width: thin;
border-style: solid;
border-collapse: collapse;
}
<link href="http://code.jquery.com/ui/1.10.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<div id="divProgress"></div>
<div id="divBody">
<input type="button" id="btn" value="Click Here" />
<table id="tbl">
<thead>
<tr>
<th>
Column1
</th>
<th>
Column2
</th>
<th>
Column3
</th>
<th>
Column4
</th>
<th>
Column5
</th>
<th>
Column6
</th>
<th>
Column7
</th>
<th>
Column8
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
在此处输入代码
您做错了几件事:
- 在执行 DOM 操作时避免长
for
循环,这非常昂贵。
请改用 requestAnimationFrame。请求动画帧
基本上指示您希望执行动画的浏览器
(或某种计算)并请求浏览器调用
下一次重绘之前的指定函数。换句话说,它就像
一个 for
循环,但每个循环迭代仅在浏览器运行时运行
决定(何时可以绘画)。
- 您正在创建 1000 个不必要的
$("#divProgress")
个对象。使用缓存。创建一个单一的
$progressBar
然后使用1000次。 $("#tbl tbody")
被创建 1000 次时出现同样的问题。
- 您正在创建 1000 个
进度条插件实例。你正在做的方式:
$progressBar.progressbar({ value: (i / Loop) * 100})
是一个
创建具有该值的新进度条实例的构造函数。
使用 setter,而不是构造函数:
$progressBar.progressbar("value", (i / Loop) * 100)
.
var g_arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
$("#btn").click(function() {
var i = 0,
Loop = 1000,
$progressBar = $("#divProgress"),
$body = $("#tbl tbody"),
requestAnimationFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
doRequestFrame = function () {
if (i++ < Loop) {
$progressBar.progressbar("value", (i / Loop) * 100);
var $newRow = $("<tr>");
$.each(g_arr, function(index, val) {
$newRow.append($("<td>").append(val));
});
$body.append($newRow);
if (requestAnimationFrame) {
// hey browser, please call again doRequestFrame() when you are idle (before repaint)
requestAnimationFrame(doRequestFrame);
} else {
setTimeout(doRequestFrame, 1);
}
}
};
$("#tbl tbody td").remove();
$progressBar.progressbar({
value: 0
});
// hey browser, please call doRequestFrame() when you are idle (before repaint)
requestAnimationFrame ? requestAnimationFrame(doRequestFrame) : doRequestFrame();
});
td,
th,
table {
border-color: black;
border-width: thin;
border-style: solid;
border-collapse: collapse;
}
<link href="http://code.jquery.com/ui/1.10.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<div id="divProgress"></div>
<div id="divBody">
<input type="button" id="btn" value="Click Here" />
<table id="tbl">
<thead>
<tr>
<th>
Column1
</th>
<th>
Column2
</th>
<th>
Column3
</th>
<th>
Column4
</th>
<th>
Column5
</th>
<th>
Column6
</th>
<th>
Column7
</th>
<th>
Column8
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
支持旧版 IE
如果 requestAnimationFrame
未定义(IE9 及以下版本会发生这种情况),我将手动调用 doRequestFrame
。
我有一个包含大约 2000 条记录的 JSON 数组,我需要构建一个 table 来显示来自这些 records.As 的数据,处理可能会导致大量数据浏览器 freeze.So 我被要求显示一个指示进度的进度条。 Javascript 是单线程我必须使用 Setinterval 来显示 progress.But 在 IE 版本中进度未正确显示,具体取决于数组中的记录数。 请帮助
var g_arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
$("#btn").click(function() {
var Loop = 1000;
$("#tbl tbody td").remove();
$("#divProgress").progressbar({
value: 0
});
//window.setTimeout(function(){
for (var i = 0; i < Loop; i++) {
var TR = $("<tr>");
$.each(g_arr, function(index, val) {
var TD = $("<td>");
TD.append(val);
TR.append(TD);
});
window.setTimeout(function() {
$("#divProgress").progressbar({
value: (i / Loop) * 100
});
}, 3000);
$("#tbl tbody").append(TR);
}
//},0);
});
td,
th,
table {
border-color: black;
border-width: thin;
border-style: solid;
border-collapse: collapse;
}
<link href="http://code.jquery.com/ui/1.10.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<div id="divProgress"></div>
<div id="divBody">
<input type="button" id="btn" value="Click Here" />
<table id="tbl">
<thead>
<tr>
<th>
Column1
</th>
<th>
Column2
</th>
<th>
Column3
</th>
<th>
Column4
</th>
<th>
Column5
</th>
<th>
Column6
</th>
<th>
Column7
</th>
<th>
Column8
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
在此处输入代码
您做错了几件事:
- 在执行 DOM 操作时避免长
for
循环,这非常昂贵。 请改用 requestAnimationFrame。请求动画帧 基本上指示您希望执行动画的浏览器 (或某种计算)并请求浏览器调用 下一次重绘之前的指定函数。换句话说,它就像 一个for
循环,但每个循环迭代仅在浏览器运行时运行 决定(何时可以绘画)。 - 您正在创建 1000 个不必要的
$("#divProgress")
个对象。使用缓存。创建一个单一的$progressBar
然后使用1000次。$("#tbl tbody")
被创建 1000 次时出现同样的问题。 - 您正在创建 1000 个
进度条插件实例。你正在做的方式:
$progressBar.progressbar({ value: (i / Loop) * 100})
是一个 创建具有该值的新进度条实例的构造函数。 使用 setter,而不是构造函数:$progressBar.progressbar("value", (i / Loop) * 100)
.
var g_arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
$("#btn").click(function() {
var i = 0,
Loop = 1000,
$progressBar = $("#divProgress"),
$body = $("#tbl tbody"),
requestAnimationFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
doRequestFrame = function () {
if (i++ < Loop) {
$progressBar.progressbar("value", (i / Loop) * 100);
var $newRow = $("<tr>");
$.each(g_arr, function(index, val) {
$newRow.append($("<td>").append(val));
});
$body.append($newRow);
if (requestAnimationFrame) {
// hey browser, please call again doRequestFrame() when you are idle (before repaint)
requestAnimationFrame(doRequestFrame);
} else {
setTimeout(doRequestFrame, 1);
}
}
};
$("#tbl tbody td").remove();
$progressBar.progressbar({
value: 0
});
// hey browser, please call doRequestFrame() when you are idle (before repaint)
requestAnimationFrame ? requestAnimationFrame(doRequestFrame) : doRequestFrame();
});
td,
th,
table {
border-color: black;
border-width: thin;
border-style: solid;
border-collapse: collapse;
}
<link href="http://code.jquery.com/ui/1.10.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<div id="divProgress"></div>
<div id="divBody">
<input type="button" id="btn" value="Click Here" />
<table id="tbl">
<thead>
<tr>
<th>
Column1
</th>
<th>
Column2
</th>
<th>
Column3
</th>
<th>
Column4
</th>
<th>
Column5
</th>
<th>
Column6
</th>
<th>
Column7
</th>
<th>
Column8
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
支持旧版 IE
如果 requestAnimationFrame
未定义(IE9 及以下版本会发生这种情况),我将手动调用 doRequestFrame
。