2016-11-02 19 views
1

私はスライドショーフレームワークを構築していますが、アニメーション機能を循環させる最善の方法を考え出すのに問題がありました。setInterval()を使用できましたが、リソースを大量に消費することなく繰り返してください。関数を無期限に、好ましくはsetInterval()を使用せずに繰り返します。

JAVASCRIPT:

class slideShow { 
    constructor(imgDir, dataList) { 
     this.imgDir = imgDir; 
     this.dataList = dataList; 
     this.settings = 0; 
     this.imgList = 0; 
     this._init(); 
    } 
    _init(){ 
     $.getJSON(`${this.imgDir}/${this.dataList}.json`, (data)=>{ 
      this.settings = data.settings; 
      this.imgList = data.imgList; 
     }) 
    } 
    start(){ 
     for(let img of this.imgList){ 
      $(this.settings.selector).fadeOut(this.settings.fadeTime,()=>{ 
       $(this.settings.selector).attr("src",`${this.imgDir}/${img}`); 
       $(this.settings.selector).fadeIn(this.settings.fadeTime); 
      }); 
     } 
    } 
} 

JSON:

{ 
    "settings":{ 
     "selector":"#slideShow", 
     "fadeTime":1000 
    }, 
    "imgList":[ 
     "slide_01.jpg", 
     "slide_02.jpg", 
     "slide_03.jpg" 
    ] 
} 
+4

'setInterval()'の問題点は何ですか? – Andreas

+2

'setInterval'に問題があり、何らかのイベント(意図しない言い回しは意図していません)をjQueryアニメーションと混同しないでください。 – Alnitak

+0

次の画像が' for..of'でアニメーションを開始する前に現在の画像がアニメーションを完了するのを待っていますか?ループ? – guest271314

答えて

2

は簡単な解決策は、「から疑似再帰的にループしていますアニメーションの最終ステップの「完了コールバック」を選択します。私はfor ... ofループを削除した

start() { 
    var current = 0; 
    (function loop() { 
     let img = imgList[current++]; 
     current %= imgList.length; 
     let $sel = $(this.settings.selector); 
     $sel.fadeOut(this.settings.fadeTime,() => { 
      $sel.attr("src",`${this.imgDir}/${img}`); 
      $sel.fadeIn(this.settings.fadeTime, loop); // <-- here 
     }); 
    })(); 
} 

注 - ここloop機能の各パスは、ちょうどスライドショーの一つのフレームを処理します。

これはあなたのコード内で何もfadeOut, change image, fadeInへの最初のサイクルを可能にしていないので、あなたが(もちろん見えないだろうそのうちの2つ)三つの連続fadeOutアニメーションを取得したいあなたの元のコードのバグ、と思われるものを解決しますfor ... ofループの次の反復が始まる前に完了してください。

+0

これはうまくいきましたが、私は 'that = this'を追加しなければなりませんでした。また、バグを指摘してくれてありがとう。 –

+1

アイロニック - 私はちょうど 'this'の正しい取り扱いについて他の回答者と長い間チャットしていて、自分の答えでバグを見つけられませんでした:) – Alnitak

+0

代わりにセレクタと設定値を参照外にすることになります'this'に依存する唯一の変数だからです。ああ、 'imgDir'も。 – Alnitak

1

あなたは.then()を使用することができ、jQueryの.promise()、再帰

class slideShow { 
    constructor(imgDir, dataList) { 
     this.imgDir = imgDir; 
     this.dataList = dataList; 
     this.settings = 0; 
     this.imgList = 0; 
     this._init(); 
    } 
    _init(){ 
     $.getJSON(`${this.imgDir}/${this.dataList}.json`, (data)=>{ 
      this.settings = data.settings; 
      this.imgList = data.imgList; 
     }).then(this.start) 
    } 
    start(){ 
     for(let img of this.imgList){ 
      $(this.settings.selector).fadeOut(this.settings.fadeTime,()=>{ 
       $(this.settings.selector).attr("src",`${this.imgDir}/${img}`); 
       $(this.settings.selector).fadeIn(this.settings.fadeTime); 
      }); 
     } 
     $(this.settings.selector).promise() 
     .then(() => this.start() /* or this._init() */) 
    } 
} 
+1

'.then'コールバックが呼び出される前にイベントループがスタックを巻き戻すため、これは"本当の "再帰ではありません。 – Alnitak

+0

@Alnitak Ok。プロセスを何と呼ぶべきですか?あなたのアプローチはおそらくOPがアニメーション部分で探しているものでしょう。 OPがアニメーションを連続した順番で望むかどうかはっきりしない?もし 'yes 'なら' for..of'ループの '.queue()'、 '$、map()'を代入します – guest271314

+0

あなたの '.then(this.start)'も間違っています。 '.then( )=> this.start) 'それ以外の場合は' this'を定義していません – Alnitak

関連する問題