読んで覚える、触って体験!JavaScript&CSS3~gihyo.jp×jsdo.it presents

第3回jQueryの基本(回答編)

お題の復習

まずは前回出したお題を復習しましょう。前回のお題は以下のようなHTMLがあったときにマウスオーバーでサブメニューを表示するようなUIをjQueryを使って書くというものでした。

お題(連載第二回目)
お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

たくさんforkしていただいてありがとうございました。今回は回答編ということでみなさんにこのお題をforkしてもらった作品を紹介しながらjQueryを使ったマウスオーバーでのメニュー表示機能を解説していきます。やってみてわからなかった人は模範解答を参考にしてみてください。

模範解答

ではまず模範解答を見ていきましょう。他にもよくできていた作品はたくさんありましたが、模範解答の例として以下の作品を紹介します。

forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

それではこの作品のコードを解説します。

まずmenuItemという要素にマウスオーバーしたときにサブメニューの表示を切り替えたいので、hoverというマウスオーバーとマウスアウトの処理を同時に設定できるhoverを.menuItemに設定します。

$('.menuItem').hover(
    function() {
        // マウスオーバーの時の処理
    },
    function() {
        // マウスアウトの時の処理
    }
);

マウスオーバーの処理は、menuItemの子要素のsubmenuを表示にしたいので以下のように書きます。

$(this).find('.submenu').show();

$(this)がマウスオーバーされた自分自身を指すので、その子要素の.submenuをshow()で表示にすると言う意味です。マウスアウトのときはshowのところをhideにするだけです。

$(this).find('.submenu').hide();

これを最初のコードに当てはめれば以下のようになり、マウスオーバーでのサブメニューの機能は完成です。

$('.menuItem').hover(
    function() {
        $(this).find('.submenu').show();
    },
    function() {
        $(this).find('.submenu').hide();
    }
);

他にも多少書き方は違いますが、以下の作品も同じ動作をします。

forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS
forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

thisの使い方

今回JavaScriptを始めて書く人にとって難しかったのが、先ほど説明したthisだったかもしれません。実際に以下のような間違えをしている作品がいくつかありました。

forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

このコードではメニューにマウスオーバーしたときにすべてのサブメニューが表示になってしまい、期待していた動作にはなりません。なぜこうなるかというと、マウスオーバーの時の処理が以下の用に書かれているからです。

$('.submenu').show();

これだと、メニューにマウスオーバーしたときにすべてのサブメニューに対してshowの処理が適用されてしまうためこのような動作になります。期待した動作にしたい場合は、マウスオーバーした要素の子要素の.submenuのみに処理をする必要があります。そこでthisを使う必要が出てきます。thisを使えばマウスーオーバーされた要素を取得できるのでそこから表示したい要素を辿ればいいのです。

$(this).find('.submenu').show();

また、以下のように書いてある作品も多くありましたが、上記と意味は同じなので、これでも問題ありません。

$('.submenu', this).show();

慣れるまではthisの扱いが難しいとは思いますが、jQueryのclickやhoverなどではthisは自分自身を指すということを覚えておきましょう。

工夫されていた作品

今回のお題は単に表示、非表示というお題でしたが、それに加えてスライドダウンやフェードなどのエフェクトも付けていた作品もありましたので紹介したいと思います。

スライドダウンの効果を使った作品

forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

こちらの作品はslideDownを使ってスライドダウンのエフェクトを加えています。slideDownなどはjQueryにあらかじめ用意されているアニメーションなので、単にshowをslideDownにするだけでこのようなエフェクトを簡単に実装することができます。

フェードの効果を使った作品

forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

こちらは同じようにfadeInとfadeOutを使っています。さらにこの作品ではアニメーションの時間をデフォルトから変更しています。fadeInやslideDownなどは以下のようにアニメーションの早さを設定することが可能です。

fadeIn('slow'); // 遅く表示
fadeIn('fast'); // 早く表示
fadeIn(1000);   // 1000ms(1秒)かけて表示

not(:animated)の判定を入れた作品

forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

この作品はslideDownが使われていますが、少し工夫されています。slideDownでアニメーションするとき、まだアニメーションしている最中にマウスアウトして再度マウスオーバーという動作を繰り返すと何度もアニメーションが動作してしまいます。それを防ぐために、マウスオーバーした際にアニメーション中かどうかという判定を入れています。

$(this).find('ul:not(:animated)').slideDown();

この:animatedというはjQueryの独自セレクタで、アニメーションしている要素かどうかを判別できます。さらにnot(:animated)ですのでアニメーションしていない場合にslideDownするということになります。

CSS3でアニメーション

forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

この作品は面白い方法でアニメーションしています。JavaScriptのコードはとても普通でcssのdisplayを変化させているだけです。

$('.menuItem').hover(
  function() {
    $('.submenu',this).css('display','block');
  },
  function() {
    $('.submenu',this).css('display','none');
  }
);

これはJavaScriptは最小限のシンプルなコードにして、CSS3のアニメーションを使ってアニメーションさせています。今回のお題の趣旨とは若干外れるので具体的なCSSのコードの解説はしませんが、今後この連載でもCSS3については扱っていく予定なので、JavaScriptの組み合わせでこのような面白い動きが実現できるというのは覚えておくといいかもしれません。

マウスアウトした後しばらくしてから非表示にする作品

forked from: forked from: forked from: お題(連載第二回目⁠⁠ - jsdo.it - share JavaScript, HTML5 and CSS

この作品は、今回forkしてもらった作品の中で一番多い量のJavaScriptが書かれていた作品で、面白い点としてマウスアウトした後しばらくサブメニューが表示されたままになっていて、ある程度時間が経過すると非表示になるという動きになっています。別のメニューにマウスオーバーしたときはサブメニューは残らずにちゃんと消えるという細かい動作もつくられています。JavaScriptを始めたばかりの人には高度なスクリプトですが、今回のお題がもの足りないと思った方はこちらのコードを読んでみると面白いかもしれません。

おわりに

今回でjQueryの基本的な使い方を解説して簡単なUIの作成を実際にやってもらいました。jQueryを使えばとても簡単で直感的にJavaScriptを書くことができることがおわかりいただけたと思います。

おすすめ記事

記事・ニュース一覧