jQueryでaddClass使って詰まった話
半年ぶりの更新.
特にメモしておきたいことだったので,自分の中で整理する意味も含めてのポスト.
端的に言うと,CSSの優先順位の問題に突き当たった訳です.
普段,それなりにCSSいじっておきながら実感することのなかった点ですが,なかなか面倒だったので,今回のケースについて整理.まず,今回の問題が発生した経緯ですが
(スタイルシート)
.before{
background:blue;
}
.after{
background:red;
}
(スクリプト)
var state = true;
$(document).click(function(){
if(state)
$("#toggle").addClass("after", 300, function(){
$("#toggle").removeClass("before")
});
else
$("#toggle").addClass("before", 300, function(){
$("#toggle").removeClass("after")
});
state = !state;
});
- 本人的には,クリックする度に赤と青がスムーズに入れ替わって欲しいわけですが,
実際にはこんな感じになる - before(青)->after(赤)はスムーズに変化(意図通り)
- after(赤)->before(青)は一瞬で変化(何かおかしい)
- 問題のあるソースコードの部分の流れとしては
- 対象の要素に"before"を指定する
- 300ms後"after"を除去する
- この内,問題が発生していたのはaddClassの処理の部分であって,
具体的には一つの要素に重複する属性を持つ2つ以上のクラスが指定されていた場合,優先されるのは「後に(下の方で)定義されたクラス」という法則を見落としていたので,うまく行ってなかった訳です. - 実際にはもっと色々基準がありますが,問題は変わらないので割愛
参考:CSSのセレクタによる優先順位を分かりやすくビジュアル化するオンラインツール -Specificity Calculator | コリス - では,どうするべきか
- beforeと全く同じダミー(dummyとする)のクラスをafterの下に追記して以下のようにしてafter->beforeの処理を以下のように変更する
- addClass("dummy")&300ms待つ
- removeClass("after")
- addClass("before")
- removeClass("dummy")
- callbackで繋げれば一応これで多分動きます(非推奨)
- jQueryUIを使う(ダウンロードして解凍してhtmlファイルぶち込む)
if(state)
$("#toggle").switchClass("normal", "warn", 300);
else
$("#toggle").switchClass( "warn","normal", 300);
state = !state; - 凄くシンプル!やったね!!(白目)
- ここまで1時間半
結論:jQueryUI使え
因みにjQueryUIだとanimateとかも微妙に拡張されて便利になってます
追記:ちょっと不適切だったのでタイトル変更しました