jQuery事始めvol.3・プラグインに頼らず自分でクリックで切り替わるタブメニューを作ってみる

Ads

暫く空いてしまいましたが、jQueryを
コピペに頼らず自分で書いてみよう、
という記事。第三回目です。僕よりも
全然詳しい人のほうが多いんですが、
最近何度かデベロッパーさんの憤り
の発言を目にするので多少でも貢献
出来ればと思います。

というわけで第三回目はよく見るタブメニューを書いてみましょう、というもの。

jQueryを使ったスムースなタブメニュー – ウェビメモ」という記事をお見かけしたのですが、簡単なタブメニューですのでコピペにもプラグインにも頼らず自分で作ってみようじゃないかと、そういう趣向です。

内容は完璧に良いコードとかではなく、あくまで脱ビギナーという内容となります。ビギナーの僕が何様だみたいな話は置いといて。

分かりやすさをメインにしていますので厳密には説明が少し違う点もあるかもしれません。誤解招きそうな記述ありましたらご指摘下さい。

ゴールの確認

まず完成形を見てみましょう。

だいたいエフェクトは先ほどのプラグインのと同じ感じでしょうか。コードの中身見てないので分かりませんけど・・


勿論IEでも動きます。

コード

じゃあコードを確認してみます。

$(document).ready(function() {
        $('.area:first').show();
    $('.tab li:first').addClass('active');

    $('.tab li').click(function() {
        $('.tab li').removeClass('active');
        $(this).addClass('active');
        $('.area').hide();

        $($(this).find('a').attr('href')).fadeIn();
        return false;
    });
});
  • .area / 実際に切り替わるボックス部分です
  • .tab li / クリックするタブです

CSS

続いてcssです。

.tab, .tab li, .tab li a {/*クリックするタブ部分*/
    float: left;
    padding:3px;
    margin-right:2px;
}

.content {/*切り替わる部分を囲うボックス*/
    clear: both;
    overflow: hidden;
    width: 300px;
    border:1px solid #eee;
    height:300px;
}
.area {/*切り替わる部分はまず全部消しておく*/
    display: none;
}
.tab li.active {/*選択中のタブ。色を変える等*/
    background: #eee;
}

.tab li.active a{/*選択中のタブのリンクカラー*/
    color:red;
}

HTML

htmlです。

<!--ここがタブ-->
<ul class="tab">
    <li><a href="#tab1">tab1</a></li>
    <li><a href="#tab2">tab2</a></li>
    <li><a href="#tab3">tab3</a></li>
    <li><a href="#tab4">tab4</a></li>
</ul>
<!--ここが切り替わる部分-->
<div class="content">
    <div class="area" id="tab1"> 
        Tab1
    </div>
    <div class="area" id="tab2">
       Tab2
    </div>
    <div class="area" id="tab3">
        Tab3
    </div>
    <div class="area" id="tab4">
        Tab4
    </div>
</div>

これらを使ってタブメニューを作ります。

では、以下より順にコードを追っていきます。

STEP.1 / コードの準備と理屈を理解する

ここは事始め第一回のおさらいですが、Webデザインレシピさんの記事が実に詳しく書かれています。

むしろレシピさん見に行った方が数百倍勉強になると思いますが、僕の記事で我慢してやるよっていう菩薩のような心をお持ちの貴方はこのままお進みください。後ろを振り返ってはなりません。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript" charset="UTF-8"></script>
<script type="text/javascript">
$(document).ready(function(){
	ここに動作させる為のコードを書く
})
</script>

これが基本形となります。これから、この中に命令文を書いていく事になります。

大体の理屈を把握しておく

さて、今回のタブメニューのために書くコードがどういう動作をするか、を触りだけ最初に確認します。

タブをクリックすると、元々表示されていたコンテンツは非表示になり、それに合うidの付いたコンテンツが代わりに表示、他のタブをクリックすれば応じてコンテンツが切り替わるという感じです。説明下手すぎて既に泣きそうですが頑張りますね。

