jQueryを使ったスライド開閉メニューをCookieでコントロールする
ちょっと前に流行った?アコーディオンメニューの開閉状態を
Cookieで保存する方法をメモをかねて紹介します。
必要なファイルを集める
面倒だと思うのでサンプルにまとめました。
サンプルファイルをダウンロードして新しいHTMLでJSファイルを読み込んでください。
HTMLを用意する
CSSファイルを読み込む
この記事でCSSの解説はしてません。。
JSファイルを読み込む
HTMLをマークアップする
HTMLがちょっと気持ち悪いと思う人もいるかもしれませんが
今回はこんな感じでマークアップしてます。
JSを書く
普通にアコーディオンメニューにする
今回は特にアコーディオン部分の記述にはふれませんが
以下の記述でアコーディオンになります。
jQuery Easingプラグインを使ってちょっと動きを変えてます。
何気ないアコーディオンもこういう動きなら面白いかもしれないですね。
単純に鬱陶しいだけにもなり得ますけど…
ちなみに、前回のエントリjQuery.easingscroll.jsはEasingプラグインを
含んでいるので併せて使うと楽しい動き(≠うざい動き)のサイトになりますね!
/* * @ スライドナビゲーション */ $("ul.sub_nav","div#sub").each(function(i){ // 開閉ナビで使う変数定義 var me = $(this), box = me.parent(), // 親要素のdiv.nav heading = me.prev().append(""), // 兄要素のh2にspan.toggleを追加して変数に保存 toggle = $("span.toggle",heading);// Toggle // 下層ナビとToggleボタンを隠す me.hide(); toggle.hide(); // Toggleボタンの表示非表示 heading.hover(function(){ toggle.show(); },function(){ // h2.openedの場合はToggleを表示したままにする if(!heading.hasClass("opened")) toggle.hide(); }); // Toggleクリック時の動作 toggle.click(function(){ heading.toggleClass("opened"); if(!box.hasClass("opened")) box.addClass("opened"); // アニメーション設定 me.animate({ height: "toggle" },{ easing: "easeOutBounce", // jQuery Easingを使って開閉時に跳ねるようにしてみる duration: 400, complete: function(){ if(!heading.hasClass("opened")) box.removeClass("opened"); } }); }); });
jQuery Cookieを使うのでちょっと紹介
jQuery.cookieプラグインを使ってます。
jQueryを使う場合はこれが一番わかりやすく、簡単にCookieを扱えます。
いちおう説明しておくと
$.cookie("Cookieの名前", "Cookieの値"); // 保存 $.cookie("Cookieの名前"); // 値の読み出し
という具合で使えます。
保存時、第3引数でオプションを指定することで保存日数などを指定できます。
$.cookie("Cookieの名前", "Cookieの値" { expires: 7, path: "/", domain: "jquery.com", secure: true });
また、値にnullを入れることでCookieを削除することができます。
$.cookie("Cookieの名前", null); // Cookieの削除
Cookieを使うタイミング
開閉状態を保存する場合Cookieを扱う箇所が3つあって
- Toggleをクリックしたとき(開けるとき) – Cookieを保存
- Toggleをクリックしたとき(閉じるとき) – Cookieを保存
- ページをロードしたとき – Cookieを読み出す
この3つのタイミングでCookieを保存したり、読み出すことで開閉状態を保存できます。
Cookieの保存方法をどうするのか
全てのアコーディオンでCookieを保存するのはきれいなやり方ではないので
開いた状態を記憶するためにCookieには[i]という値を保存していくことにします。
例えば、1つめのパネルが開いた場合、Cookieには[0]が保存されることになります。
さらに、2つめも開いた場合、[0][1]という値が保存されます。
閉じる場合には逆で[i]を取り除くことで元の状態になります。
これらの値はパネルが開いた順に保存されていくので
3-2-4という順番で開いた場合、[2][1][3]といったように保存されますが
値の削除時にはreplace関数を使うので、この順番は特に問題ありません。
ちなみに[]を使う理由はパネル数が10を超える場合に
0と1〜9の区別がつかなくなるのを防ぐためです。
とりあえずCookieを使って保存していく
まずはCookieの値を変数に保存しておきます。
これはページロードのタイミングで行います。
var cookie = ($.cookie("menu") && $.cookie("menu")!=null) ? $.cookie("menu") : "";
Cookieの名前はmenuにしています。
Cookiに値がある場合はcookieに値を保存
それ以外の場合は空の値を渡しておきます。
あとCookieに保存する・識別用の値を宣言しておきます。
// 開閉ナビで使う変数定義に追記する var pos = "["+i+"]"; // Cookieに保存する
この i はeach関数でループ時に得られる引数を使います。
準備ができたらClick時に保存するように記述します。
if(!box.hasClass("opened")){ // 開くとき box.addClass("opened"); cookie += pos; // このパネルの識別用の値をCookieの値に追記 $.cookie("menu",cookie); // Cookieの値をCookie["menu"]に保存する }else{ // 閉じるとき cookie = cookie.replace(pos,""); // このパネルの識別用の値をCookieの値から削除する $.cookie("menu",cookie.length==0 ? null : cookie); // Cookieの値をCookie["menu"]に保存する // このとき値が空になったらCookie["menu"]を削除する }
あとは初期表示パネルを最初に保存したCookieの値から決めます。
cookie.match(new RegExp(pos))の部分で判別してます。
// クッキーに[i]がある場合はナビを表示する if($.cookie("menu")==null || cookie.indexOf(pos)==-1){ me.hide(); toggle.hide(); }else{ box.addClass("opened"); heading.addClass("opened"); }
これらのソースコードを追記した完成版が以下になります。
/* * @ スライドナビゲーション * @ Cookieを使って開閉をコントロール */ // ナビゲーションで使うCookieを読みこんでおく var cookie = ($.cookie("menu") && $.cookie("menu")!=null) ? $.cookie("menu") : ""; $("ul.sub_nav","div#sub").each(function(i){ // 開閉ナビで使う変数定義 var me = $(this), box = me.parent(), // 親要素のdiv.nav heading = me.prev().append(""), // 兄要素のh2にspan.toggleを追加して変数に保存 toggle = $("span.toggle",heading), // Toggle pos = "["+i+"]"; // Cookieに保存する // クッキーに[i]がある場合はナビを表示する if($.cookie("menu")==null || cookie.indexOf(pos)==-1){ me.hide(); toggle.hide(); }else{ box.addClass("opened"); heading.addClass("opened"); } // Toggleボタンの表示非表示 heading.hover(function(){ toggle.show(); },function(){ // h2.openedの場合はToggleを表示したままにする if(!heading.hasClass("opened")) toggle.hide(); }); // Toggleクリック時の動作 toggle.click(function(){ heading.toggleClass("opened"); if(!box.hasClass("opened")){ box.addClass("opened"); cookie += pos; $.cookie("menu",cookie); }else{ cookie = cookie.replace(pos,""); $.cookie("menu",cookie.length==0 ? null : cookie); } // アニメーション設定 me.animate({ height: "toggle" },{ easing: "easeOutBounce", // jQuery Easing duration: 400, complete: function(){ if(!heading.hasClass("opened")) box.removeClass("opened"); } }); }); });
というわけで
肝心のCookieはかなり簡単に使えるということが伝わったでしょうか。
Cookieの保存方法は色々考えられるので試してみると楽しいです。
jQueryとjquery.cookie.jsを使って開閉を保持するメニューを作ってみる – caraldo.net
jQueryを使用したCookie開閉保持メニューをよりjQueryっぽく書き直す – caraldo.net
同じHTMLで2通りのやり方とか。後の記事の方がCookieがすっきりします。
Leave a comment
Trackbacks: 2
- Trackback URL for this entry
- Listed below are links to weblogs that reference
- jQueryを使ったスライド開閉メニューをCookieでコントロールする from 5509
-
pingback from links for 2009-05-26 | Webデザインのリンク集 Webデザインポータルサイト S5-Style [...] jQueryを使ったスライド開閉メニューをCookieでコントロールする | 5509 [...]
-
pingback from links for 2009-12-04 » ononolab.com - [...] jQueryを使ったスライド開閉メニューをCookieでコントロールする :: 5509 (tags: webdesign css tips javascript ajax tutorial jquery 案件) [...]
Comments: 8 - Leave a comment
デフォルトを開いた状態にするには、どうすれば良いでしょうか。
クッキー判定のあたりを変更するのかと思い、
いろいろ試してみたのですが上手くいきませんでした。
全体の処理を反対にする必要があるのでしょうか。
よろしければご教示ください。
メニューが複数、開けますが、
1つのみにするにはどうしたらいいでしょうか。
(別のメニューを開いたら、開いているメニューが閉じる。
必ず開いているメニューは1つのみ。)
貴重な情報、ありがとうございます!!
最初に質問している「sato」同様に要素が10個以上の場合に、おかしな表示になってしまいます。
何か回避方法ありますでしょうか?
ソースコードが悪かったですね!
32行目:
!cookie.match(new RegExp(pos))
部分を
cookie.indexOf(pos)==-1
に修正したのでもう大丈夫なはずです。
ものすごーく参考になりました。
ありがとうございます!
1点だけご質問させてください。
これを別ページ、別メニューにも使用する時、例えばページAでメニューA、ページBでメニューBと使用する場合同じcookieを見てしまう為、Aの情報をBが引き継いでしまいます。
この使い方をする場合はcookieを別けるべきでしょうか?
宜しくお願い致します。
貴重な情報をありがとうございました。
とても参考になりました。
ただ、サンプルソースではリンク先が全て空文字(=すべて同じという事)なので問題はないのですが、実際にリンク先を指定して実行すると、そのパス別にクッキーが保存されてしまうので、クッキーを保存する時にパスを指定してあげる必要があります。
パスは何でも良いと思い’/'にしました。
具体的にはこんな感じです。
$.cookie(“menu”,cookie,{path: ‘/’});
$.cookie(“menu”,cookie.length==0 ? null : cookie,{path: ‘/’});
一応参考になればと思い、コメントさせて頂きました。
お返事遅くなりごめんなさい。
コメントありがとうございます!
確かにそうですね。。そこ全然考えてなかったです。
追記しておきます!ありがとうございました!
大変参考になりました!!
が、セクション(開閉するテーブル)が10個以上になると
動作がおかしくなるようです。
たとえば開閉テーブルが10個以上の時、
1番目のテーブルを開いた状態でリロード(F5)すると
11番目のテーブルも開いた状態でリロードされます。
回避方法などありましたら教えていただけると大変助かります。