2016-09-24 140 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