web-dev-qa-db-ja.com

JavaScriptを介して割り当てられた場合、CSSトランジションは機能しません

JavaScriptを介してCSS3トランジションをスライドショーに適用しようとすると大きな頭痛の種があります。

基本的に、JavaScriptはスライドショー内のすべてのスライドを取得し、CSSクラスを正しい要素に適用して、素敵なアニメーション効果を提供します。CSS3トランジションのサポートがない場合は、トランジションなしでスタイルを適用します。

さて、私の「小さな」問題。すべてが期待どおりに機能し、すべてのスライドが正しいスタイルを取得し、コードはバグなしで実行されます(これまでのところ)。ただし、正しいスタイルが適用されていても、指定されたトランジションは機能しません。また、スタイルとトランジションは、インスペクタを介して自分で適用すると機能します。

自分で論理的な説明を見つけることができなかったので、誰かが答えられると思いました。

コードが現在何であるかの小さな例をまとめました: http://g2f.nl/38rvma またはJSfiddle(画像なし)を使用してください: http:// jsfiddle。 net/5RgGV/1 /

28
Jon Koops

transitionを機能させるには、3つのことが必要です。

  1. この場合、要素には明示的に定義されたプロパティが必要です。この場合:opacity: 0;
  2. 要素には遷移が定義されている必要があります:transition: opacity 2s;
  3. 新しいプロパティを設定する必要があります:opacity: 1

例のように1と2を動的に割り当てる場合、ブラウザがリクエストを処理できるように、3の前に遅延が必要です。デバッグ時に機能する理由は、この遅延を段階的に実行し、ブラウザに処理時間を与えることです。 .target-fadeinの割り当てを遅らせます。

window.setTimeout( function() { slides[targetIndex].className += " target-fadein"; }, 100 ); 

または、.target-fadein-beginをHTMLに直接挿入して、ロード時に解析され、移行の準備ができるようにします。

要素にtransitionを追加しても、アニメーションをトリガーするのではなく、プロパティを変更します。

デモ: http://jsfiddle.net/ThinkingStiff/QNnnQ/

HTML:

<div id="fade1" class="fadeable">fade 1 - works</div>
<div id="fade2">fade 2 - doesn't work</div>
<div id="fade3">fade 3 - works</div>

CSS:

.fadeable {
    opacity: 0;
}

.fade-in {
    opacity: 1;
    transition:             opacity 2s;
        -moz-transition:    opacity 2s;
        -ms-transition:     opacity 2s;
        -o-transition:      opacity 2s;
        -webkit-transition: opacity 2s;
}

脚本:

//works
document.getElementById( 'fade1' ).className += ' fade-in';

//doesn't work
document.getElementById( 'fade2' ).className = 'fadeable';
document.getElementById( 'fade2' ).className += ' fade-in';

//works
document.getElementById( 'fade3' ).className = 'fadeable';
window.setTimeout( function() {

    document.getElementById( 'fade3' ).className += ' fade-in';

}, 100);
48
ThinkingStiff

レイアウトエンジンをだましてください!

function finalizeAndCleanUp (event) {
    if (event.propertyName == 'opacity') {
        this.style.opacity = '0'
        this.removeEventListener('transitionend', finalizeAndCleanUp)
    }
}
element.style.transition = 'opacity 1s'
element.style.opacity = '0'
element.addEventListener('transitionend', finalizeAndCleanUp)
// next line's important but there's no need to store the value
element.offsetHeight
element.style.opacity = '1'

すでに述べたように、transitionsは、状態[〜#〜] a [〜#〜]から状態[〜#〜] b [〜#〜]に補間することによって機能します。。スクリプトが同じ関数に変更を加える場合、レイアウトエンジンはwhere state [〜#〜] a [〜#〜]の終了と[〜#〜] b [〜#〜 ]が始まります。あなたがそれにヒントを与えない限り。

ヒントを作成するofficialの方法がないため、一部の関数の副作用に依存する必要があります。この場合 .offsetHeight getterは、レイアウトエンジンを停止し、設定されているすべてのプロパティを評価、計算し、値を返すようにします。通常、これはパフォーマンスへの影響のために回避する必要がありますが、私たちの場合、これはまさに必要なものです:状態の統合。

完全を期すためにクリーンアップコードが追加されました。

5
transistor09

一部の人々はなぜ遅延があるのか​​と尋ねてきました。標準では、スタイル変更イベントと呼ばれる複数の遷移を一度に発生させることを望んでいます(要素が回転して同時にフェードインするなど)。残念ながら、同時に発生させたい遷移をグループ化する明示的な方法は定義されていません。代わりに、ブラウザは、呼び出される間隔によって、同時に発生する遷移を任意に選択できます。ほとんどのブラウザは、リフレッシュレートを使用してこの時間を定義しているようです。

詳細が必要な場合の標準は次のとおりです。 http://dev.w3.org/csswg/css-transitions/#starting

1
user3723889