javascripでの特殊なドロップダウンメニューの作成について質問させてください。


現在、あるサイトでグローバルナビゲーションにドロップダウンメニューを実装しようとしているのですが、壁にあたってしまいました。

↓参考サイトです
http://flatone.s206.xrea.com/index.html

こういったドロップダウンメニューなのですが、例えばこのメニューのページ1というボタンをクリックするとhttp://flatone.s206.xrea.com/page1/index.htmlというURLに飛びますが、このURLの/page1ディレクトリ以下を閲覧中の時にはページ1ボタンのドロップダウンメニューを"出さない"ということがやりたいのです。

ちなみにメニュー下に表示しているスクリプトはここに読み込んでいるmenu.jsの内容です。
自分なりに色々とやってはみたものの、javascriptの経験が浅いので正直なところよくわからないのが現状です。

どなたか解決法をご教授いただければ幸いです。
よろしくお願いします。

回答の条件
  • 1人50回まで
  • 登録:
  • 終了:2009/10/18 02:39:37
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Cherenkov No.3

回答回数1504ベストアンサー獲得回数493

ポイント50pt

こういう質問はコメント欄を有効にしましょう。

一番簡単なのは、http://flatone.s206.xrea.com/page1/index.htmlのhtmlの

表示したくないプルダウンメニューのMM_showHideLayers('Layer1','','show')を

MM_showHideLayers('Layer1','','hide')に書き換えるのが早いけど、

動的に変えるならこうですかね。

(ちゃんと関数つくってあったんですね。引数の扱いが読み辛いので分かってきたら直したほうがいいかと思います。)

以下のコードをmenu.jsに追加するか、scriptタグで囲んでpage1/index.htmlに貼るか。

if(/\/page1\//.test(location.href)) {
  var a = document.getElementsByTagName('a');
  for(var i=0; i<a.length; i++) {
    if(/Layer1/.test(a[i].onmouseover)){
      a[i].onmouseover = "MM_showHideLayers('Layer1','','hide')";
    }
  }
}

説明

正規表現のtestメソッドでアドレスに/page1/が含まれるか判定。

表示したくないプルダウンを指定するためにdocument.getElementsByTagNameを使ってすべてのaタグを抽出。

すべてのaタグのなかから再びtestメソッドを使ってLayer1を含むものを洗い出す。

マッチしたらonmouseoverを上書き。



プルダウンメニューにid属性(Layer1)を付けてやれば効率があがります。

if(/\/page1\//.test(location.href)) {
  var hide = document.getElementById('Layer1');
  hide.onmouseover = "MM_showHideLayers('Layer1','','hide')";
}

とか。

id:yurina1023

ご回答ありがとうございます。

この方法は簡単に実現できて大変良かったのですが、なぜかいつもページを開いて1回目にメニューボタンにマウスオーバーした時はドロップダウンメニューが表示されてしまいます。

2回目以降のマウスオーバー時には表示されないのですが。

この問題の解決法を今一度ご教授願えればと思います。

よろしくお願いします。

2009/10/17 15:16:04

その他の回答2件)

id:Reiaru No.1

回答回数152ベストアンサー獲得回数38

現在のページを取得する方法が非常にやっつけなのですが、

概念としては各 index.html 内 (page1 ~ page5) に以下の様な記述が必要なのではないかと思います。


それぞれにある既存の <li> をコメントアウトし、

そこに <Script Language="JavaScript"> ~ </script> までをコピーすれば動作するにはする筈です。

(本来は、追加する JavaScript 部分を menu.js に定義してそれを呼び出す形にすべきなのですが)


<!--//メニュー5-->

<!--
  <ul>
		<li><a href="index.html" onmouseout="MM_showHideLayers('Layer1','','hide')" onmouseover="MM_showHideLayers('Layer1','','show')"><img src="../images/gnavi01.gif" class="btn" /></a></li>
		<li><a href="../page2/index.html" onmouseout="MM_showHideLayers('Layer2','','hide')" onmouseover="MM_showHideLayers('Layer2','','show')"><img src="../images/gnavi02.gif" class="btn" /></a></li>
		<li><a href="../page3/index.html" onmouseout="MM_showHideLayers('Layer3','','hide')" onmouseover="MM_showHideLayers('Layer3','','show')"><img src="../images/gnavi03.gif" class="btn" /></a></li>
		<li><a href="../page4/index.html" onmouseout="MM_showHideLayers('Layer4','','hide')" onmouseover="MM_showHideLayers('Layer4','','show')"><img src="../images/gnavi04.gif" class="btn" /></a></li>
		<li><a href="../page5/index.html" onmouseout="MM_showHideLayers('Layer5','','hide')" onmouseover="MM_showHideLayers('Layer5','','show')"><img src="../images/gnavi05.gif" class="btn" /></a></li>
		</ul>