では以下より1行ずつ見て行きましょう。先ほどのサンプルを見ながらだと頭に入りやすいと思います。

STEP.2 / 最初に1つだけ表示しておく


さて、では1行目から。

$('.area:first').show();

これはclass=”area”というclass名のアイテムの最初だけを表示するという命令文です。

アイテムの最初だけ = $(‘.area:first’)
表示する = .show()

class=”area”というコンテンツ部分は、cssにて

.area {
    display: none;
}

と書いているため、最初は全部消えているわけですね。なのでshow()で1つだけ表示させます。

唯一表示させる部分

htmlでいうと以下の場所が最初のareaになります。

    <div class="area" id="tab1"> 
        Tab1
    </div>

他のid=”tab2″~4は非表示になっています。

STEP.3 / STEP.2に合わせてタブにclassを与えておく

2行目です。STEP2で.areaの最初だけを表示させました。

$('.tab li:first').addClass('active');

その表示されているコンテンツに合わせて、タブも最初のアイテム(li:firstで指定)だけスタイルを変更させて、タブが選択中であることをユーザーさんに明示します。そのために、現状とは別のclass名を加え、cssでスタイルを変えます。

.addClass()は指定したセレクタ、ここではli:firstですね。最初のliだけにclass=”active”となるようにしました。

最初のliだけ = $(‘.tab li:first’)
classが加わる = .addClass(‘active’)

DOM操作でどう変化したかをチェック

こうすることで、htmlは以下のように変化しています。

    <li class="active"><a href="#tab1">tab1</a></li>
    <li><a href="#tab2">tab2</a></li>
    <li><a href="#tab3">tab3</a></li>
    <li><a href="#tab4">tab4</a></li>

最初のliだけにclassが追加されていますね。li:firstでclass=”active”を与えました。

なので、cssでスタイルを変更すれば選択中の部分だけグレーに変えてあることが分かるかと思います。

.tab li.active {/*選択中のタブ。色を変える等*/
    background: #eee;
}

