我正在尝试为我的网站制作一个加载器动画样式。加载动画是16条,按顺序增加和减少。例如,第一个柱将增加然后减小回原始大小。然后下一个栏将重复此过程,直到所有栏完成,然后停止该过程并显示页面。在这种情况下,因为JavaScript在调用函数时是异步的,所以我使用了一个承诺绕过它。承诺的使用是在前一个完成动画之后为该动画设置动画。目前,我的代码仅动画第一个栏并停在那里。它不会继续为其余部分制作动画。以下是我的所有代码:
重要! 它在javascript上的问题。不要花时间在HTML或CSS上。
var index = -1;
function loading(){
var loader = document.getElementById("loader");
display = window.getComputedStyle(loader).display;
if (display == "block"){
var child = document.getElementById("loader-ul").getElementsByTagName("div");
index = index + 1;
alert("dd");
animate(child);
}
}
function animate(element){
var el = element[index];
var MaxHeight = false;
var finished = false;
function anim(){
return new Promise(function(resolve, reject){
if (finished == false){
if (MaxHeight == false){
var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
height = height + 1;
Bot = Bot + 0.5;
el.style.bottom = Bot + "px";
el.style.height = height + "px";
if (height <= 100){
window.requestAnimationFrame(anim);
}
else{
MaxHeight = true;
}
}
if (MaxHeight == true){
var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
height = height - 1;
Bot = Bot - 0.5;
el.style.bottom = Bot + "px";
el.style.height = height + "px";
if (height >= 50){
window.requestAnimationFrame(anim);
}
else{
MaxHeight = true;
finished = true;
el.style.bottom = 0 + "px";
el.style.height = 50 + "px";
}
}
}
else{
resolve();
}
});
}
anim().then(loading);
}
body{
margin: 0px;
padding: 0px;
margin: auto;
}
#loader{
display: block;
position: fixed;
height: 100%;
width: 100%;
background-color: white;
z-index: 9999;
}
#loader .center{
position: relative;
height: 50px;
width: 200px;
background-color: red;
top: 50%;
transform: translateY(-50%);
margin: auto;
}
#loader .center div{
width: 2px;
height: 50px;
background-color: blue;
float: left;
padding: 0px;
margin-right: 5px;
margin-bottom: 25px;
position: relative;
}
<body onload="loading()">
<div id="loader">
<div class="center" id="loader-ul">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</body>
我还有一个指向jsfiddle的链接:
https://jsfiddle.net/6227jjen/
谢谢大家!
注意: 我为调试目的添加了一些警报。
答案 0 :(得分:1)
问题在于并非所有路径都能解决问题。更大的问题是你的代码创造了许多承诺而不是一个承诺。以下是变化的概要。
function anim () {
return new Promise (function (resolve) {
function _anim () {
if (!finished) {
_logic();
// By putting requestAnimationFrame at the end, you can ensure
// that it will be called after your logic
// (assuming finished eventually equals true).
window.requestAnimationFrame(_anim);
}
else
resolve();
}
});
这是实际修复。
var index = -1;
function loading() {
var loader = document.getElementById("loader");
display = window.getComputedStyle(loader).display;
if (display == "block") {
var child = document.getElementById("loader-ul").getElementsByTagName("div");
index = index + 1;
alert("dd");
animate(child);
}
}
function animate(element) {
var el = element[index];
var MaxHeight = false;
var finished = false;
function anim() {
return new Promise(function(resolve, reject) {
function _anim() {
if (finished == false) {
if (MaxHeight == false) {
var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
height = height + 1;
Bot = Bot + 0.5;
el.style.bottom = Bot + "px";
el.style.height = height + "px";
if (height > 100) {
MaxHeight = true;
}
}
if (MaxHeight == true) {
var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
height = height - 1;
Bot = Bot - 0.5;
el.style.bottom = Bot + "px";
el.style.height = height + "px";
if (height < 50) {
MaxHeight = true;
finished = true;
el.style.bottom = 0 + "px";
el.style.height = 50 + "px";
}
}
window.requestAnimationFrame(_anim);
} else {
resolve();
}
}
_anim();
});
}
anim().then(loading);
}
&#13;
body {
margin: 0px;
padding: 0px;
margin: auto;
}
#loader {
display: block;
position: fixed;
height: 100%;
width: 100%;
background-color: white;
z-index: 9999;
}
#loader .center {
position: relative;
height: 50px;
width: 200px;
background-color: red;
top: 50%;
transform: translateY(-50%);
margin: auto;
}
#loader .center div {
width: 2px;
height: 50px;
background-color: blue;
float: left;
padding: 0px;
margin-right: 5px;
margin-bottom: 25px;
position: relative;
}
&#13;
<body onload="loading()">
<div id="loader">
<div class="center" id="loader-ul">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</body>
&#13;
答案 1 :(得分:0)
致电window.requestAnimationFrame(anim);
永远不会解决您的承诺。它将调用anim
,这将创建另一个承诺,如果你已经完成,可能会得到解决,但最初的承诺永远不会实现。
不应该将anim
的整个主体包裹在new Promise
构造函数中,而应该仅对requestAnimationFrame
进行委托,然后使用它来构建承诺链。
function animate(element){
var el = element[index];
var MaxHeight = false;
var finished = false;
function getFrame() {
return new Promise(function(resolve) {
window.requestAnimationFrame(resolve);
});
}
function anim(){
if (finished == false){
if (MaxHeight == false){
var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
height = height + 1;
Bot = Bot + 0.5;
el.style.bottom = Bot + "px";
el.style.height = height + "px";
if (height <= 100){
return getFrame().then(anim);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
} else{
MaxHeight = true;
}
}
if (MaxHeight == true){
var height = parseInt(window.getComputedStyle(el).height.slice(0, -2));
var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2));
height = height - 1;
Bot = Bot - 0.5;
el.style.bottom = Bot + "px";
el.style.height = height + "px";
if (height >= 50){
return getFrame().then(anim);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
} else{
MaxHeight = true;
finished = true;
el.style.bottom = 0 + "px";
el.style.height = 50 + "px";
}
}
}
return Promise.resolve();
}
return anim().then(loading);
}