-->

<!-- 追加部分 -->
<Script Language="JavaScript">
<!--
var str;
str=escape(location.href);
var n = str.indexOf("page");
n = str.substr(n + 4, 1);

document.open();
document.write("<ul>");
if (n != '1') {document.write("<li><a href='index.html' onmouseout='MM_showHideLayers('Layer1','','hide')' onmouseover='MM_showHideLayers('Layer1','','show')'><img src='../images/gnavi01.gif' class='btn' /></a></li>");};
if (n != 2) {document.write("<li><a href='../page2/index.html' onmouseout='MM_showHideLayers('Layer2','','hide')' onmouseover='MM_showHideLayers('Layer1','','show')'><img src='../images/gnavi02.gif' class='btn' /></a></li>");};
if (n != 3) {document.write("<li><a href='../page3/index.html' onmouseout='MM_showHideLayers('Layer3','','hide')' onmouseover='MM_showHideLayers('Layer1','','show')'><img src='../images/gnavi03.gif' class='btn' /></a></li>");};
if (n != 4) {document.write("<li><a href='../page4/index.html' onmouseout='MM_showHideLayers('Layer4','','hide')' onmouseover='MM_showHideLayers('Layer1','','show')'><img src='../images/gnavi04.gif' class='btn' /></a></li>");};
if (n != 5) {document.write("<li><a href='../page5/index.html' onmouseout='MM_showHideLayers('Layer5','','hide')' onmouseover='MM_showHideLayers('Layer1','','show')'><img src='../images/gnavi05.gif' class='btn' /></a></li>");};
document.write("</ul>");
document.close();
//  -->
</Script>
<!-- 追加部分ここまで -->

    <p> </p>
id:yurina1023

ご回答ありがとうございます。

ご回答いただいた方法を試してみたのですが、page1ボタン自体が消えてしまいました。

説明が不十分で申し訳ないのですが、ドロップダウンメニューだけが出力されないようにしたいです。

あと、便宜上今はディレクトリ名をpage1,page2などとしていますが、実際にはそれぞれのディレクトリ名はgaiyouやinformationといった感じになります。

このナビゲーションを含めたヘッダー部は後にphpでインクルードしてどのページでも同じようにして使えるようにしたいと思っています。

説明が不十分で大変申し訳ありませんでした。

よろしくお願いします。

2009/10/16 15:57:28
id:Reiaru No.2

回答回数152ベストアンサー獲得回数38

ポイント50pt

申し訳ありません、完全に仕様を誤解しておりました。

これも効率的とは言えないかもしれませんが、取りあえず動くものを提示致します。


menu.js (場所はどこでも良いです。AAA.html などは適宜ファイル名を変更して下さい)

function setPageNo() {
  var str; var n;
  str = escape(location.href);
  str = str.split(/[\\\/]/).pop();
  switch (str) {
    case 'index.html':
      n = 1; break;
    case 'AAA.html':
      n = 2; break;
    case 'BBB.html':
      n = 3; break;
    case 'CCC.html':
      n = 4; break;
    case 'DDD.html':
      n = 5; break;
  }
  return n;
}

各 *.html

<body onload="initRollovers();"><div align="center">

<!-- 追加部分 -->
<Script Language="JavaScript">
<!--
n = setPageNo();
//  -->
</Script>
<!-- 追加部分ここまで -->

<h1>ページ1</h1>

