我需要做与这篇文章相反的"Best way to iterate over an array without blocking the UI“
我必须遍历数百行并为每个行设置一个值。但是,在我允许用户执行下一步并将更新的行提交到数据库之前,该作业必须完成。
javascript在下面。
// toolbar events/actions
changeZeroDiscountButton.click(function (event) {
var value = discountComboBox.jqxComboBox('val');
if ((value != null) && (value != "")) {
value = value / 100;
// get all the rows (this may have to be changed if we have paging
var datainformations = $('#jqxgrid').jqxGrid('getdatainformation');
var rowscounts = datainformations.rowscount;
for (var i = 0; i < rowscounts; i++) {
var preSetDiscount = $("#jqxgrid").jqxGrid('getcellvalue', i, "discount");
if (preSetDiscount == .0000) {
$("#jqxgrid").jqxGrid('setcellvalue', i, "discount", value);
}
}
}
});发布于 2016-07-31 05:31:17
JavaScript的设计使其不以任何方式阻止UI,这是浏览器最重要的特性之一。唯一的例外是弹出消息框(即alert()、confirm()和propmpt())。即使有可能,也不建议阻止UI。
有许多其他方法可以防止用户触发在发生其他事情之前不应该触发的操作。示例:
var processing = true)并在操作按钮的单击事件中检查该标志,以便它显示一条消息(例如,“仍在处理,请等待.”)当标志为true时,当标志为false时执行操作。记住不要对消息使用alert(),否则您将阻止处理。使用弹出div代替。alert(),否则您将阻止处理。使用弹出div代替。div,其中包含一条消息(例如,“仍在处理,请等待.”)、进度条或一些动画。模式弹出阻止用户与页面交互,因此他们不能单击任何内容。要使其工作,模式弹出不能有关闭按钮或任何其他方式关闭它。在处理结束时,关闭模式弹出,以便用户现在可以继续。重要注意事项:您在评论中提到的覆盖(与我最后一点中的模式弹出类似)直到处理结束时才会显示。这是因为您的处理占用了处理器,并阻止它处理UI线程。当你能做的是延迟你的处理。因此,首先显示模态弹出(或覆盖),然后使用setTimeout()在1秒后开始处理(可能500毫秒甚至更少就足够了)。这使处理器有足够的时间在UI线程开始长时间处理之前处理它。
这里的编辑是最后一个方法的示例:
function start() {
disableUI();
setTimeout(function() {
process();
}, 1000);
}
function process() {
var s = (new Date()).getTime();
var x = {};
for (var i = 0; i < 99999; i++) {
x["x" + i] = i * i + i;
}
var e = new Date().getTime();
$("#results").text("Execution time: " + (e - s));
enableUI();
}
function disableUI() {
$("#uiOverlay").dialog({
modal: true,
closeOnEscape: false,
dialogClass: "dialog-no-close",
});
}
function enableUI() {
$("#uiOverlay").dialog("close");
}.dialog-no-close .ui-dialog-titlebar {
display: none;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<button type="button" onclick="start()">Start</button>
<div id="results"></div>
<div id="uiOverlay" style="display: none;">Processing... Please wait...</div>
这里的编辑2是第三种方法的示例:
$("#StartButton").on("click", start);
function start() {
//remove all previous click events
$("#StartButton").off("click");
//set the click event to show the message
$("#StartButton").on("click", showProcessingMsg);
//clear the previous results
$("#results").text("");
setTimeout(function() {
process();
}, 1000);
}
function process() {
var s = (new Date()).getTime();
var x = {};
for (var i = 0; i < 99999; i++) {
x["x" + i] = i * i + i;
}
var e = new Date().getTime();
$("#results").text("Execution time: " + (e - s));
//remove all previous click events
$("#StartButton").off("click");
//set the click event back to original
$("#StartButton").on("click", start);
}
function showProcessingMsg() {
$("#results").text("Still processing, please wait...");
}.dialog-no-close .ui-dialog-titlebar {
display: none;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="StartButton">Start</button>
<div id="results"></div>
发布于 2016-07-30 05:49:58
如果是长循环浏览器本身就会阻止所有其他事件。您可能只是体验冻结浏览器。
那不是一次好的经历。
您可以使用这样的Overlay来覆盖UI,并将操作通知用户。
https://stackoverflow.com/questions/38670610
复制相似问题