![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
タイトルの通り、開いたツリーメニューからリンクを踏んで、またメニューのあるページに戻ってきた時にメニューを開いたままにしたいです。
色々と調べるうちにcookieを使うことはわかったのですが、どこもツリーメニューの方法が違うため載っているソースのどこを弄れば自分の使ったツリーメニューに対応させられるのかわかりませんでした。
javascriptを切った状態では開いたまま表示させたいので、ツリーメニューのソースは以下を参考にさせていただきました。
http://blog.ptlabo.net/index.php?id=06100064
これを利用して「戻ってきた時ツリーメニューを開いた状態に」することはできますか?
できない場合、
・cssオン、javascriptオフの状態では開いている
・ブラウザバックしたときに開いている
この条件に合うツリーメニューであれば何でも良いのでお教えいただきたいです。
初心者ですので詳細にご教授いただければ幸いです。
よろしくお願いします。
A 回答 (5件)
- 最新から表示
- 回答順に表示
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_12.png?e8efa67)
No.5
- 回答日時:
要望を実現するためには、折りたたみのある項目すべて(もしくはどちらか一方をすべて)を保存する必要があります。
クッキーに保存できる文字数は限られています(4kだったかな?)
それ以下なら実現できると思いますが、私にはそこまで書く気力がありません。
これまでの事をヒントにご自分で努力することをお勧めします
私は、自分の書いたコードが最良だと思っていません。
むしろ毎日勉強している立場です。
今度はあなたの自助努力の成果を見せていただきたいと思っております
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_12.png?e8efa67)
No.4
- 回答日時:
訂正します。
これまでの場合はツリーメニュー以外のLIとかULにも処理が及んでしますので、一番親のULにclass="treemenu"を追加します
クリックされるとその度にチェックしにいきます。
なのでそこを訂正しました!
しかも初の説明付き!
<html>
<body>
<ul id="a" class="treemenu">
<li>A
<ul>
<li><a href="htp://blove.cc/tes1/">A-1</a></li>
<li>A-2
<ul>
<li><a href="htp://blove.cc/tes1/">ページ1へ飛ぶ</a></li>
<li><a href="htp://blove.cc/tes2/">ページ2へ飛ぶ</a></li>
</ul>
</li>
<li>A-3
<ul>
<li><a href="htp://blove.cc/tes1/">ページ1へ飛</a></li>
<li><a href="htp://blove.cc/tes2/">ページ2へ飛ぶ</a></li>
</ul>
</li>
</ul>
</li>
<li>b
<ul>
<li><a href="htp://blove.cc/tes1/">ページ1へ飛ぶ</a></li>
<li><a href="htp://blove.cc/tes2/">ページ2へ飛ぶ</a></li>
</ul>
</li>
</ul>
<script>
addEvent( window,'load', function(){ openTreeMenu2('a') }); //イベントはwindow.onload=function(){ でもいいが、他のプログラムとの共用ができないかも!なので追加
addEvent( document.body, 'click', chkClick );//onclickイベントは、いろいろなところにとりつけるよりも、body1箇所ですませるとすっきり
function chkClick( evt ){//クリックのイベント処理
var element = evt.target || event.srcElement;//イベントが起きた箇所のエレメントを調べる
if( element.tagName != 'LI' ) return; //タグがLI以外なら必要ないのでやめる
if( !checkParentCSS( element, 'ul', 'treemenu' ) ) return;//エレメントが属する親を調べてclassに"tremenu"があるか調べる。このおかげで普通のULなのかメニューなのかわかる
putCookie( 'li', getFirstText( element ),10);//LI要素の最初の#textノードの文字を調べ、クッキーに保存する。期間は10日
putCookie( 'lic', getChildDisplay( element ),10);//li要素の子のulが開いているか閉じているかも調べクッキーに保存する
if(1) openTreeMenu2('a'); //1なら対象外は隠す。メニューの折りたたみに好みがあるみたいなので0か1を指定
else {
var ul = element.firstChild;//liの中にあるulを調べて開くか閉じるか決める
while( ul.nodeName != 'UL' ){ ul = ul.nextSibling; if( !ul ) return }//ulを探す。そうでなければ戻る
ul.style.display = ( ul.style.display == 'none') ? 'block':'none';//閉じていれば開き、そうでなければ逆に三項演算子を利用
}
}
function checkParentCSS( element, tag, css ){//親のタグとクラスを探る。今回は li で treemenu
var tag = tag.toUpperCase();//タグを返す関数は大文字を返すので、大文字にしておく
var reg = new RegExp( '\b*'+ css+ '\b*' );//正規表現で検索。なので className=" abc treemenu di dfji" みたいなのでも見つけ出せる
while( element = element.parentNode ){//treeの親をどんどん探す。
if( element.tagName == tag && element.className.match( reg ) ) return true;//タグが同じでクラスも同じなら有りで帰る
if( element.tagName == 'BODY' ) return false;//親をたどると結局、空になるがBODYでやめる。だからなくてもいいかな?
}
}
function openTreeMenu2( elementId, keyword, flag ){//折りたたみメニューの本体
var element = ( typeof( elementId ) == 'string' )? document.getElementById( elementId ): elementId;//idでもオブジェクトでも処理
var ul = element.getElementsByTagName('ul');//id="a"以下のすべてのulを拾い出す
for( var i=0, m= ul.length; i<m; i++) ul[i].style.display = 'none';//すべてのULを一旦、消す
keyword = keyword || getCookie('li');//keywordは今回使用していないが、無い場合はクッキーに保存したliのテキストを読み込む
flag = flag || getCookie('lic') - 0;//flafはそのLI要素の中のULが、開いているかどうかを保存してある
if( keyword ) {//LIにあるテキストをさがす
var li = element.getElementsByTagName( 'li' );//すべてのLIのテキストを検索するために収集
for( var i=0, m=li.length;i<m;i++){//ループ処理
if( getFirstText( li[i] ) == keyword ){//LI要素のテキストと検索するテキストを比較
var descendant = li[i];//一致したので、ここを基準に閉じたULを開いていく
do {
var descendant = descendant.parentNode;//親の親
if( descendant.nodeName == 'UL' ) descendant.style.display = 'block';//表示
} while( descendant.nodeName != 'BODY' )//親がBODYならやめる
if( !flag ){//今度はLIの中のULを開くかどうか?
var nd = li[i].firstChild;
while( nd ){
if( nd.nodeName == 'UL' ) nd.style.display = 'block';//ULタグが見つかったら表示する
nd = nd.nextSibling;//次のエレメント(兄弟を探す)
}
}
}
}
}
element.style.display = 'block';//対象を開く
}
function getFirstText( element ){//タグで囲まれた中の文字を拾い出す
var nd = element.firstChild;
while( nd ){//例えば<span>abc<span> <p>~ 見たいに<p>の前に空白があると#textノードとみなされる。ブラウザによって処理が微妙
if( nd.nodeName == '#text' ) return nd.nodeValue;
nd = nd.nextSibling;
}
return false;
}
function getChildDisplay( element ){//今回の場合LI要素の中のUlが開いていれば1、閉じていれば0を返す
var child = element.firstChild;
while( child ){
if( child.nodeName == 'UL') if( child.style.display == 'block') return 1;
child = child.nextSibling;
}
return 0;
}
function addEvent(elementId, evt, eventHandler, flag){//イベント追加処理/cc_onは、IEだけが実行される。最近はこれが主流?
var element = ( typeof( elementId ) == 'string' )? document.getElementById( elementId ): elementId;
element./*@cc_on @if(1)attachEvent('on'+ @else @*/addEventListener(/*@end@*/evt, eventHandler, flag);
}
function getCookie( valueName ){//クッキーを得る
var value = '', c, cookies = document.cookie.split('; ');
for(var i in cookies)
if((c = cookies[i].split(/=/), c[0]==valueName)) return c[1]? decodeURIComponent( c[1] ): '';//文字をそのまま保存するとやばいのでエスケープ処理
return false;
}
function putCookie( valueName, value, day ){//クッキーの保存、保存期間は日単位
document.cookie = valueName + '=' + encodeURIComponent( value )+ '; expires='
+ new Date( (new Date).getTime() + day * 86400000).toGMTString();
}
</script>
</body>
</html>
とても丁寧にありがとうございます!
無知故に苦労しましたが、お陰でなんとかやりたかったデザインに組み込むことができました。
重ねて質問なのですが、
>if(1) openTreeMenu2('a'); //1なら対象外は隠す。メニューの折りたたみに好みがあるみたいなので0か1を指定
↑この値を0の「対象外も隠さない」設定にしたあと、メニューを複数開く場合、クッキーの保存が最後に開いたもののみになるようですが(メニューAを開き、そのあとBも開く→飛んで戻ってくる→Bしか開いていない という状態です)、
「複数開いた」ことを保存させるようにする事はできますか?
(AもBも開いたら、AもBも開いたままにしておきたいです)
しつこく聞くようで申し訳ないのですが、ご回答いただければ幸いです。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_12.png?e8efa67)
No.3
- 回答日時:
遅くなりました!なんとなくカレンダーを作るのにハマってました!
まじめに作ると長いね~。補足説明は、これが記憶にあるうちにね!
字下げするために全角スペースにしました。タブとかに置きかえして
使用のこと。スクリプトとスタイルシートは外部に。
<html>
<body>
<ul id="a">
<li>A
<ul>
<li><a href="htp://blove.cc/tes1/">A-1</a></li>
<li>A-2
<ul>
<li><a href="htp://blove.cc/tes1/">ページ1へ飛ぶ</a></li>
<li><a href="htp://blove.cc/tes2/">ページ2へ飛ぶ</a></li>
</ul>
</li>
<li>A-3
<ul>
<li><a href="htp://blove.cc/tes1/">ページ1へ飛</a></li>
<li><a href="htp://blove.cc/tes2/">ページ2へ飛ぶ</a></li>
</ul>
</li>
</ul>
</li>
<li>b
<ul>
<li><a href="htp://blove.cc/tes1/">ページ1へ飛ぶ</a></li>
<li><a href="htp://blove.cc/tes2/">ページ2へ飛ぶ</a></li>
</ul>
</li>
</ul>
<script>
addEvent( window,'load', function(){ openTreeMenu2('a') });
addEvent( document.body, 'click', chkClick );
function chkClick( evt ){
var element = evt.target || event.srcElement; if( element.tagName != 'LI' ) return;
putCookie( 'li', getFirstText( element ),10);
putCookie( 'lic', getChildDisplay( element ),10);
if(1) openTreeMenu2('a'); //1なら対象外は隠す
else {
var ul = element.firstChild;
while( ul.nodeName != 'UL' ){ ul = ul.nextSibling; if( !ul ) return }
ul.style.display = ( ul.style.display == 'none') ? 'block':'none';
}
}
function openTreeMenu2( elementId, keyword, flag ){
var element = ( typeof( elementId ) == 'string' )? document.getElementById( elementId ): elementId;
var ul = element.getElementsByTagName('ul');
for( var i=0, m= ul.length; i<m; i++) ul[i].style.display = 'none';
keyword = keyword || getCookie('li');
flag = flag || getCookie('lic') - 0;
if( keyword ) {
var li = element.getElementsByTagName( 'li' );
for( var i=0, m=li.length;i<m;i++){
if( getFirstText( li[i] ) == keyword ){
var descendant = li[i];
do {
var descendant = descendant.parentNode;
if( descendant.nodeName == 'UL' ) descendant.style.display = 'block';
} while( descendant.nodeName != 'BODY' )
if( !flag ){
var nd = li[i].firstChild;
while( nd ){
if( nd.nodeName == 'UL' ) nd.style.display = 'block';
nd = nd.nextSibling;
}
}
}
}
}
element.style.display = 'block';
}
function getFirstText( element ){
var nd = element.firstChild;
while( nd ){
if( nd.nodeName == '#text' ) return nd.nodeValue;
nd = nd.nextSibling;
}
return false;
}
function getChildDisplay( element ){
var child = element.firstChild;
while( child ){
if( child.nodeName == 'UL') if( child.style.display == 'block') return 1;
child = child.nextSibling;
}
return 0;
}
function addEvent(elementId, evt, eventHandler, flag){
var element = ( typeof( elementId ) == 'string' )? document.getElementById( elementId ): elementId;
element./*@cc_on @if(1)attachEvent('on'+ @else @*/addEventListener(/*@end@*/evt, eventHandler, flag);
}
function getCookie( valueName ){
var value = '', c, cookies = document.cookie.split('; ');
for(var i in cookies)
if((c = cookies[i].split(/=/), c[0]==valueName)) return c[1]? decodeURIComponent( c[1] ): '';
return false;
}
function putCookie( valueName, value, day ){
document.cookie = valueName + '=' + encodeURIComponent( value )+ '; expires='
+ new Date( (new Date).getTime() + day * 86400000).toGMTString();
}
</script>
</body>
</html>
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_12.png?e8efa67)
No.2
- 回答日時:
参考にした!っていうより
書いたプログラムを見せていただいたほうが早い。
「javascriptオフでも見れる」というのであれば
逆に考えて、スクリプトが実行できるなら、
読み込みが終わった時点でメニューを折りたためば?
引き続き回答ありがとうございます。
参考にした、というかそのまま当てはめただけなので…
<script type="text/javascript" language="javascript">
document.writeln("<style type=\"text/css\">");
document.writeln("#ほにゃらら{display:none;}");
document.writeln("<\/style>");
</script>
をhead内に入れて、メニューの部分を、
<span onclick="this.nextSibling.style.display=(this.nextSibling.style.display=='block'?'none':'block');">
メニュー名</span>
<div id="ほにゃらら">
<a href="該当URL">項目1</a><br>
<a href="該当URL">項目2</a><br>
</div>
という風に書きました。本当にそのままですが…
これならjavascriptを切ると同時にdisplay:noneも無効になってくれそうな事が理解できたので使いたいと思ったのです。
>「javascriptオフでも見れる」というのであれば
>逆に考えて、スクリプトが実行できるなら、
>読み込みが終わった時点でメニューを折りたためば?
そんな事ができるのですか!
過去の質問でpipi様が回答されていたプログラムを参考に「クッキー保存させるツリーメニュー」を作成して、それを「読み込みが終わった時点でメニューを折りたたむ」ように改変、もしくは書き足しする、という事でいいのでしょうか。
お恥ずかしながらまだ、javascriptの何がどうなっているのかもわからないもので、どこをどのように弄ればそのようにプログラムすることができるのか、よろしければ教えていただきたいです。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_12.png?e8efa67)
No.1
- 回答日時:
他の回答も一応見たのですが、
「javascriptオフでも見れる」という条件に合うものかどうかわからなかったので質問させていただきました。
display:noneをcssで指定するだけでは、cssがオンでjsがオフな時ツリー開きませんよね?
今回私が参考にしている方法で作ったツリーメニューをcookieに保存させる事はできないのでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
タブ切り替えの初期表示について
-
「jQuery」アコーディオンメニ...
-
SeleniumBasicのエラー対策を教...
-
javascriptでEnterキーをtabキ...
-
特定のクラスを持つ<li>を非表...
-
JQueryタブのアクティブ アン...
-
javascript テキストエリアを1...
-
MAX関数を使ってからLEFT JOIN...
-
クリックで色変更後に既に変更...
-
iframe内のリンクが飛ばないの...
-
前回の質問の続き function mov...
-
画面が真っ白になるのはどうして?
-
javascriptでオブジェクトの重...
-
1枚の画像をクリックして複数の...
-
Vb.net2005での画像の合成方法
-
JavaScriptでの画像切り替えを...
-
画像のスムーズなフェードイン方法
-
c++std::string型をTCHARに変換...
-
removeEventListenerについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
jquery ドロップダウンメニュー...
-
JQueryタブのアクティブ アン...
-
jQueryのeqで最後からn番目以降...
-
チェックボックスに入っている...
-
「jQuery」アコーディオンメニ...
-
クリックした<a>タグのみにClas...
-
javascriptでEnterキーをtabキ...
-
【JQuery】アコーディオンの入...
-
タブ切り替えの初期表示について
-
jQueryでネスト構造の<li>がク...
-
どの<li><a> が押されたか判別...
-
大量のチェックボックス状態取...
-
フルスクリーンについて・・・
-
jQueryのhide,showで中の要素が...
-
【jQuery】遅延実行(タイムラ...
-
アコーディオン自動開閉メニュ...
-
jQueryで表示する吹き出しdivの...
-
JqueryFileTree.js でフォルダ...
-
タブ切り替えの初期表示に関して
おすすめ情報