2016-09-24 145 views
2

我想为我的网站制作加载器动画样式。加载动画是16个条形,按顺序增加和减少。例如,第一个小节会增加,然后回到原始大小。然后下一个小节将重复这个过程,直到所有小节完成它,然后停止该过程并显示页面。在这种情况下,因为JavaScript在调用函数上是异步的,所以我用一个承诺来解决它。承诺的使用是在前一个动画完成后为动画条添加动画。目前,我的代码只会动画第一个栏并停在那里。它不会继续为其他人创造动力。以下是我的所有代码:Javascript:Promise().then does not work

重要! 问题在JavaScript上。不要花时间在HTML或CSS上。

var index = -1; 
 

 
function loading(){ 
 
\t var loader = document.getElementById("loader"); 
 
\t display = window.getComputedStyle(loader).display; 
 
\t if (display == "block"){ 
 
\t \t var child = document.getElementById("loader-ul").getElementsByTagName("div"); 
 
\t \t index = index + 1; 
 
\t \t alert("dd"); 
 
\t \t animate(child); 
 
\t } 
 
} 
 

 
function animate(element){ 
 
\t var el = element[index]; 
 
\t var MaxHeight = false; 
 
\t var finished = false; 
 
\t function anim(){ 
 
\t \t return new Promise(function(resolve, reject){ 
 
\t \t \t if (finished == false){ 
 
\t \t \t \t if (MaxHeight == false){ 
 
\t \t \t \t \t var height = parseInt(window.getComputedStyle(el).height.slice(0, -2)); 
 
\t \t \t \t \t var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2)); 
 
\t \t \t \t \t height = height + 1; 
 
\t \t \t \t \t Bot = Bot + 0.5; 
 
\t \t \t \t \t el.style.bottom = Bot + "px"; 
 
\t \t \t \t \t el.style.height = height + "px"; 
 
\t \t \t \t \t if (height <= 100){ 
 
\t \t \t \t \t \t window.requestAnimationFrame(anim); 
 
\t \t \t \t \t } 
 
\t \t \t \t \t else{ 
 
\t \t \t \t \t \t MaxHeight = true; 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 
\t \t \t \t if (MaxHeight == true){ 
 
\t \t \t \t \t var height = parseInt(window.getComputedStyle(el).height.slice(0, -2)); 
 
\t \t \t \t \t var Bot = parseFloat(window.getComputedStyle(el).bottom.slice(0, -2)); 
 
\t \t \t \t \t height = height - 1; 
 
\t \t \t \t \t Bot = Bot - 0.5; 
 
\t \t \t \t \t el.style.bottom = Bot + "px"; 
 
\t \t \t \t \t el.style.height = height + "px"; 
 
\t \t \t \t \t if (height >= 50){ 
 
\t \t \t \t \t \t window.requestAnimationFrame(anim); 
 
\t \t \t \t \t } 
 
\t \t \t \t \t else{ 
 
\t \t \t \t \t \t MaxHeight = true; 
 
\t \t \t \t \t \t finished = true; 
 
\t \t \t \t \t \t el.style.bottom = 0 + "px"; 
 
\t \t \t \t \t \t el.style.height = 50 + "px"; 
 
\t \t \t \t \t } 
 
\t \t \t \t } 
 
\t \t \t } 
 
\t \t \t else{ 
 
\t \t \t \t resolve(); 
 
\t \t \t } 
 
\t \t }); 
 
\t } 
 
\t anim().then(loading); 
 
}
body{ 
 
\t margin: 0px; 
 
\t padding: 0px; 
 
\t margin: auto; 
 
} 
 

 
#loader{ 
 
\t display: block; 
 
\t position: fixed; 
 
\t height: 100%; 
 
\t width: 100%; 
 
\t background-color: white; 
 
\t z-index: 9999; 
 
} 
 

 
#loader .center{ 
 
\t position: relative; 
 
\t height: 50px; 
 
\t width: 200px; 
 
\t background-color: red; 
 
\t top: 50%; 
 
\t transform: translateY(-50%); 
 
\t margin: auto; 
 
} 
 

 
#loader .center div{ 
 
\t width: 2px; 
 
\t height: 50px; 
 
\t background-color: blue; 
 
\t float: left; 
 
\t padding: 0px; 
 
\t margin-right: 5px; 
 
\t margin-bottom: 25px; 
 
\t position: relative; 
 
}
<body onload="loading()"> 
 
    <div id="loader"> 
 
\t \t \t <div class="center" id="loader-ul"> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t \t <div></div> 
 
\t \t \t </div> 
 
\t \t </div> 
 
\t </body>

我也有一个链接到的jsfiddle:

https://jsfiddle.net/6227jjen/

谢谢大家!

注: 我已经添加了一些警报用于调试目的。

+3

请删除您的HTML和CSS,这是风马牛不相及的问题,也会干扰你的问题。 –

+0

我同意,但我只添加运行剪切。 – GeorGios

+1

您的小提琴存在问题 - 请参阅控制台:加载未定义。您需要在您的JS选项中不包装。 –

回答

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); 
 
}
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>

+0

您的代码完全按照我的意愿工作,谢谢!你能解释我为什么像一个5岁的为什么你的代码工作,我不?我需要明白为什么这个工作,我不这样做。 – GeorGios

+0

为了保证工作,所有内部代码路径必须达到param1(result)或param2(reject)或抛出错误。达到'result'的唯一方法是如果finish === true,但设置finish = true的代码路径永远不会调用'window.requestAnimationFrame(anim)',所以'loading'永远不会再被调用。即使从该路径调用'window.requestAnimationFrame(anim)',该承诺也不是来自anim(),then(加载)的承诺,而是最后调用的'window.requestAnimationFrame(anim)'。我试着不要从上到下改变你的代码,所以仍然可以看到改变了什么。 –

+0

谢谢,我明白,它的工作原理。你让我今天一整天都感觉很好! – GeorGios

0

致电window.requestAnimationFrame(anim);永远不会解决您的承诺。它会打电话anim,这将创造另一个承诺,如果你完成了,那么这个承诺可能会得到解决,但最初的承诺永远不会实现。

而不是将anim的整个主体包装在new Promise的构造函数中,您应该仅提交​​,然后使用它构建承诺链。

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); 
} 
+0

我有点困惑。你可以发布你正在谈论的代码吗? – GeorGios

+0

我测试了一下,不想工作。 – GeorGios

+0

我有一些括号太多了,你能再试一次吗?它应该工作。 – Bergi