Movable Type 備忘録

 

 jQueryで横スライドなメニューを表示する

今日(昨日)は隅田川花火大会のはずだったけど、TV 中継がなかったのですっかり忘れてました。

こんばんわ^^
行くのが面倒なので花火を TV で見ようとしてた、情緒お粗末な bzbell です。

考えてみれば、去年も一昨年も TV で見た記憶がない。 以前は TV で中継してたよね!? いつからやらなくなったんだろ。

学生の頃は、近くに友人宅があったので浴衣に着替えてよく見に行ったんですよ。
でも、花火はキレイだったと思うけど、それ以上にメチャ混んでるし、暑いしの記憶のほうが強く残ってます。

今年は(も)、東京湾大華火祭(8/11)とたまがわ花火大会(8/18)を見るくらいかな。

さて、今回は jQuery を使って横スライドするメニューを作ってみました。
横スライドのメニューといったら、こちらのmootoolsでスライドメニュー表示で紹介したカスタマイズが気に入ってます。

こちらのホームページを作る人のネタ帳さんのところで紹介されてたので試してみました。

jQuery は当然として、Interface プラグインを併用しています。
※上記 JavaScript は圧縮ファイル中に同梱されてました。

まずはサンプルですね。
各カテゴリ内の最新のエントリ 3 件分を一覧表示させてみました。

オリジナルでは、アルファチャンネル PNG を使用していたので PNG を使わず、わたし向けにカスタマイズしたものです。

