2004年8月24日

サイドメニュー折りたたみ(改)

August 24,2004 11:55 PM
Tag:[]
Permalink

2004.12.06 追記
サイドメニュー折りたたみのエントリーを書き直しましたので

サイドメニュー折りたたみスクリプト(cookie等改善版)

を参照ください。


我楽さんのサイトにあるサイドメニューの折りたたみが気に入り、あらかたできたので、ぼちぼちエントリー追加。経由で

JUGEMカスタマイズ講座ナビゲーションの折り畳み

に随分前から取りかかってましたがようやく陽の目を見ることになりました。苦労した点はあとで書くとして、とりあえずメモ。
なお関連記事もございますのでよろしければ後ほど参照ください。

この機能は文字のごとくサイドメニューの折りたたみです。メニューのタイトル部分は常時表示で、タイトル横にある[+]/[-]でメニューリストの表示・非表示を切り替えられます。またメニュー単位に表示・非表示の初期状態を設定できます。
私の場合はリストが長いものに折りたたみをつけ、さらに利用度が低いと思われる「Monthly Archives」と「Recent Entries」を折りたたんだ状態にしてみました。またメニューのリスト合計数をタイトル横に表示できます。そのままの流用では正常に表示されませんでしたが若干のスクリプト修正で有効になりました。以下設定方法です。

1.テンプレートのサイドメニューにid属性を付与
下記の要領で折りたたみたいサイドメニューのタイトルに「id=xxname」、リストの方に「id=xxlist」を付与します。"name"と"list"は固定、"xx"の部分はメニュー毎に異なる名称を付与します(例えばカテゴリーリストは"category"、エントリーは"entry"等)。

<div class="sidetitle">
Categories
</div>
 
<div class="side">
<MTCategories>
<a href="<$MTCategoryArchiveLink$>">
<$MTCategoryLabel$></a>  [<$MTCategoryCount$>]<br />
</MTCategories>
</div>
<div class="sidetitle" id="categoryname">
Categories
</div>
 
<div class="side" id="categorylist">
<MTCategories>
<a href="<$MTCategoryArchiveLink$>">
<$MTCategoryLabel$></a>  [<$MTCategoryCount$>]<br />
</MTCategories>
</div>

2.JavaScriptファイルの作成
下記の内容を丸ごとコピーして"menufolder.js"という名前のファイルを作成します。作成したファイルはここではmt.cgiが配置されているディレクトリに配置することにします。赤および青字はオリジナルのスクリプトとの差分を示しています。
オリジナルではスクリプトをテンプレートに直接記述されていますが、他のテンプレートで同機能を持ちまわることを考え、ここでは独立したファイルにしてみました。注:ファイルの文字コードはBlogの文字コードと一致させてください。またMac+IEの場合は、後述の「テンプレートにJavaScriptファイル読み込みの設定」で示された位置に、本スクリプトを直接埋め込むようにしてください(jsファイルを正常に読み込めない報告を頂いております)。

