web-dev-qa-db-ja.com

CSS移行が起動しない

DOM要素(div)を作成し、それをDOMに追加してから、JavaScriptで1回のクイックヒットでその幅をすべて変更しています。これは理論的にはCSS3遷移をトリガーするはずですが、結果はAからBに直接なり、間に遷移はありません。

別のテストクリックイベントで幅を変更すると、すべてが期待どおりに機能します。

これが私のJSとCSSです:

JS(jQuery):

var div = $('<div />').addClass('trans').css('width', '20px');
$('#container').append(div);
div.css('width', '200px');

CSS(ちょっとモジラだけ):

.trans {
    -moz-transition-property: all;
    -moz-transition-duration: 5s;
    height: 20px;
    background-color: cyan;
}

私はここで混乱していますか、それとも「オールインワンクイックヒット」は物事が行われるべき方法ではありませんか?

すべての助けは本当にありがたいです。

25
Kong

SetTimeoutに依存しないよりクリーンなアプローチは、設定する前に問題のcssプロパティを読み取ることです。

var div = $('<div />').addClass('trans');
$('#container').append(div);
div.css('width');//add this line
div.css('width', '200px');

ここでの作業:

http://jsfiddle.net/FYPpt/144/

以下のLuceroのコメントで説明されているように、この方法で行うには、ブラウザに「自動」や「継承」などではなく実際の値を計算させる必要があります。実際の値がないと、ブラウザは新しい値が以前からの変更であることを認識しません。

48
Torin Finnemann

これを行うには2つの方法があります。

1-CSSトランジション

setTimeoutを使用すると、前のスクリプトではなくaddClassメソッドが実行され、transitionイベントが発生します。

例jsfiddle

jQuery:

_var div = $('<div class="trans" />');
$('#container').append(div);
// set the class change to run 1ms after adding the div
setTimeout(function() {div.addClass('wide')}, 1); 
_

CSS:

_.trans {
    width: 20px;
    height: 20px;
    background-color: cyan;
    -webkit-transition: all 5s ease;
       -moz-transition: all 5s ease;
        -ie-transition: all 5s ease;
         -o-transition: all 5s ease;
            transition: all 5s ease;
}
.wide {
    width: 200px;
}
_

2-jQueryの.animate() function

例jsfiddle

jQuery:

_var div = $('<div class="trans" />');
$('#container').append(div);
div.animate({'width': '200px'}, 5000); // 5 sec animation
_

CSS:

_.trans {
    width: 20px;
    height: 20px;
    background-color: cyan;
}
_
21
MikeM

JQueryの.offset()メソッドを呼び出してみてください。

ブラウザがオフセットを取得すると、リフロー/リペイント/レイアウトイベントがトリガーされ、トランジションが機能するようになります。

このフィドルを参照してください: http://jsfiddle.net/FYPpt/199/

-- http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html も参照してください。

6
theozero

バウンティに応えて:

どのプロパティが移行されているかを知る余裕がない場合、または単にsetTimeoutを強制してアニメーションを起動させるのは良い習慣ではないと思う場合は、別の方法でリフローを強制できます。

そもそもsetTimeoutが機能する理由は、期間が0に設定されている場合でも、その間に完全なドキュメントのリフローが発生しているためです。それがリフローを引き起こす唯一の方法ではありません。


フィドルへのリンク

JavaScript

for (x = Math.ceil(Math.random() * 10), i=0;i<x;i++){
    $('<div />').appendTo($('#container')).addClass('trans');
}

var divs = $('#container div');
var x = divs.eq(Math.ceil(Math.random() * divs.length));
x[0].offsetHeight;
x.addClass('wide');

このJavaScriptを使用して、1〜10個のdiv要素をランダムに追加し、次にそれらの1つをランダムに選択して、wideクラスを追加します。

そこにはJavaScriptの奇妙な行、つまりx[0].offsetHeightがあります。これは、操作全体の要です。 offsetHeightを呼び出すと、setTimeoutを使用したり、CSS値を照会したりせずに、ドキュメントがリフローするようにトリガーされます。

DOMに関連するリフローとは:

リフローはページのレイアウトを計算します。要素のリフローは、要素の寸法と位置を再計算し、DOMでその要素の子、祖先、および要素の後に表示される要素でさらにリフローをトリガーします。次に、最終的な再描画を呼び出します。リフローは非常に高価ですが、残念ながら簡単にトリガーできます。

したがって、これらの機能の使用方法には注意してください。最近のほとんどのブラウザーではそれほど心配する必要はありませんが(jQueryは複数のリフローを発生させることで有名です)、Webサイト全体にこのソリューションのようなものを追加する前に考慮すべきことがあります。


重要な注意:これはaよりも多かれ少なかれ効率的です= setTimeoutcall。これは魔法の弾丸の解決策ではなく、内部で同じことを行っています。


参考までに、対応するCSSを次に示します。

.trans {
    width: 20px;
    height: 20px;
    background-color: cyan;
    -webkit-transition: all 5s ease;
       -moz-transition: all 5s ease;
         -o-transition: all 5s ease;
            transition: all 5s ease;
}

.trans.wide {
    width: 200px;
}
4
Josh Burgess

@onetrickponyが尋ねていたように、すべてのルールがCSSファイルにあり、JS関数に追加すべきではない場合はどうでしょうか。

Torin Finnemannからの回答に基づいて、わずかな変更を加えました。

ルールが定義されているクラスを追加します:new-rules

var div = $('<div class="trans" />');
$('#container').append(div);

var div = $('<div />').addClass('trans');
$('#container').append(div);
div.height();
div.addClass('new-rules');

cSSで、クラスを事前定義します。

.trans.new-rules {
    width: 200px;
    background: yellow;
}

これで、CSSを変更するときにJSをいじくり回す必要がなくなりました。 new-rulesのCSSファイルで変更してください:)

http://jsfiddle.net/FYPpt/201/

2
MMachinegun
var div = $('<div />');

$('#container').append(div);

div.css('width', '20px').addClass('trans', function() {
   div.css('width', '200px') 
});

CSSトランジションを起動するために、新しいDIV要素を作成し、その要素に「trans」クラスを追加します

1
mike510a