class=”active”はグレー(#eee)になります。

蛇足:DOMってなんでしょう?

DOMというのはDocument Object Modelの頭文字を取ったものです。HTMLやXMLなどのpタグとかdivとかを操作できる仕組みを指します。

こういった構造をDOMツリーといい、それぞれの要素をノードと呼びます。

STEP.3ではliというノードにclass=”active”を加えるというDOM操作をしました。

:firstやcssでも馴染みのある:first-childという擬似クラスは、jQueryを使う事でクロスブラウザに対応させることが出来ます。これをフィルターと呼びます。

このようなフィルターはDOMの操作に凄く役に立ってくれますのでぜひ覚えてください。

[note]以前記事にしましたので合わせてご覧下さい。[/note]

STEP.4 / タブをクリックさせてイベントを発生させる


続いて3行目です。ここからが本番みたいなものですね。

    $('.tab li').click(function() {
        //クリックして起こるイベント
    });

これは、.tab liをクリックすると、この中の命令文が発動する、という指示です。

今日の内容は「タブをクリックしてコンテンツが切り替わる」というコードですので、click()を使うわけですね。

クリックで何か起こる = .click()

これより以下からクリックして何が起こるか、を書いていきます。

STEP.5 / クリックしたタブにclass名を加えて他classは削除


ちょっと重複しますので一気に4~6行目まで行きます。

$('.tab li').removeClass('active');
        $(this).addClass('active');
        $('.area').hide();

さて、ここからはクリックイベントですので、この中身は「クリックしたら起こること」です。

まず、.tab liに先に付いていたclass=”active”をremoveClass()メソッドで削除します。続いてそのままクリックしたところに同じくclass=”active”を加えます。

他のタブに既にあったclassを消す = .removeClass(‘active’)
クリックしたタブclassを加える = .addClass(‘active’);
既存のコンテンツを非表示にする = .hide()


少し混乱しそうですね。HTMLを見てみましょう。

これがクリック前です。

    <li class="active"><a href="#tab1">tab1</a></li>
    <li><a href="#tab2">tab2</a></li>
    <li><a href="#tab3">tab3</a></li>
    <li><a href="#tab4">tab4</a></li>

では、tab3をクリックしてみましょう。

    <li><a href="#tab1">tab1</a></li>
    <li><a href="#tab2">tab2</a></li>
    <li class="active"><a href="#tab3">tab3</a></li>
    <li><a href="#tab4">tab4</a></li>

tab1のclass=”active”はremoveClass()メソッドで削除され、クリックしたtab3を包括するli要素に新たにclass=”active”が加わりました

これで、クリックしたタブがグレーになる、というクリックイベントが完成しましたね。

同時に既存のコンテンツを非表示にする

で、その後に$(‘.area’).hide();というのがありますね。これでタブをクリックしたら、現在表示されているコンテンツを非表示にします。

ただ、このままだと何も表示されなくなってしまいます。ですので、クリックしたタブに紐付けられたコンテンツを表示させます。

STEP.6 / コンテンツをフェードインさせる


さて、最後の命令文です。ここがメインですね。クリックしたタブに合わせてコンテンツをフェードインさせます。

 $($(this).find('a').attr('href')).fadeIn();

ちょっと意味が分かりませんね。

まず、find(‘a’)っていうのはクリックした部分からa要素を探すっていう命令です。そのa要素の中からhref属性に指定されているものを取得して、その場にフェードイン(fadeInメソッド)させながら読み込みます。

$(‘.area’).hide();で既存のコンテンツが非表示になり、href属性に指定されている”#tab2″に当たるid=”tab2″が取得されて、フェードインしながら表示されます。

クリックしたタブの中でa要素を探す = .find(‘a’)
そのa要素の中のhref属性の中身を取得する = .attr(‘href’)
その取得した中身をフェードイン表示する = .fadeIn()

ちょっと分かりにくいですかね・・・

HTMLを見てみましょう。ちょっと端折りますね。

<ul class="tab">
    <li><a href="#tab1">tab1</a></li>
    <li><a href="#tab2">tab2</a></li>
</ul>
<div class="content">
    <div class="area" id="tab1"> 
        Tab1
    </div>
    <div class="area" id="tab2">
       Tab2
    </div>
</div>

tab2はhref=”#tab2″となっています。これに合うのはid=”tab2″ですよね?ページ内リンクにもよく使われています。

このid=”tab2″がフェードインしながらその場に読み込まれる、という仕組みです。

ここまでがクリックイベントです。特にややこしいのは最後の.attr()じゃないでしょうか。.attr()は属性値を取得するだけでなく、別のものに置き換えたりも出来ますがここでは割愛します。

では全体像を見てみます。復習も兼ねてコメントも入れておきました。

STEP.7 / 確認しよう

$(document).ready(function() {

        //.areaはcssで全てdisplay:none;されてるので、最初の.areaだけ表示させる
        $('.area:first').show();

    //一番最初のタブにclass="active"を加える
    $('.tab li:first').addClass('active');

    //タブがクリックされて起こる事をこの中で命令する
    $('.tab li').click(function() {

        //元々存在していたタブのclass="active"を削除する
        $('.tab li').removeClass('active');

        //クリックしたタブに新たにclass="active"を加える
        $(this).addClass('active');

        //既に表示されていたclass="area"を非表示にする
        $('.area').hide();

        //クリックしたタブ内のアンカータグ内のhref属性に当たるid名のボックスをフェードインで表示させる
        $($(this).find('a').attr('href')).fadeIn();

        //ここでイベントが終了
        return false;

    });//ここまでクリックイベント

});

問題無さそうですか?クリックイベントは指定されたノードをクリックする度に発生します。

これで、タブをクリックすると、コンテンツが切り替わるタブメニューが出来上がりました。

おさらい

今日使ったメソッドをリファレンスサイトにリンクしておきます。1.4のリファレンスなんですが、今日出てきたメソッドはattr()以外は(多分)変わりません。まずは各メソッドの大まかな用途を知って見るといいですね。でも、出来る限り本家を見るようにしてください。

  1. .show() / 非表示状態にあるものを表示
  2. .addClass() / cssを加える
  3. .click() / クリックで起こるイベントを発生させる
  4. .removeClass() / 既存のclassを削除する
  5. .hide() / 表示されているものを隠す
  6. .find() / 指定した要素を探す
  7. .attr() / 属性を操作・・・1.6でゴタゴタしてたのでここもご覧下さい
  8. .fadeIn() / 非表示の要素をフェードイン表示

ここで終わりなんですが、もう一歩理解を深めるために、変更を加えてみましょう。

おまけ / 書き方を変える

こんな状態ですが、もう少しコードを軽くして、しかも見やすくしたいものです。とはいえ、この程度の短さじゃ変わりませんが、こういう事が出来ますよ、という事でご参考下さい。

$(document).ready(function() {
        $('.area:first').show();
    $('.tab li:first').addClass('active');

    $('.tab li').click(function() {
        $('.tab li').removeClass('active');
        $(this).addClass('active');
        $('.area').hide();

        $($(this).find('a').attr('href')).fadeIn();
        return false;
    });
});

ここで、$(‘.tab li’)っていうのが2回出てきますよね?もっとコードが長くなると毎回書くのは非合理的です。それと、find(‘a’)のあたりもなんかごちゃ付いてます。

$(document).ready(function() {
        $('.area:first').show();
    $('.tab li:first').addClass('active');

    var $tbl = $('.tab li');


    $tbl.click(function() {
        $tbl.removeClass('active');
        $(this).addClass('active');
        $('.area').hide();

    var $ath = $(this).find('a').attr('href');

        $($ath).fadeIn();
        return false;
    });
});

var・・っていうのが出てきました。

var ここに書く文字に置き換える = 該当するコード;

大雑把ですけどこんな感じです。

$(‘.tab li’)って毎回書かなくても、最初に$tblでも同じだよ、という定義を作ります。予め変数宣言し、値を代入しておけば全体を通して少ないコードで済みますし、コードも見やすくなりそうです。
サンプルでは $($(this).find(‘a’).attr(‘href’))という書き方をしていますが、実際はvar find = $(this).find(‘a’).attr(‘href’);などのように定義しておくのが一般的です。

コードの最適化・・って言っていいかどうか分かりませんが、簡略化するのはとても大事です。.filter()など、さらに絞り込めるようなメソッドなども今後覚えていかれるかと思いますが、今日はこんなところで終わりにします。

おまけ / エフェクトを変える

エフェクトはjQueryを学びたい、と思う切欠として一番多いかもしれません。理由は置いておいて、かっこいい動作のコンテンツを作ってみたいですよね。

サンプルではフェードインでしたが、スピード感のあるスライドインにして見ましょう。

$(document).ready(function() {
        $('.area:first').show();
    $('.tab li:first').addClass('active');

    var $tbl = $('.tab li');

    $tbl.click(function() {
        $tbl.removeClass('active');
        $(this).addClass('active');
        $('.area').hide();

    var $ath = $(this).find('a').attr('href');
        $($ath).slideDown('fast');//スライドさせながら早く表示
        return false;
    });
});

おまけ / jQueryUIでタブを作る

jQueryにはjQueryUIというライブラリも用意されています。このUIを使えば簡単なコードでタブメニューを実装できます。

jQueryはこのようにユーザーに便利な機能を作れますが、Web制作者向けに便利な物も作れたりします。

指定要素全てにボーダーを指定してくれるプラグインなんかはその一例です。

いろいろ覚えると便利ですし、制作の幅も広がるし、何より配布されているプラグインに問題が生じたときも対応しやすくなります。プラグインを使う為にjQueryを全て知る必要はありませんが、多少なりとも知識があったほうがリスクが減るのは確かだと思います。お仕事で使うならぜひとも身に付けたいものですね。

以上、事始めでした。どうも説明とか苦手なのでこういったチュートリアルは苦手です。僕もそんな詳しい人間ではありませんので、何か間違ってるようでしたらやんわりご指摘いただければと思います。年末に事始めってなんだかアレですけどw