也许我应该改进我的榜样。
function doSomethingHeavy() {
// emulate do something heavy
var now = new Date().getTime();
while (new Date().getTime() < now + 5000) {
// do nothing
}
}
$("#testButton").bind("click.performTest", function () {
$("#loading").show();
doSomethingHeavy();
$("#loading").hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" id="testButton">Perform Test</button>
<div id="loading" style="display:none" >Loading</div>
我假设显示加载被调用然后doSomethingHeavy,之后隐藏加载。但是,装完后会显示并隐藏......
答案 0 :(得分:1)
问题是CGRect
函数,它将执行线程保持5秒钟。
在javascript中,脚本执行和ui刷新都发生在一个线程中,因此如果您运行脚本直到完成,UI将不会更新。
所以你的apply
函数在调用show之后很快就会持有执行线程,因此不会执行UI中元素的显示。
因此,要延迟项目的执行,而不是使用基于硬编码apply
循环的延迟,请使用如下所示的计时器。
while
&#13;
function show() {
return $("#loading").show().promise();
}
function hide() {
return $("#loading").hide().promise();
}
function start() {
return $.when(show()).then(apply).then(hide);
}
function apply() {
var deferred = $.Deferred();
var now = new Date().getTime();
setTimeout(function() {
deferred.resolve();
}, 5000)
return deferred.promise();
}
start();
&#13;
但是jQuery-ish解决方案就像
一样简单
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="loading" style="display:none">Loading</div>
&#13;
function start() {
return $("#loading").show().delay(5000).hide(0);
}
start();
&#13;
答案 1 :(得分:1)
@ jfriend00的答案应该有效。但使用window.setTimeout
是不可靠的。刚刚使用CPU速度慢/内存不足的VM进行检查,window.setTimeout
15ms无法正常工作......
要获得更可靠的方法,您可以尝试使用window.requestAnimationFrame
来保证重绘/重排事件的发生。
$(document).ready(function () {
function showLoading() {
$("#loading").show();
}
function hideLoading() {
$("#loading").hide();
}
function performTest() {
showLoading();
window.requestAnimationFrame(function () {
// redraw/ reflow occurred for #loading to show...
window.requestAnimationFrame(function () {
doSomethingHeavy(4000);
hideLoading();
});
});
}
function doSomethingHeavy(processTime) {
// emulate do something heavy
var start = +new Date();
while (+new Date() - start < processTime) {
// do nothing
}
}
$("#testButton").bind("click.performTest", performTest);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" id="testButton">Perform Test</button>
<div id="loading" style="display: none">Loading... (this will disappear in 4 seconds)</div>
&#13;
使用嵌套window.requestAnimationFrame
来包装doSomethingHeavy
是奇怪的而且不直观,也许值得使用promise模式......
$(document).ready(function () {
function showLoading() {
var deferred = $.Deferred();
window.requestAnimationFrame(function () {
$("#loading").show();
// ensure the redraw/ reflow occurred, then resolve the callback
window.requestAnimationFrame(function () {
deferred.resolve();
});
});
return deferred.promise();
}
function hideLoading() {
var deferred = $.Deferred();
window.requestAnimationFrame(function () {
$("#loading").hide();
// ensure the redraw/ reflow occurred, then resolve the callback
window.requestAnimationFrame(function () {
deferred.resolve();
});
});
return deferred.promise();
}
function performTest() {
$.when(showLoading()).then(function () {
doSomethingHeavy(4000);
}).done(hideLoading);
}
function doSomethingHeavy(processTime) {
// emulate do something heavy
var start = +new Date();
while (+new Date() - start < processTime) {
// do nothing
}
}
$("#testButton").bind("click.performTest", performTest);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" id="testButton">Perform Test</button>
<div id="loading" style="display: none">Loading... (this will disappear in 4 seconds)</div>
&#13;
答案 2 :(得分:0)
也许您应该检查.delay()
功能。
以下是使用它的示例:
var DELAY = 1000,
ANIMATION_DURATION = 500;
var loading = {
elm: function() {
return $('#loading').delay(DELAY);
},
show: function() {
loading.elm().fadeIn(ANIMATION_DURATION);
},
hide: function() {
loading.elm().fadeOut(ANIMATION_DURATION);
}
};
loading.show();
setTimeout(loading.hide, 2000);
&#13;
#loading {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #ccc;
display: none;
}
&#13;
<div id="loading"></div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
&#13;