[解決済み】CSSのトランジション効果を一時的に無効にする一番きれいな方法は何ですか?
質問
以下のような効果が適用されたDOM要素を持っています。
#elem {
-webkit-transition: height 0.4s ease;
-moz-transition: height 0.4s ease;
-o-transition: height 0.4s ease;
transition: height 0.4s ease;
}
私はこの要素のサイズを変更するjQueryプラグインを書いています。私はスムーズにサイズを変更できるように、これらの効果を一時的に無効にする必要があります。
これらの効果を一時的に無効にする(そして再び有効にする)最もエレガントな方法は何でしょうか。
解決方法は?
簡単な答え
このCSSを使用してください。
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
さらに、このJS(jQueryなし)のどちらかを...
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
あるいは、このJSをjQueryで...
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions
... あるいは、あなたが使っている他のライブラリやフレームワークを使って同等のコードを書いてください。
説明
これは、実はかなり微妙な問題なのです。
まず最初に、'notransition' クラスを作成して、要素に適用し、その
*-transition
CSS属性に
none
. 例えば
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
<サブ
(余談ですが、この記事では
-ms-transition
が入っています。必要ないでしょ。Internet Explorerの最初のバージョンでは、遷移をサポートするために
まったく
はIE10で、接頭辞なしでサポートされました)。
しかし、これは単なるスタイルであり、簡単なことです。このクラスを使おうとすると、ある罠にぶつかる。その罠とは、このようなコードは、あなたが素朴に期待するようには動かないということです。
// Don't do things this way! It doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
someElement.classList.remove('notransition')
素直に考えれば、高さの変化は「notransition」クラスが適用されている間に起こるので、アニメーションにはならないだろうと思うかもしれません。しかし、実際には する 少なくとも私が試したすべてのモダンブラウザで、アニメーションが表示されました。問題は、ブラウザがJavaScriptの実行が終わるまで、必要なスタイルの変更をキャッシュし、一度のリフローですべての変更を行うことです。その結果、トランジションが有効かどうかに正味の変化はないものの、高さには正味の変化がある状態でリフローが行われます。その結果、高さの変化をアニメーションで表現しています。
これを回避する合理的でクリーンな方法は、'notransition' クラスの削除を、次のように 1ms のタイムアウトでラップすることだと思うかもしれません。
// Don't do things this way! It STILL doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
setTimeout(function () {someElement.classList.remove('notransition')}, 1);
が、これも確実に動作するわけではありません。WebKit ブラウザでは上記のコードが壊れることはありませんでしたが、Firefox では(遅いマシンでも速いマシンでも)時々(一見ランダムに)素朴なアプローチを使ったときと同じ動作になることがあります。この理由は、JavaScript の実行が十分に遅く、ブラウザがアイドル状態になり、そうでなければ日和見的なリフローを行おうと考えている時点でタイムアウト関数の実行を待っている可能性があり、そのシナリオが発生すると Firefox はリフローの前にキューに入った関数を実行するからだと思われます。
この問題を解決するために、私が見つけた唯一の方法は
力
を削除する前に、その要素に加えられたCSSの変更をフラッシュし、要素のリフローを行います。これを行うには、さまざまな方法があります。
ここで
があります。標準的な方法として一番近いのは
offsetHeight
プロパティを使用します。
では、実際に機能する1つの解決策はというと
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
ここで説明した3つの可能なアプローチ(成功した1つのアプローチと失敗した2つのアプローチの両方)を説明するJSフィドルを紹介します。 http://jsfiddle.net/2uVAA/131/
関連
-
[解決済み】react router v^4.0.0 Uncaught TypeError: 未定義のプロパティ'location'を読み取れない
-
[解決済み] textareaのresizableプロパティを無効にするにはどうしたらよいですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] モバイル端末の検出にはどのような方法がありますか?
-
[解決済み] CSSのdisplayプロパティで遷移する
-
[解決済み] jQueryでJavaScriptオブジェクトから選択する際に、オプションを追加する最も良い方法は何ですか?
-
[解決済み】JavaScript版sleep()とは?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】このエラーの原因は何ですか - "Fatal error: ローカルgruntを見つけることができません"
-
[解決済み】JavaScriptのgetElementByNameが機能しない
-
[解決済み] テスト
-
[解決済み] [Solved] Uncaught TypeError: nullのプロパティ 'appendChild' を読み取ることができない。
-
[解決済み】SyntaxError: JSON の位置 1 に予期しないトークン o があります。
-
[解決済み】TypeError:res.jsonは関数ではありません。
-
[解決済み】ETIMEDOUTエラーの対処方法は?
-
[解決済み】'useState' が定義されていない no-undef React
-
[解決済み】未定義のプロパティ 'forEach' を読み取ることができない
-
[解決済み] CSSのdisplayプロパティで遷移する