在进行同步Ajax调用之前,我需要制作一个覆盖整个屏幕的div。
但是似乎绝对没有我尝试做的事情导致DOM被修改以在ajax调用之前显示此div。屏幕将“冻结”,并且只有在执行了ajax调用之后才显示div。
我已经尝试了成千上万种方法,但是似乎只有在DOM修改后(显示div),才能使ajax运行。
HTML
[...]
<body>
<div id="loadingDiv" style="display: none; width: 100%; height: 100%; background-color: #004000; position: absolute; z-index:10000;"></div>
[...]
javascript
[...]
$("#loadingDiv").css("display", "block");
var ajaxOp;
$.ajax({
type: someType,
url: someUrl,
data: someData,
dataType: someDataType,
async: false,
success: function (someArg) {
ajaxOp = someArg;
},
error: function (someArg0, someArg1, someArg2) {
// do something
}
});
return ajaxOp;
[...]
注意我::我正在使用JQuery。
注意II:不能将“ ajaxOp”定义为“ undefined”。
更新:希望对理解有所帮助,并应@Felipe Dutra Ferreira的要求,在下面的更新中针对该问题进行了更多解释...
真实案例:我有一个带有多个旧代码的应用程序,这些旧代码消耗了libray js,而该函数又进行了ajax调用(我们称之为“ certainfunction”)。我们正在尝试更新此应用程序,以使其在ajax调用期间显示“加载屏幕”(而不仅仅是在这些调用期间“锁定” UI)。因此,处理此问题的最简单方法是在对“ certainfunction”的调用之后以及在运行ajax调用之前显示“加载屏幕”。还要注意,“ certainfunction”返回ajax调用的输出,并且一旦不同步执行此调用,该输出将是“ undefined”,也就是说,只有在此ajax调用具有输出之后,代码才能继续。
答案 0 :(得分:2)
我为您写了以下内容。
请查看我的GITHUB中的以下示例
因为我有一个完整的示例,我已尽力为您提供帮助。 在这里,您将看到Jquery CallBack Methods和Promise框架的使用,这似乎是您遇到的问题。请回覆我,让我知道这是否是最终解决方案,因为我决心为您提供帮助。
单击JSBin查看我的示例=> https://jsbin.com/xeloful/edit?html,output
<body onload="myFunction()" style="margin:0;"></body>
我想引起您的注意如果您仍需要帮助,请与我们联系...还是没有帮助...
或者您可以在StackOverflow上运行此代码段。下面,我使用的是$(myFunction)
而不是onload="myFunction()"
,这对jQuery用户而言更为常规。点击下面的“运行代码段”以查看结果。
function showPage() {
document.getElementById("loader").style.display = "none";
document.getElementById("myDiv").style.display = "block";
};
function myFunction() {
//Showing a Div prior to call as promised...
$("#redSquare").fadeIn(3000).fadeOut(3000, function () {
//Making the following API Call that will receive a random email from a random user...
$.ajax({
url: 'https://randomuser.me/api/',
dataType: 'json',
success: showPage
}).done(function (res, req) {
//Spitting out information about the HTTP call made...
console.log(res);
console.log(req);
//Storing the email in the following variable...
var RandomEmail = res.results[0].email;
//Displaying the email in the console...
console.log(RandomEmail);
//Injecting the following email to the DOM
document.getElementById("randomEmail").innerHTML = RandomEmail;
});
});
}
//When the body loads, render this function as seen in the body HTML tag with the onload... This is the jQuery way to do it...
$(myFunction);
#redSquare {
display: none;
width: 100vw;
height: 100vh;
background-color: crimson;
}
/* Center the loader */
#loader {
position: absolute;
left: 50%;
top: 50%;
z-index: 1;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* Add animation to "page content" */
.animate-bottom {
position: relative;
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 1s;
animation-name: animatebottom;
animation-duration: 1s
}
@-webkit-keyframes animatebottom {
from {
bottom: -100px;
opacity: 0
}
to {
bottom: 0px;
opacity: 1
}
}
@keyframes animatebottom {
from {
bottom: -100px;
opacity: 0
}
to {
bottom: 0;
opacity: 1
}
}
#myDiv {
display: none;
text-align: center;
}
#randomEmail {
color: white;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="redSquare">
<!--Making this Appear for 3 Seconds prior to Ajax...-->
</div>
<div id="loader"></div>
<div style="display:none;" id="myDiv" class="animate-bottom">
<h2>Tada!</h2>
<p>Some text in my newly loaded page..</p>
<h1>
RandomEmail: <span id="randomEmail"></span>
</h1>
</div>
答案 1 :(得分:0)
一种解决方法是使用下面的功能,当我们进行同步呼叫(“ ajax”)时,该功能允许在系统上显示“正在加载屏幕”。可以很容易地将其修改为与旧版代码一起使用。
认识到即使在此调用之前执行了“ ajax”也会阻止对“ DOM”的修改。如果此方法仅在之前涉及某个同步ajax调用的进程的第一时间使用,则该方法才有效。基本上,它会在执行所需功能/方法(“ appFunc”)之前创建一个时间窗口(50毫秒)以更新DOM。仅在需要在执行同步ajax调用后立即使用输出的情况下,才可以使用此功能。
使用示例:<button type="button" onclick="opSyncLoading(login, [this.form])">
提示::请注意,如果“加载屏幕”上有动画gif,它将被“锁定”,直到完成“ ajax”调用为止,但是在某些现代浏览器中,此问题不会解决发生。在极端情况下,如果将图像加载到iframe(https://stackoverflow.com/a/16704839/3223785)中,则该图像可能会保持“动画”状态。
function opSyncLoading(appFunc, appFuncArgs) {
if (typeof appFuncArgs === "undefined" || appFuncArgs === "") {
appFuncArgs = [];
}
$("#loadingDiv").fadeIn(500, setTimeout(function () {
// NOTE: Passing unknown arguments in quantity and nature to a callback function. By Questor
// [Ref.: https://stackoverflow.com/a/49680525/3223785 ]
appFunc.apply(this, appFuncArgs);
}, 50));
}
谢谢! = D