タイトルの通り、開いたツリーメニューからリンクを踏んで、またメニューのあるページに戻ってきた時にメニューを開いたままにしたいです。
色々と調べるうちにcookieを使うことはわかったのですが、どこもツリーメニューの方法が違うため載っているソースのどこを弄れば自分の使ったツリーメニューに対応させられるのかわかりませんでした。
javascriptを切った状態では開いたまま表示させたいので、ツリーメニューのソースは以下を参考にさせていただきました。
http://blog.ptlabo.net/index.php?id=06100064
これを利用して「戻ってきた時ツリーメニューを開いた状態に」することはできますか?
できない場合、
・cssオン、javascriptオフの状態では開いている
・ブラウザバックしたときに開いている
この条件に合うツリーメニューであれば何でも良いのでお教えいただきたいです。
初心者ですので詳細にご教授いただければ幸いです。
よろしくお願いします。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
要望を実現するためには、折りたたみのある項目すべて(もしくはどちらか一方をすべて)を保存する必要があります。
クッキーに保存できる文字数は限られています(4kだったかな?)
それ以下なら実現できると思いますが、私にはそこまで書く気力がありません。
これまでの事をヒントにご自分で努力することをお勧めします
私は、自分の書いたコードが最良だと思っていません。
むしろ毎日勉強している立場です。
今度はあなたの自助努力の成果を見せていただきたいと思っております
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も開いたままにしておきたいです)
しつこく聞くようで申し訳ないのですが、ご回答いただければ幸いです。
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>
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の何がどうなっているのかもわからないもので、どこをどのように弄ればそのようにプログラムすることができるのか、よろしければ教えていただきたいです。
No.1
- 回答日時:
他の回答も一応見たのですが、
「javascriptオフでも見れる」という条件に合うものかどうかわからなかったので質問させていただきました。
display:noneをcssで指定するだけでは、cssがオンでjsがオフな時ツリー開きませんよね?
今回私が参考にしている方法で作ったツリーメニューをcookieに保存させる事はできないのでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript [Java] Edgeでのアドレスバー非表示について 3 2022/04/20 17:51
- HTML・CSS HTMLを正しく表示させるには 2 2023/06/18 09:12
- ブルーレイ・プレーヤー・レコーダー 動画のDVD出力と再生について 6 2022/12/07 09:47
- CGI (フリーの)ツリー掲示版CGI、昔は多用させてもらいましたが・・今セキュリティ上どうでしょう? 2 2023/06/25 07:18
- その他(ソフトウェア) Ghosteryのプライバシー 広告ブロッカーのトラブルについて質問です。 1 2023/05/03 21:09
- UNIX・Linux raspberrypi に bluealsaを入れようにも見つからない 1 2023/02/04 10:55
- 筋トレ・加圧トレーニング 72歳父親がデイサービスに行きたくないらしいので自宅で筋トレメニューを考えています 3 2023/03/26 22:30
- docomo(ドコモ) 通話録音が(最初から)自動的に始まるアプリは? 7 2023/01/16 15:53
- その他(スマホアプリ・スマホゲーム) au WiFi アプリをインストールして使えるかどうか不安になりました、 ★アプリのメニューから、何 2 2022/03/31 16:53
- Windows 10 エクスプローラでリスト表示かつその場で階層表示はできますか? 1 2022/09/02 01:48
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
JavaScriptで、?マークとコロ...
-
【javascript で動的に a タグ...
-
大量のチェックボックス状態取...
-
javascriptでEnterキーをtabキ...
-
for(var i=0;...) の i の値を...
-
多階層ドロップダウンのスマホ...
-
jquery 3の倍数のliだけ色を変える
-
JavaScript インクリメントの書...
-
JS <a></a>タグ内のリンク先ア...
-
jquery ドロップダウンメニュー...
-
【JQuery】アコーディオンの入...
-
div要素をランダムに表示させたい
-
複数のラジオボタン項目でのテ...
-
タブメニューを上下に設置
-
jQueryでネスト構造の<li>がク...
-
onmouseoverの表示切り替えが上...
-
jQueryセレクタ/複数要素の指...
-
MAX関数を使ってからLEFT JOIN...
-
jspでcssが読み込めない
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
javascriptでEnterキーをtabキ...
-
クリックした<a>タグのみにClas...
-
チェックボックスに入っている...
-
【javascript で動的に a タグ...
-
jquery ドロップダウンメニュー...
-
「jQuery」アコーディオンメニ...
-
jQueryのeqで最後からn番目以降...
-
jQueryで、リンクURLの一致を確...
-
ネストされたチェックボックス...
-
javascriptで、クリックしたら...
-
文字と数字が混在する要素のsor...
-
onmouseoverの表示切り替えが上...
-
jQueryでネスト構造の<li>がク...
-
タブメニューを上下に設置
-
<li></li>の数を制限
-
jQuery多層式アコーディオンメ...
-
CSSとJavaScriptを使ってドロッ...
-
複数の画像をランダム(シャッ...
-
どの<li><a> が押されたか判別...
おすすめ情報