function InitFoldNavi() {
  FoldNavigation('newentry','off',false); // new entry
  FoldNavigation('entry'   ,'on' ,true);  // entry
  FoldNavigation('comment' ,'on' ,false); // comment
  FoldNavigation('tb'      ,'on' ,false); // trackback
  FoldNavigation('archive' ,'off',true);  // archive
  FoldNavigation('link'    ,'on' ,true);  // link
  FoldNavigation('profile' ,'off',false); // profile
}
function FoldNavigation(idName,initMode,viewNum) {
  var openMark = '[+]'; // open mark
  var closeMark = '[?]'; // close mark
  var preMark = true; // position of mark
  var idTitle = Array(idName,'name').join('');
  var idList = Array(idName,'list').join('');
  var objTitle = this.document.getElementById(idTitle);
  var objLists = this.document.getElementById(idList);
  if (!objTitle || !objLists) return;
  var dispMode = objLists.style.display;
  if (!dispMode) {
    var tmpText = Array('FoldNavigation(',"'",idName,"','chng','');return(false);").join('');
    var insMark = new Array();
    var insText = new Array();
    insMark[insMark.length] = Array('<a class="foldmark" href="#" onclick="',tmpText,'" onkeypress="',tmpText,'">').join('');
    insMark[insMark.length] = (initMode == 'off') ? openMark : closeMark;
    insMark[insMark.length] = '</a>';
    if (preMark) insText[insText.length] = insMark.join('');
    //    insText[insText.length] = objTitle.innerHTML;
    if (viewNum) {
      var objItems;
      objItems = objLists.getElementsByTagName('a');
      var counter;
      if (idName == "link") { // delete 3Link
        counter = objItems.length - 3;
      } else {
        counter = objItems.length;
      }
      insText[insText.length] = '&nbsp;&nbsp;' + Array(' <span>',counter,'</span>').join('') + ' ' + objTitle.innerHTML;
    } else {
      insText[insText.length] = '&nbsp;&nbsp;' + objTitle.innerHTML; 
    }
    if (!preMark) insText[insText.length] = insMark.join('');
    objLists.style.display = (initMode == 'off') ? 'none' : 'block';
    objTitle.innerHTML = insText.join('');
  } else if (initMode == 'chng') {
    var objMarks = objTitle.getElementsByTagName('a');
    for (i=0;i<objMarks.length;i++) {
      if (objMarks[i].className == 'foldmark') {
        objMarks[i].firstChild.nodeValue = (dispMode == 'none') ? closeMark : openMark;
      }
    }
    objLists.style.display = (dispMode == 'none') ? 'block' : 'none';
  }
}
InitFoldNavi();

以下スクリプトの説明です。上部にある

FoldNavigation('newentry','off',false); 

ですが、()内のパラメータの意味はそれぞれ

FoldNavigation('id属性名','初期状態',リスト数表示);

です。id属性名が先の"category"や"entry"に対応します。つまり折りたたみをしたいメニュー分、この行を作ります(注:全角文字(空白など)が混入しないように気をつけてください)。その右の初期状態はページを開いた時の折りたたみ状態です。onは開いた上体、offは閉じた状態です。最後のリスト数表示はタイトル横にそのメニュー内のリスト数(例えばカテゴリーメニューにカテゴリーが10あれば"10")を表示します。'true'と記述すれば表示、'false'は非表示です。

青色部分はオリジナルから変更した部分です。以下主な変更内容です。
まず、"[+]"、"[?]"はメニュータイトル横に表示される折りたたみ切り替え用のリンク文字です(好きな文字を設定できます)。
このスクリプトは前述の通りタイトル横にリストの合計数を表示してくれます。オリジナルは"li"のタグ数を計算して表示していますが改造版では<a href="?">タグの数を計算するようにしています(リスト表示に<li>タグを使っていないため)。またオリジナルではリストの合計数をタイトル右側に"()"で表示していますが、このスクリプトではタイトルの左側に表示するようにしてみました。BlogPeopleのリンク数についてはバナーと登録用リンクの計3つが余分なので、その分を減算しています(エレガントさに欠けますが…)。
さらに折りたたみ用マークをつけることでタイトルの位置が若干左にずれるため、タイトル左に全角空白を1文字挿入して微妙に位置調整しています(ただしマークをタイトル右側に挿入することが前提)。

3.テンプレートにJavaScriptファイル読み込みの設定
テンプレートの一番最後の方(</body>の直前等)に、先に作成したJavaScriptファイルを読み込むためのタグをを挿入します。

<script type="text/javascript" src="http://xxx/menufolder.js"></script>

"xxx"の部分には任意のURLを設定してください。JavaScriptファイルをmt.cgiと同じディレクトリに配置した場合、私のblogを例にとるとxxxの部分は"www.koikikukan.com"になります。

4.スタイルシートの追加
styles-site.css の .sidetitle の下に下記を追加します。