カスタマイズ

  1. まず、必要な JavaScript をダウンロードします。
    こちらのdev.portalZINE | jQuery - Horizontal Accordionさんところから圧縮ファイルを入手します。

    そして、適当なフォルダに展開して、サーバにアップロードします。
    ちなみに、上記サンプルで使用している lib/main.js は以下のようになっています。

    lib/main.js

    1. $(document).ready(function() {
    2.     jQuery.noConflict();
    3.  
    4.     jQuery('.handle').bind('mouseover', function() {
    5.         /*
    6.          * マウスカーソルがメニュー合わさった場合、
    7.          * ボーダー色を変更します
    8.          */
    9.         jQuery(this).css({border: '1px solid #cc7eb1'});
    10.     });
    11.  
    12.     jQuery('.handle').bind('mouseout', function() {
    13.         if (jQuery(this).attr('rel') != 'selected') {
    14.             /*
    15.              * マウスカーソルがメニューから離れた場合、
    16.              * ボーダー色を元に戻します
    17.              */
    18.             jQuery(this).css({border: '1px solid #dcd6d9'});
    19.         }
    20.     });
    21.  
    22.     jQuery('.handle').bind('click', function() {
    23.         /*
    24.          * クリックしたメニュー番号を取得します
    25.          */
    26.         var no = jQuery(this).attr('id').slice(6);
    27.         /*
    28.          * 選択済みのメニューかチェックします
    29.          */
    30.         if (jQuery('.handle[@id$=handle'+no+']').attr('rel') != 'selected') {
    31.             jQuery('.handle').attr('rel', '');
    32.             /*
    33.              * すべてのメニューのボーダーを初期化して、
    34.              * クリックしたメニューのボーダー色を変更します
    35.              */
    36.             jQuery('.handle').css({border: '1px solid #dcd6d9'});
    37.             jQuery(this).css({border: '1px solid #cc7eb1'});
    38.             /*
    39.              * すべてのメニューの左にスライドします
    40.              */
    41.             jQuery('div[@id*=content]').animate({className:'content'}, 500, 'backin');
    42.             jQuery('div[@id*=hdiv]').animate({className:'start'}, 500, 'backin');
    43.             /*
    44.              * クリックしたメニューコンテンツを右にスライドします
    45.              */
    46.             jQuery('#hdiv'+no).animate({className:'end'},500, 'easein');
    47.             jQuery('#content'+no).animate({className:'endcontent'}, 500, 'easein');
    48.             /*
    49.              * クリックしたメニューを選択済みにします
    50.              */
    51.             jQuery('.handle[@id$=handle'+no+']').attr('rel', 'selected');
    52.         }
    53.     });
    54. });

    そして index.html は以下のようになります。

    index.html

    1. <MTTopLevelCategories>
    2. <MTIfNonZero tag="MTCategoryCount">
    3.  
    4. <div id="hdiv<$MTCategoryID$>" class="start">
    5.     <div id="content<$MTCategoryID$>" class="content">
    6.         <div class="hdiv-block">
    7.             <h3><$MTCategoryLabel decode_html="1" remove_html="1"$></h3>
    8.  
    9.             <ul>
    10.             <MTEntries lastn="3">
    11.             <li><a href="<$MTEntryPermalink$>" title="<$MTEntryTitle$>"><$MTEntryTitle$></a></li>
    12.             </MTEntries>
    13.             </ul>
    14.         </div>
    15.     </div>
    16. </div>
    17. <div class="handle" id="handle<$MTCategoryID$>">&nbsp;</div>
    18. </MTIfNonZero>
    19.  
    20. <$MTSubCatsRecurse max_depth="3"$>
    21. </MTTopLevelCategories>

    最後に css/main.css です。

    css/main.css

    1. .start {
    2.     float: left;
    3.     width: 0;
    4.     height: 200px;
    5.     overflow: hidden;
    6. }
    7.  
    8. div.handle {
    9.     float: left;
    10.     width: 38px;
    11.     height: 200px;
    12.     margin: 0 2px 0 0;
    13.     cursor: pointer;
    14.  
    15.     border: 1px solid #dcd6d9;
    16. }
    17.  
    18. /*
    19.  * 各メニューのタイトルイメージ
    20.  */
    21. div#handle4 { background: url(images/ha4.gif) no-repeat top left; }
    22. div#handle57 { background: url(images/ha57.gif) no-repeat top left; }
    23. div#handle6 { background: url(images/ha6.gif) no-repeat top left; }
    24. div#handle5 { background: url(images/ha5.gif) no-repeat top left; }
    25. div#handle8 { background: url(images/ha8.gif) no-repeat top left; }
    26.  
    27. .content {
    28.     padding-left: 0;
    29.  
    30.     float: left;
    31.     width: 0;
    32.     height: 200px;
    33.  
    34.     overflow:hidden;
    35. }
    36. .endcontent {
    37.     padding-left: 24px;
    38.     float: left;
    39.  
    40.     width: 320px; /* div.hdiv-block と同サイズ */
    41.     height: 200px;
    42. }
    43. .end {
    44.     float: left;
    45.     width: 360px; /* スライド量を示す横幅 */
    46.     height: 200px;
    47. }
    48.  
    49. .content h3{
    50.     border-bottom: 1px solid silver;
    51.     color: rgb(172, 194, 112);
    52. }
    53. .content ul {
    54.     margin: 0;
    55.     padding: 0;
    56.     list-style: none;
    57. }
    58. .content div.hdiv-block {
    59.     width: 320px; /* コンテンツの横幅 */
    60. }

以上です。
このカスタマイズでは、たまにクリック・イベントを取りこぼすというか、mouseover イベント時の動作がおかしそうです。
あと、Opera9.2 では期待通りの動作がされませんでした。Firefox、IE では問題なさそうです。

- 2007.07.29 追記 -

クリック・イベントを取りこぼす・・・という現象ですが原因がわかりました。
取りこぼすというより、タグの ID が重複してしまったために起こった現象でした。具体的には main.js を以下のように修正することで対応できます。

16行目
if ($('.handle[@id$=handle'+no+']').attr('rel') != 'selected') {
28行目
$('.handle[@id$=handle'+no+']').attr('rel', 'selected');

これによりカテゴリ ID が '5' と '57' の場合、重複するがことなくなりました。

たぶん、jQuery か Interface プラグインの不具合!? かなって思ってます。

 Trackback Pings(0)

No trackbacks found.

 Comments(0)

No comments found.

 Post a Comment

コメント用フィード