knowledge base

マークアップ/フロントエンドエンジニアのWEB制作における備忘録です。平日はWEB屋、休日は社会人劇団の主宰・劇作家をしています。

n秒づつ遅らせてクラスを追加する

delayはアニメーションのみ

このような要件を実装するためによく使われるのは、以下のようにdelayを利用したロジックです。

[ex].200ミリ秒づつ遅らせてフェードインする

var $targets = $('.fade');
var delay = 200;
$targets.each(function(i){
    $(this).delay(i*delay).fadeIn();
});

ところが、delayというのはfadeIn/Outやanimateなどのアニメーションのためのメソッドのみに効くようで、 たとえば次のように、CSS3のプロパティを用いたクラスによるアニメーション制御には時差が生まれません。

一斉に同じタイミングでフェードインします。

※fadeクラスにinクラスが追加されると、opacityとtransitionの組み合わせによりフェードインアニメーションします。

var $targets = $('.fade');
var delay = 200;
$targets.each(function(i){
    $(this).delay(i*delay).addClass('in');
});
.fade{
  opacity: 0;
}
.fade.in{
  opacity: 1;
  transition: opacity 250ms;
}

queueメソッドを利用する

そもそもdelayとはエンキューするよう命令するメソッドで、どうやらanimateやfadeIn/Outなどコールバック関数を持てるメソッドは内部的にエンキュー/デキューを行っているようです。

では、そうではないメソッドの場合はどうすればよいでしょうか。

内部的にエンキューする機能がないならば、明示的にエンキュー/デキューすればよいのです。

jQueryにはエンキュー/デキューするメソッドが用意されているため、こちらを利用すればねらいどおりの挙動を実現することができます。

queueメソッドにはイテレータ(下記例ではnextという引数で受け取っています)があり、こちらを実行することで、順次デキューできるようです。

var $targets = $('.fade');
var delay = 200;
$targets.each(function(i){
  var $this = $(this);
  $this.delay(i *delay).queue(function(next) {
    $this.addClass('in');
    next();
  });
});

こうすることで、クラスによる制御の場合でも、n秒づつ遅らせてアニメーションさせることが可能になります。