[CSS3]transition-durationの時間を無視して途中で終わってしまう時のTips

2011
06.29
このエントリーをはてなブックマークに追加

皆さんご無沙汰しております、どっぷりと新製品の開発に浸かっております。

そこそこ経験を積んでからのチャレンジだったので、それなりに順調なのですが…やっぱりハマるとこはハマりますね。

 

その中でもハマると厄介な部分の Tips を紹介したいと思います。

 

内容は件の通り、再現は確実に取れる訳ではないのですが javascript から要素の transition プロパティを設定して、すぐに値を変更させようとすると再現しやすいようです。

具体的には下記のような感じ。

 

1
2
3
4
5
6
7
8
9
// 検証環境は safari です
var hoge = function() {
    $('#foo').css('-webkit-transition', 'all 1000ms ease-in');
    $('#foo').css('-webkit-transform', 'rotate(360deg)');
}

$(function() {
    hoge();
});

 

こんな具合で実行すると、要素 #foo が1秒かけてぐるりと1回転するハズが少し傾いた直後に一瞬で「360度回転した」事になりアニメーションの最終結果まで飛ばされてしまう。

と言う現象が発生します。

ちなみに Line : 3〜4 をチェインさせても発生する時はしますし、はたまたこれで普通に動いちゃったりもするので何だか良く解りません。

先に fix してしまったので、それ以降発生せず原因が不明なままなんですよね。発生しないに越した事は無いけど。

 

取りあえず css の元ファイルの方でデフォルト状態を色々変更しつつ検証していたのですが、同じプロパティを持つ3つの要素があって、2つの要素は行けるけど、1つだけ駄目だったと言うケースもあったりなんかして云々。

結局 transition の設定を値変更処理が追い抜いてしまっているんじゃないかと言う推測に至りました。

 

と言う訳で困った時の setTimeout です、本当はコールバックを駆使するのが一番確実だと思うのですが、コールバックイベントとして用意されているのは webkitTransitionEnd と言うのしか見つけられませんでした。

このイベントは「値の変化が終了したら発生」するのでこの場合は約に経ちませんので、ここは setTimeout に頼る事にしました。

同期的な部分は上記のイベントでコールバックを蹴って取れば良いと思う、終わり良ければなんとやら。事後処理で手を打つのも悪く無い選択だと思います。

では fix 版のコードを書いてみます。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
// 検証環境は safari です
var timer;
var hoge = function() {
    $('#foo').css('-webkit-transition', 'all 1000ms ease-in');
   
    timer = setTimeout(function() {
        $('#foo').css('-webkit-transform', 'rotate(360deg)');
    }, 0);
}

$(function() {
    hoge();
});

 

取りあえずこれで動いています、今の所は。

setTimeout の第2引数は最初100でやってたのですが、0でも問題無いようです。

すると遅延による処理追い越しとか単純な事じゃないのかもしれませんね、今回のように無名関数で実行する等のプロセスを分ける事に意味があるのかもしれない。

 

全部推測だけど

 

ActionScriptJavaScript を今までガッツリやってる方達からすると基本だろ!と言われそうですが、これ系のスクリプトが得意と言うのは「いかに同期を取らせるのが上手いか」なんだろうなと思いました。

 

それではまた。

 

Tags: , , , ,

Your Reply