我有一个加载数据的页面(它将使用AJAX),因此我想显示“正在加载,请稍候”消息。现在,我正在使用循环来模拟网络延迟。我使用JQuery设置和显示消息,但是直到循环完成后才显示。我需要做什么来“刷新” JQuery命令,以便在调用循环之前显示消息?
我在下面提供了骨骼CSS,HTML和JQuery / JavaScript。
<!DOCTYPE html>
<html>
<head>
<style>
.ais-card-message {
padding: 6px;
margin-top: 6px;
margin-bottom: 6px;
text-align: left;
}
.ais-card-message-info {
background-color: lightskyblue;
}
.ais-card-message-warn {
background-color: lightpink;
}
</style>
</head>
<body>
<div id="title">
<p>Message "Loading, please wait ..." should appear below when button clicked.
Followed by either "Error" or "Loaded" after a short delay.</p>
</div>
<div id="data">Data will be loaded here</div>
<div id="msgBox" class="ais-card-message">Messages should display here</div>
<div><button id="btnLoad">Load</button></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
function showMsg(msg, type) {
// msg is message to display. type is either "info" or "warn"
$('#msgBox').removeClass("ais-card-message-info ais-card-message-warn");
$('#msgBox').addClass("ais-card-message-" + type);
$('#msgBox').text(msg);
$('#msgBox').show();
return
}
$('#btnLoad').click(function(){
// For some reason the following message doesn't display
showMsg('Loading, please wait ...', 'info');
if (!loadData()) {
// But this message does display if loadData returns false
showMsg('Error', 'warn');
return
}else{
// and this message also displays if loadData returns true
showMsg('Loaded', 'info');
return
}
});
function loadData() {
// Just a loop to simulate network delay
var i;
for (i=0; i < 100000; i++) {
var j;
for (j=0; j < 100000; j++) {
var k = Math.sqrt(j);
}
}
$('#data').text("Here is some dummy data");
return true
}
});
</script>
</body>
</html>
答案 0 :(得分:1)
您的代码中有几个问题。首先,在“模拟” AJAX请求中,您正在使用循环。这是同步操作,也是导致无法更新UI的问题的原因。循环正在停止执行任何其他操作(即DOM中元素的更新)。因此,它似乎仅在循环完成后才更新。
其次,一旦您实际上开始在loadData()
函数中使用AJAX请求,您将遇到同步问题,因为您期望布尔值返回值指示AJAX请求是否有效。这对于异步逻辑是不可能的。因此,您需要使用Promise和/或回调。
为此,您需要在$.ajax()
函数中从loadData()
返回承诺。然后,您可以使用done()
和fail()
方法根据请求的结果来更新DOM。它应该看起来像这样:
$('#btnLoad').click(function() {
showMsg('Loading, please wait ...', 'info');
loadData().done(function() {
showMsg('Loaded', 'info');
}).fail(function() {
showMsg('Error', 'warn');
});
});
function loadData() {
return $.ajax({
url: '/yourpage',
data: {
foo: 'bar'
}
});
}
下面是一个工作示例,该示例通过3秒钟后手动解析延迟的对象来模拟AJAX请求。由于正确使用了异步逻辑,您可以看到正在正确显示加载消息。
$(document).ready(function() {
function showMsg(msg, type) {
$('#msgBox')
.removeClass("ais-card-message-info ais-card-message-warn")
.addClass("ais-card-message-" + type)
.text(msg)
.show();
}
$('#btnLoad').click(function() {
showMsg('Loading, please wait ...', 'info');
loadData().done(function() {
showMsg('Loaded', 'info');
}).fail(function() {
showMsg('Error', 'warn');
});
});
function loadData() {
// mock AJAX request, just for this demo
var deferred = jQuery.Deferred();
setTimeout(function() {
deferred.resolve();
}, 3000);
return deferred;
}
});
.ais-card-message {
padding: 6px;
margin-top: 6px;
margin-bottom: 6px;
text-align: left;
}
.ais-card-message-info {
background-color: lightskyblue;
}
.ais-card-message-warn {
background-color: lightpink;
}
<div id="title">
<p>Message "Loading, please wait ..." should appear below when button clicked. Followed by either "Error" or "Loaded" after a short delay.</p>
</div>
<div id="data">Data will be loaded here</div>
<div id="msgBox" class="ais-card-message">Messages should display here</div>
<div><button id="btnLoad">Load</button></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>