開発メモ,主に補足by子連れ親父プログラマー

2010-05-06

jQueryで作るタブのメニュー画面がリンクから飛んできた時も選択した状態にしたい

今開発してるシステムでちょっとおもしろそうな題材があったので紹介しておきます。
ソース全部載せると分かりづらいので一部だけで概念的に説明しますが、これはまあ、普通にレフトメニューがあって、そしてメインの部分にはタブでメニューを選択できるようなレイアウトの画面だと思って下さい。
レフトメニューはこんな感じ
<div class="left">
    <p>メニュー</p>
    <ul>
        <li><a href="sample.html#menu1">menu1</a></li>
        <li><a href="sample.html#menu2">menu2</a></li>
        <li><a href="sample.html#menu3">menu3</a></li>
        <li><a href="sample.html#menu4">menu4</a></li>
        <li><a href="sample.html#menu5">menu5</a></li>
    </ul>
</div>
メイン部分のタブはこんな感じ
<div class="menu-tab">
    <ul>
        <li><a href="#menu1" class="selected">menu1</a></li>
        <li><a href="#menu2">menu2</a></li>
        <li><a href="#menu3">menu3</a></li>
        <li><a href="#menu4">menu4</a></li>
        <li><a href="#menu5">menu5</a></li>
    </ul>
</div>
そして、このメイン部分のタブ表示の下に、以下のような、各タブをクリックした時に表示すべき内容を menu1 から menu5 まで全部並べておきます。
<div class="menu">
    <div id="menu1" class="list">
        menu1の内容
    </div>
    <div id="menu2" class="list">
        menu2の内容
    </div>
    <div id="menu3" class="list">
        menu3の内容
    </div>
    <div id="menu4" class="list">
        menu4の内容
    </div>
    <div id="menu5" class="list">
        menu5の内容
    </div>
</div>
これを jQuery を使って、menu2 のタブをクリックした時は <div id="menu2"> の内容だけを表示させ、かつ、
<a href="#menu2"> のタブには選択した状態のクラス(selected)をあてたい、しかもレフトメニューからのクリックでも同じ動きができて、レフトメニューはサイト内の他のページにもそのまま(同じまま)設置されるので、他のページから、
<a href="sample.html#menu2"> というリンクで飛んできた時にも menu2 の内容を表示したい、ということなんですね。

んで、最初に送られてきたソースがこんな感じでした。
$("div.list:not("+$(".menu-tab li a.selected").attr("href")+")").hide();
$(".menu-tab li a").click(function(){
    $(".menu-tab li a").removeClass("selected");
    $(this).addClass("selected");
    $("div.list").hide();
    $($(this).attr("href")).show();
    return false;
});
1行目で、クラスが selected になっている(=つまり選択状態)のタブの href 属性を取得して(この場合は #menu1 )、それ以外の $("div.list")、すなわち各メニューの内容を隠しています。
2行目でタブのクリックを取得して、クリックされたタブについてあれこれ処理しています。
3行目は全てのタブから selected クラスの除去。
4行目は選択されたタブに selected クラスを付加。
5行目は各メニューの内容を一旦全部隠して。
6行目でクリックされたタブの href 属性と同じ id のメニューの内容を表示。

このままでは確かにレフトメニューからクリックされた時も、このページに他のページからリンクで飛んできた時も動きません。
ということで、どうやって、<a href="sample.html#menu2"> の#以下の部分を取得するか、なんですが、とりあえず
location.hash
で取得できる、ということです。
あと、jQueryの .attr() の場合は単に、
.attr("hash")
でいけると。
今回の場合基本的に #menu2 という文字列がキーになっていて、あとはタブ部分のオブジェクトをなにがしか操作すればよさそうなので、メインの部分はこんな感じで。
$(function(){
    var selected_tab = location.hash;
    var link_tab = $(".menu-tab li a");

    tabchange(selected_tab, link_tab);

    $(".menu-tab li a, .left li a").click(function(){
        tabchange($(this).attr("hash"), link_tab);
    });
});
tabchange という function を別途用意することにして、それに #menu2 という文字列と、タブ部分のオブジェクトを渡してなんとかすることにします。
7行目は、タブをクリックしたか、あるいはレフトメニューをクリックしたか、で動かして、クリックしたリンクの .attr("hash") を渡す処理にしています。
ということで、function tabchange はこんな感じで。
function tabchange(selected_tab, link_tab){
    link_tab.removeClass("selected");
    link_tab.each(function(n){
        if ($(this).attr("hash") == selected_tab){$(this).addClass("selected");}
    });
    $(selected_tab).siblings().hide();
    $(selected_tab).show();
}
each とか、siblings とか使っちゃってますが、やってる内容は元々のやつと同じです。
一応完成っす。

このブログを検索

Powered by Blogger.

ラベル

php (17) jQuery (13) OSX (10) MySQL (8) Javascript (7) Postgres (7) port (7) apache (6) Java (3) Smarty (2) html (2) pear (2) FCKEditor (1) XAMPP (1) css (1) git (1) perl (1) ruby (1)

Facebookバナー