有没有一种方法可以在长时间运行的JavaScript操作之前强制回流
Is there a way to force a reflow before a long-running JavaScript operation?
准备好面对反弹了,因为我知道这是一个经常被问到的问题,并且充分意识到有"更好"的方法来实现我想要实现的目标。。。
我在一个函数中有一个长时间运行的JavaScript操作,它可能需要10秒才能运行。我有一个"加载div",可以随意显示和隐藏。通常,这个显示/隐藏操作工作得很快,但如果我试图在与长期运行的函数相同的调用链中这样做,浏览器就没有机会在被长期运行的功能锁定之前回流并显示加载的div。
我试过:
1-只显示div,然后调用函数:
$('#loadingDiv').show();
longRunningFunction();
2-显示div,然后在当前函数完成后执行的setTimeout内调用长时间运行的函数:
$('#loadingDiv').show();
setTimeout(function(){longRunningFunction();}, 0);
3-与2相同,但超时时间更长:
$('#loadingDiv').show();
setTimeout(function(){longRunningFunction();}, 100);
有了更长的超时时间(比如5000毫秒),我就可以显示加载屏幕,并正确执行我的长时间运行功能——但很明显,这增加了执行时间,我想这不会与跨浏览器兼容(碰巧我使用的浏览器在这XXXX毫秒内进行了重新绘制——另一个浏览器可能不会?)
我还尝试了在SO和其他地方看到的各种技巧,比如更改页面上div上的offsetLeft
/offsetTop
,更改self.status
,但我所做的一切似乎都有相同的效果:用页面上的旧内容锁定浏览器几秒钟,然后在长时间运行的函数完成后显示加载的div。
我知道我所做的是"错误的",但这正是我此刻想做的——最终我会:
1) 将此代码分解为更小的块
2) 可能将其移动到Web Worker中
3) 加快速度,这样就不会花那么长时间,也不会锁定浏览器
但是目前有人能建议一种简单的方法,在我的长期运行操作运行之前,强制向用户显示"loadingdiv"吗?
使用回调:
$('#loadingDiv').show("fast", longRunningFunction);
这将在显示div之后调用您的函数。
我可能会建议为此目的使用jquery的延迟功能。延迟对象是为此而创建的,您可以在http://net.tutsplus.com/tutorials/javascript-ajax/wrangle-async-tasks-with-jquery-promises/
我制作了一个样品小提琴,向你展示它是如何使用的。http://jsfiddle.net/Nemesis02/PH2nE/1/
以下是如何编写JavaScript的
(function($) {
function initLongWait() {
var deferred = new $.Deferred();
setTimeout(function() {
deferred.resolve();
}, 2000);
return deferred.promise();
}
var promise = initLongWait();
$('#wait').fadeIn();
initLongWait().done(function() {
$('#wait').fadeOut();
$('#done').fadeIn();
});
})(jQuery);
jsFiddle Demo
你可以采取你在#2中使用的方法,它应该有效。
$("#loadingDiv").show();
setTimeout(function(){
longRunningFunction();
$("#loadingDiv").hide();
},10);
- 操作javascript变量[HTML]以只显示文本
- 如何使用keyup或input进行操作?javascript(jQuery)
- RubyonRails环境控制器操作JavaScript响应
- 在替换之前,操作javascript正则表达式匹配,例如$1
- 每次 iframe 重新导航时执行操作.(JavaScript)
- 使用下划线操作 JavaScript 对象
- 如何阻止 confirm() 的默认操作 JavaScript
- 结束游戏的逻辑操作 Javascript
- 操作 JavaScript 日期对象
- CSS 样式操作:Javascript 不起作用
- 镜像/复制鼠标操作 JavaScript
- 使用Java操作JavaScript
- 操作JavaScript数组
- 循环遍历无序列表并对每个节点执行操作Javascript
- 操作Javascript数据在D3.js上切换系列
- 如何通过在检查器中操作Javascript来抓取表?页面仅显示当前日期's的数据,但我想回到过去,重新收集
- 从java操作Javascript对象
- 更改默认键操作JavaScript
- 使用Jquery $.each()操作Javascript对象
- 是否有一种方法可以使用JS或jQuery来操作JavaScript表单