THE HAM MEDIA BLOG

jQuery:hoverで背景色が変わった後、交互に背景がついているところの色を元に戻す方法

Clip to Evernote このエントリーをはてなブックマークに追加
カテゴリ:
jQuery
タグ:
jquery
javascript

hoverの前の色に戻すスクリプト

リストとかテーブルで行ごとに色が違う設定になっているとき、
そこに背景色が変わるJavaScriptのhoverの設定をつけてみた。
CSSで設定する場合はhoverの設定をすればいいだけなのだが、
jQueryとかで設定すると、hoverが終わったoutの時の設定も必要になる。

そのとき、元の背景色に戻す指定が必要なのだが、
なぜか複雑に考えすぎてうまく元に戻せなかった。

あ、これでいいじゃん…なんてうっかりをしていたので、
メモのためにエントリーしておく。

すぐにわかるでしょうか?

まず、最初にエラーになるスクリプトを書いておきます。
どこが悪いかわかるでしょうか?

まずは正しく動作している状態をみてください。

■プレビュー

TH1 TH2 TH3 TH4 TH5 TH6 TH7 TH8
1−1 1−2 1−3 1−4 1−5 1−6 1−7 1−8
2−1 2−2 2−3 2−4 2−5 2−6 2−7 2−8
3−1 3−2 3−3 3−4 3−5 3−6 3−7 3−8
4−1 4−2 4−3 4−4 4−5 4−6 4−7 4−8
5−1 5−2 5−3 5−4 5−5 5−6 5−7 5−8
6−1 6−2 6−3 6−4 6−5 6−6 6−7 6−8
7−1 7−2 7−3 7−4 7−5 7−6 7−7 7−8
8−1 8−2 8−3 8−4 8−5 8−6 8−7 8−8

マウスを乗せると横の行の色が変わるようになっています。
そしてマウスがはなれると、元の色に戻るというもの。

CSSでやるならとってもシンプルなことですよね。

失敗した時のスクリプト

$('#test1 tr').hover(function(){
  var bgColor = $(this).css('backgroundColor');
  $(this).css({
    backgroundColor:'#ff47a3',
    color:'#ffffff'
  });
},function(){
  $(this).css({
    backgroundColor:bgColor,
    color:'#333333'
  });
});

これを動作させようとするとマウスががoutしたとき、
背景色がホバーの時のままで変わらなくなってしまいます。
エラーになってしまうのです。

あたまの中での仕組みとしては、
マウスがhoverしたら、まずそのときの背景色を取得して、
変数に格納しておきます。
それと同時に色をhoverしたときの色に変化させます。
そしてoutになったときに、背景色を格納しておいた色を指定…
ということを想定していたのですが、上のスクリプトだと動きません!

さて、どうしたらできるようになるでしょう?

とってもシンプルなのですが、なぜ僕はこれにすぐに気づかなかった...
地味にこれに2時間くらい悩みました。。。

エラーになる原因

エラーになる原因は最初わからなかったのですが、
気づいたのは、outの時に指定しているbgColorに
何も格納されていませんよ〜というエラーがでるということ。

hoverした時には変数の中身はあるのですが、outの時には中身がない。
なぜ!?

これは単純な話で、hoverの時とoutの時と
呼び出している関数が違うために、hoverした時に値を取得しても
それをoutの時に活かすことができないのでエラーになっているらしい。

ではどうするのか…

シンプルではない解答

まずは、こんな方法もあるよって解答

$('#test1 tr').hover(function(){
  $(this).css({
    backgroundColor:'#ff47a3',
    color:'#ffffff'
  });
},function(){
  $('#test1 tr:nth-child(odd)').css({
    backgroundColor:'#b2d8ff',
    color:'#333333'
  });
  $('#test1 tr:nth-child(even)').css({
    backgroundColor:'#ffffff',
    color:'#333333'
  });
});

outしたときに再度交互の色指定を再度しなおす方法である。
シンプルではないですよね。なんというか、無理やり感タップりな方法です。

一番シンプルな方法

では、正解はどのような方法かというと、これだけでいい。

$('#test1 tr').each(function(){
  var bgColor = $(this).css('backgroundColor');
  $(this).hover(function(){
    $(this).css({
      backgroundColor:'#ff47a3',
      color:'#ffffff'
    });
  },function(){
    $(this).css({
      backgroundColor:bgColor,
      color:'#333333'
    });
  });
});

そう、全体をeachで囲ってそこに変数を指定すれば
hover時もout時にも変数を使うことができる。

もっとこれに早く気づいていたら…
なんて、いまさら思います。

みなさんはすぐに気づけましたか?

この記事へのコメント
それだとtrの数だけbgColor変数やコールバック関数が設定されるので、使われるメモリが増えるような・・・。さらにtrの数だけ関数が呼ばれるのでデータが増えれば処理も重くなると思います。

グローバル変数としてbgColorを宣言して、失敗した時のスクリプトからvarを外して代入だけにすれば意図した動きになると思います。

var bgColor;
(function($){
  :
  :
$('#test1 tr').hover(function(){
bgColor = $(this).css('backgroundColor');
$(this).css({
backgroundColor:'#ff47a3',
color:'#ffffff'
});
},function(){
$(this).css({
backgroundColor:bgColor,
color:'#333333'
});
});
  :
  :
Posted by 通りすがり at 2009年11月14日
>通りすがりさん
そうですね、当時はデータ数が多い時のことは頭にいれていなかったので、エントリーに書いたような内容です。

しかもtrに入れていたか、自分。。。

時間があれば、再エントリーでもするようにしてみます。

Posted by ハム at 2009年11月15日
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

トップに戻る