各 *.html (以下は1のみですが、実際にはそれぞれのメニューの改変が必要です。" が ' になっていたりするので気をつけて下さい)

<!--メニュー1-->
<div style="position:relative; z-index:2;">
<div id="Layer1">
<table cellspacing="0" width="168">
<tr>

<!-- コメントアウト -->
<!--
<td onMouseOut="MM_swapImgRestore();MM_showHideLayers('Layer1','','hide'); hideMenu('Layer1')" onMouseOver="MM_showHideLayers('Layer1','','show'); showMenu('Layer1')">
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
<a href="#" class="puldown"> sample</a>
//-->
<!-- コメントアウトここまで -->

<!-- 追加部分 -->
<Script Language="JavaScript">
<!--
document.open();
if (n != 1) {document.write(
"<td onMouseOut='MM_swapImgRestore();MM_showHideLayers('Layer1','','hide'); hideMenu('Layer1')' onMouseOver='MM_showHideLayers('Layer1','','show'); showMenu('Layer1')'>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>" +
"<a href='#' class='puldown'> sample</a>"
)};
document.close();
//  -->
</Script>
<!-- 追加部分ここまで -->

</td></tr></table>
</div>
</div>
<!--//メニュー1-->

関係ありませんが、プログラム関係の質問をされるときはコメント欄を空けておいて頂けると助かります。

不明な点があったり、後から間違いに気が付いたりする事もありますので…。

id:yurina1023

ご回答ありがとうございます。

この方法でできました。

ただ、本サイトに入れる時にどの部分をディレクトリ名(/gaiyou/や/information/みたいな)に変更したら良いのかがわからなかったのです。

case 'index.html':

↑menu.jsのこの部分でしょうか?ここはファイル名を入れるということで、ディレクトリ名ではないということでしょうか?

申し訳ありませんが、この点だけ今一度ご回答いただけると嬉しいです。

2009/10/17 15:11:39
id:Cherenkov No.3

回答回数1504ベストアンサー獲得回数493ここでベストアンサー

ポイント50pt

こういう質問はコメント欄を有効にしましょう。

一番簡単なのは、http://flatone.s206.xrea.com/page1/index.htmlのhtmlの

表示したくないプルダウンメニューのMM_showHideLayers('Layer1','','show')を

MM_showHideLayers('Layer1','','hide')に書き換えるのが早いけど、

動的に変えるならこうですかね。

(ちゃんと関数つくってあったんですね。引数の扱いが読み辛いので分かってきたら直したほうがいいかと思います。)

以下のコードをmenu.jsに追加するか、scriptタグで囲んでpage1/index.htmlに貼るか。

if(/\/page1\//.test(location.href)) {
  var a = document.getElementsByTagName('a');
  for(var i=0; i<a.length; i++) {
    if(/Layer1/.test(a[i].onmouseover)){
      a[i].onmouseover = "MM_showHideLayers('Layer1','','hide')";
    }
  }
}

説明

正規表現のtestメソッドでアドレスに/page1/が含まれるか判定。

表示したくないプルダウンを指定するためにdocument.getElementsByTagNameを使ってすべてのaタグを抽出。

すべてのaタグのなかから再びtestメソッドを使ってLayer1を含むものを洗い出す。

マッチしたらonmouseoverを上書き。



プルダウンメニューにid属性(Layer1)を付けてやれば効率があがります。

if(/\/page1\//.test(location.href)) {
  var hide = document.getElementById('Layer1');
  hide.onmouseover = "MM_showHideLayers('Layer1','','hide')";
}

とか。

id:yurina1023

ご回答ありがとうございます。

この方法は簡単に実現できて大変良かったのですが、なぜかいつもページを開いて1回目にメニューボタンにマウスオーバーした時はドロップダウンメニューが表示されてしまいます。

2回目以降のマウスオーバー時には表示されないのですが。

この問題の解決法を今一度ご教授願えればと思います。

よろしくお願いします。

2009/10/17 15:16:04
  • id:Reiaru
    Cherenkov 様の回答が素晴らしいと思います。
    ただ、正規表現などの具体的なソースは示されていない為、その辺りは yurina1023 様自身で行って頂くしかありませんが、
    プログラム手法としては非常に正しいものだと私は思います。

    私が提示した例は「取りあえず動けば良い」レベルのものでしかなく、
    メンテナンス性などを考えますとやはり非効率であると言わざるを得ませんので。
  • id:Cherenkov
    その1回目表示されちゃうページもアップしてもらえるのが一番いいのですが。
    回答で提示したコードをどこに追加したのでしょうか、経験が浅いので下手な推測になってしまい先へ進めません。
  • id:yurina1023
    コメントありがとうございます。

    現在、http://flatone.s206.xrea.com/page1/index.htmlにCherenkovさんからご提示いただいた方法を適用してみました。

    入れた場所は、function MM_showHideLayers()の、

    var i,p,v,obj,args=MM_showHideLayers.arguments;

    for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];

    の間です。

    これはやはり私の入れている箇所が悪いということでしょうか?

    よろしくお願いします。
  • id:Reiaru
    function setPageNo() {
     var str; var n;
     str = location.href;
     switch (str) {
      case 'http://flatone.s206.xrea.com/page1/gaiyou/index.html':
       n = 1; break;
      case 'http://flatone.s206.xrea.com/page1/infomation/index.html':
       n = 2; break;

       //(以下続く)
     }
     return n;
    }

    ファイル名の切り出しとかやめて、いっそこんなでもいいです~。
  • id:Cherenkov
    コードを追加している箇所が悪いです。
    今のonmouseoverで関数を実行する形であれば、
    追加したコードを消して、
    <a onmouseover="MM_showHideLayers('Layer1','','show')"

    <a onmouseover="MM_showHideLayers('Layer1','','hide')"
    にするだけでいいのではないでしょうか。
  • id:Cherenkov
    >このナビゲーションを含めたヘッダー部は後にphpでインクルードしてどのページでも同じようにして使えるようにしたいと思っています。

    php触ったことがないのでわからないんですけど、プルダウンメニューはどのページでも同じものを表示させたいということなんですかね?
    だとしたら上のコメントの方法では違ってくるし。


    ではこうしてみてください。
    <a onmouseover="if(/\/page1\//.test(location.href)){MM_showHideLayers('Layer1','','hide')}else{MM_showHideLayers('Layer1','','show')}"
  • id:Cherenkov
    説明が足りませんでした。
    追加したコードは消してプルダウンメニューのonmouseoverの中を書き換える です。


    んー、ちょっとこんがらがってきました。
    コメントいただければ納得するまでお付き合いしますのでよろしくおねがいします。
  • id:yurina1023
    Cherenkovさん、本当にありがとうございます。


    menu.jsの中に追加したコードを削除して、
    htmlのほうの

    <td onMouseOut="MM_swapImgRestore();MM_showHideLayers('Layer1','','hide'); hideMenu('Layer1')" onMouseOver="MM_showHideLayers('Layer1','','show'); showMenu('Layer1')">

    ここを書き換えるということで良いのでしょうか?

    熱心に教えていただいているのに、初歩的な質問で申し訳ありません・・・。
  • id:yurina1023
    さしでがましいのですが、この例で使用しているファイルをまとめたzipを用意しました。

    http://flatone.s206.xrea.com/web.zip

    一番最初の何も追加していない状態です。
    本当に申し訳ないのですが、よろしくお願いします。
  • id:Cherenkov
    いいえ
    <td onMouseOut=~
    ではなく、もうちょっと下にあるulタグで囲まれた部分です。
    \web\page1\index.htmlの125行目。を以下のように。onmouseoutとonmouseoverを間違えないように。

    <li><a href="index.html" onmouseout="MM_showHideLayers('Layer1','','hide')" onmouseover="if(/\/page1\//.test(location.href)){MM_showHideLayers('Layer1','','hide')}else{MM_showHideLayers('Layer1','','show')}"><img src="../images/gnavi01.gif" class="btn" /></a></li>
  • id:Reiaru
    http://www1.axfc.net/uploader/Sc/so/46577
  • id:Cherenkov
    動作します?
  • id:yurina1023
    Cherenkovさんありがとうございます。
    ご教授いただいた方法を試してみたところ、望みどおりの結果を得ることができました。
    TOPページやpage1の下層ディレクトリでの動作も問題ありませんでした。

    あとは、

    <li><a href="index.html" onmouseout="MM_showHideLayers('Layer1','','hide')" onmouseover="if(/\/page1\//.test(location.href)){MM_showHideLayers('Layer1','','hide')}else{MM_showHideLayers('Layer1','','show')}"><img src="../images/gnavi01.gif" class="btn" /></a></li>

    ↑の、/\/page1\//の部分を対応する、"gaiyou"や"information"などといったディレクトリ名に直してやってそれを全ボタン分繰り返せば良いということですよね?


    Reiaruさん、zipまで用意して頂いて本当にありがとうございました。
    後学の為に参考にさせていただきたいと思います。
    ありがとうございます。

    お二人には本当にこんな初心者相手にお付き合いいただいて申し訳ありませんでした。
    望みどおりの結果が得られて本当にうれしく思っています。

    ありがとうございました。
  • id:Cherenkov
    >全ボタン分繰り返せば良いということですよね?
    いいと思います。
    やっているうちにアレ?と思ったらFirefoxとアドオンのFirebugを使って値を変えてみるといいですよ。
    簡単に試行錯誤することができます。
    任務完了できてよかった♪
  • id:Reiaru
    動作はする筈です。ローカルでも試しましたし、自サーバーにも上げて確認しました。
    ただ、menu.js に記述したパスが間違っているかもしれませんー。

    単に、動かないものを提示したまま放置する様な事はしませんよーという意思を示したかったかっただけです。
    Cherenkov 様のコードが適切なのは間違いありません。そちらを使って下さい~(^-^)
    解決されたようで何よりですっ。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません