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;
}
私はここで混乱していますか、それとも「オールインワンクイックヒット」は物事が行われるべき方法ではありませんか?
すべての助けは本当にありがたいです。
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のコメントで説明されているように、この方法で行うには、ブラウザに「自動」や「継承」などではなく実際の値を計算させる必要があります。実際の値がないと、ブラウザは新しい値が以前からの変更であることを認識しません。
これを行うには2つの方法があります。
1-CSSトランジション
setTimeout
を使用すると、前のスクリプトではなくaddClass
メソッドが実行され、transition
イベントが発生します。
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
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;
}
_
JQueryの.offset()
メソッドを呼び出してみてください。
ブラウザがオフセットを取得すると、リフロー/リペイント/レイアウトイベントがトリガーされ、トランジションが機能するようになります。
このフィドルを参照してください: http://jsfiddle.net/FYPpt/199/
-- http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html も参照してください。
バウンティに応えて:
どのプロパティが移行されているかを知る余裕がない場合、または単に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よりも多かれ少なかれ効率的です= setTimeout
call。これは魔法の弾丸の解決策ではなく、内部で同じことを行っています。
参考までに、対応する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;
}
@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ファイルで変更してください:)
var div = $('<div />');
$('#container').append(div);
div.css('width', '20px').addClass('trans', function() {
div.css('width', '200px')
});
CSSトランジションを起動するために、新しいDIV要素を作成し、その要素に「trans」クラスを追加します