.sidetitle a {
    float: right; /* マークを右側に配置 */
    width: 1.8em;
    text-decoration: none;
}
.sidetitle a.foldmark {
    font-size:7px; /* マークのフォントサイズ */
    padding-right:3px; /* マークの位置調整 */
}

このスタイルシートは適切な指定でないかも知れませんがとりあえず正常に動作しています。

設定方法は以上です。当初マークが右側に配置されなくて悩みましたがオリジナルのサイトにかなりの質問コメントが寄せられており、そちらを参照しました(スタイルシートのfloat: rightの設定とJavaScript上部にある「マークの挿入位置」がきちんと指定できていれば大丈夫みたいです)。
マークは右側に無事配置されたのですが今度はタイトル右端にくっついてしまうのが気になるので、これはpaddingで調整しました。blogの中にblogを作っている気分です。この時スタイルシートを変更しても変更が反映されずまたしても悩みましたが、ブラウザのキャッシュに古いデータが残っているのが原因のようでした。IEであればブラウザの「更新」をクリックするかキャッシュを削除しましょう。

ちなみに「Recent Comments」等もリスト数を取得できる筈なのですが動作確認できていないので保留にしています。できるようになりました。↓追記参照ください。

2004.08.31追記
上記2.の青色部分を下記のスクリプトの青色部分と入れ替えれば「最近のコメント」も件数表示が可能になります。これは「最近のコメント」にあるURLのaタグの"#"を計数しています。

if (viewNum) {
  var objItems;
  var href;
  var commentCounter = 0;
  objItems = objLists.getElementsByTagName('a');
  if (idName == 'comment') {
    for (i = 0; i < objItems.length; i++) {
      href = objItems[i].getAttribute("href");
      if(href.indexOf("#") == -1){
        commentCounter++;
      }
    }
  }
  var counter;
  if (idName == "link") {
    counter = objItems.length - 3;
  } else {
    counter = objItems.length - commentCounter;
  }
  insText[insText.length] = '&nbsp;&nbsp;' + Array(' <span>',counter,'</span>').join('') + ' ' + objTitle.innerHTML;
} else {
  insText[insText.length] = '&nbsp;&nbsp;' + objTitle.innerHTML;
}

2004.09.20追記
BlogPeople以外にリンクを増やす場合は

if (idName == "link") { // Linkは不要な3リンク分を減算
  counter = objItems.length - 3;
} else {
  counter = objItems.length;
}

の部分を

if (idName == "link1") {
  counter = objItems.length - 3;
} else if (idName == "link2") {
  counter = objItems.length - 2;
} else {
  counter = objItems.length;
}

のように、link名を適宜対応した属性名のものに変更して条件文を必要な分だけ追加してください。追加するのは減算が必要な場合だけです。

2004.10.01追記
コピー後、";"のある行は途中で折り返しがないかご確認ください(折り返しがあるとsafariで正常に表示されないようです)

2004.11.01追記
サイドメニュー折りたたみ状態保持スクリプトおよびサイドメニュー折りたたみの動作遅延対処へのリンクを本文に追加しました。

2004.11.02追記
JavaScriptの日本語コメントを半角英数に修正しました。またMac+IEの場合はmenufolder.jsを正常に読み込めないようですので、スクリプトを直接テンプレート内に埋め込む記述を追加しました。

Comments [77] | Trackbacks [26]
Now loading...
ギターに入った猫
掲載広告募集
Styles
Font Size
Default
For defective color vision
Gray Scale
RGB Color
Search this site

このブログをメールで購読する by:FeedBurner

AMN
Categories
Monthly Archives
2020年
2019年
2018年
2017年
2016年
2015年
2014年
2013年
2012年
2011年
2010年
2009年
2008年
2007年
2006年
2005年
2004年
2003年
BlogPeople
Syndicate this site
FeedBurner(RSS1.0/RSS2.0/Atom)
Counter
これまでのアクセス
Powered by
Movable Type 6.0.3