dポイントプレゼントキャンペーン実施中!

ホームページに折りたたみ式のメニューを設置しようと思い以下の用件を満たすプログラムを検索しました。

「別のメニューをクリックすると閉じる折りたたみメニュー」

ホームページの縦幅を固定するレイアウトのためにメニューをすべて開いてしまうと固定幅に収まらないためです。

選択している一つ以外は閉じているという状態を維持するものです。

以下の案件を見つけました。
http://oshiete1.goo.ne.jp/qa1436588.html
この例にならって設置してみました。

IE7ではうまく動作しますが、Firefox3.0ではポインタが変化せずクリックもできません。

ソースは以下です。
------------------------------
<script language="JavaScript">
<!--
function doClick()
{
var strName;
var intNo;

myObj = window.event.srcElement;
if((myObj.id=="")||(myObj==null))return true;

/* 対象となるメニューを取得 */
strName = myObj.id + "_menu";
var thisMenu = document.all.item(strName);
if(thisMenu !=null)
if(thisMenu.style.display == "block")
{
/* 対象メニューが開いていたらそれを閉じるだけ */
thisMenu.style.display = "none";
}
else
{
/* 対象メニューを開く */
thisMenu.style.display="block";

intNo=1;
strName="cate" + intNo + "_menu";
while(document.all.item(strName)!=null)
{
/* 対象メニュー以外は閉じる */
if(thisMenu != document.all.item(strName))
document.all.item(strName).style.display="none";

intNo++;
strName="cate" + intNo + "_menu";
}
}
}

//-->
</script>
------------------------------

本文は
------------------------------
<body onclick="doClick()">
<ul>
<li><a id="cate1">カテゴリ</a>
<ul id="cate1_menu" style="display:none;">
<li><a href="index.html">menu1</a></li>
<li><a href="index.html">menu2</a></li>
</ul></li>
<li><a id="cate2">カテゴリ</a>
<ul id="cate2_menu" style="display:none;">
<li><a href="index.html">menu3</a></li>
<li><a href="index.html">menu4</a></li>
<li><a href="index.html">menu5</a></li>
</ul></li>
</ul>
</body>
------------------------------

です。いろいろ試してみましたが初心者のため不具合箇所が特定できません。。

ご教授願えませんでしょうか。

A 回答 (5件)

> IEでも片方を開いたときに片方が自動的には閉じず、


ごめんなさい、それは実装してなかったのでそうなると思います。
一応、修正したものを下に載せておきます。

> Firefoxでは全開状態で表示されてしまいます。
エラーがでてないですか?
ツール → エラーコンソールで確認してみてください。
>>2 もですが、コピペしてもエラーはでないと思いますが。
もし何か出ていたら教えてください。
Firefox1.0 ~ Firefox 3.0 で確認しましたが、こちらの環境では問題ないですね。

もしくは JavaScript が Off になっているか。

===========================================================
var treeView = {
opened : null,

doClick : function(evt) {
var t = (function(n){
return n ? n.nodeName == 'LI' ? n : arguments.callee(n.parentNode) : null;
})(evt.target || evt.srcElement);
var c = (function(n){
return n ? n.nodeName == 'UL' ? n : arguments.callee(n.nextSibling) : null;
})(t ? t.firstChild : null);

if(c){
if(c.style.display == 'block'){
c.style.display = 'none';
if(c == treeView.opened){
treeView.opened = null;
}
} else {
c.style.display = 'block';
treeView.opened && (treeView.opened.style.display = 'none');
treeView.opened = c;
}
}
}
}

document.write(
'\u003Cstyle type="text/css">'
+ '.treeView ul { display : none; }'
+ '.treeView li { cursor : pointer; }'
+ '\u003C/style>'
);
    • good
    • 0

<body>未だに解決が齎されずに留まっているのでしょうか?</body>

    • good
    • 0
この回答へのお礼

締め切っていませんでした。
申し訳ございません。

お礼日時:2011/03/23 01:12

>上のものをFirefoxにも使えるように書き直すとどうなるのか?


1. srcElement ⇒ target
2. event オブジェクトは、関数の第一引数で受け取るようにする。
3. document.all ⇒ document.getElementById など。
4. item メソッドの仕様が異なるので注意。例のようなことをする場合は namedItem を使うか、または省略します。

>>2
1. 誤解を与えてしまったかも知れないので、
type 属性にはデフォルト値はセットされないので、必須です。(style も)
2. onclick はバブルするので、親要素につけておけば十分です。
this を使おうとしてのことかもしれませんが、this(currentTarget)には色々ありまして、、。直につけてるから、いいか。
イベントについては
https://developer.mozilla.org/ja/DOM/element.add …
このへんとか。
3. className は複数のクラスをとりうるので、書き換えには気をつけてください。
4. (参考までに) スタイルの追加について、全ノードをめぐるのは最悪の手段にとっときたいので、他のとこでも、書きましたが insertRule など、便利なメソッドがあるので有効に活用しませう。
ただ、IE などサポートしてないことなどを考えると、document.write でいいかって感じです。

以下、雑なので参考までに。
==============================================================
[JavaScript]
//@cc_on
function doClick(evt) {
var t = (function(n) {
return n ? n.nodeName == 'LI' ? n : arguments.callee(n.parentNode) : null;
})(evt.target || evt.srcElement);
var c = (function(n) {
return n ? n.nodeName == 'UL' ? n : arguments.callee(n.nextSibling) : null;
})(t ? t.firstChild : null);

c && (c.style.display = (function(d) {
return d == 'none' ? 'block' : 'none';
})((function() {
if(c.style.display) {
return c.style.display;
}else {
var s = null;
/*@if(@_jscript_version > 5.5)
s = c.currentStyle;
/*@else@*/
if(document.implementation && document.implementation.hasFeature('CSS2', '2.0'))
s = document.defaultView.getComputedStyle(c, '');
/*@end@*/

return s ? s.display : '';
}
})()));
}

document.write(
'\u003Cstyle type="text/css">'
+ '.treeView ul { display:none; }'
+ '.treeView li { cursor:pointer; }'
+ '\u003C/style>'
);

[HTML]
<ul onclick="doClick(event);" class="treeView">
<li>cate1
<ul>
<li><div>cate1-1</div> <!-- ラベルは好きなように -->
<ul>
<li>menu1-1-1</li>
</ul>
</li>
<li><a href="index.html">menu1</a></li>
<li><a href="index.html">menu2</a></li>
</ul>
</li>
<li>cate2
<ul>
<li><a href="index.html">menu3</a></li>
<li><a href="index.html">menu4</a></li>
<li><a href="index.html">menu5</a></li>
</ul>
</li>
</ul>
    • good
    • 0
この回答へのお礼

何度もご返答ありがとうございます。

試してみましたが、IEでも片方を開いたときに片方が自動的には閉じず、Firefoxでは全開状態で表示されてしまいます。
何か当方の記述の仕方が悪いのでしょうか?。。。

ありがとうございます。

お礼日時:2009/04/01 21:46

こんな感じでどうでしょ?



<style>
.hide{
display:none;
}
</style>
<script>
window.onload=function(){
hideUL();
setDIV();
}
function hideUL(){
var menu=document.getElementById("menu");
var n=menu.getElementsByTagName("ul");
for(var i=0;i<n.length;i++){
n[i].className="hide";
}
}
function setDIV(){
var menu=document.getElementById("menu");
var n=menu.getElementsByTagName("div");
for(var i=0;i<n.length;i++){
n[i].onclick=clickDIV;
}
}
function clickDIV(){
var n=this.nextSibling;
while(n){
if(n.nodeName=="UL") break;
n=n.nextSibling;
}
var cn=n.className;
hideUL();
if(cn=="hide") n.className="";
}
</script>
<ul id="menu">
<li><div>カテゴリ</div>
<ul>
<li><a href="index.html">menu1</a></li>
<li><a href="index.html">menu2</a></li>
</ul></li>
<li><div>カテゴリ</div>
<ul>
<li><a href="index.html">menu3</a></li>
<li><a href="index.html">menu4</a></li>
<li><a href="index.html">menu5</a></li>
</ul></li>
</ul>
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
試してみましたが、やはりIEではきちんと動作しますが、Firefoxでは両方開いてしまします。
希望する状態にはなりませんでした。。

お礼日時:2009/04/01 21:42

1. language は非推奨属性なので、type を使うようにします。

type については、、、type="text/javascript" でいいと思います。
興味があるなら
http://www.rfc-editor.org/rfc/rfc4329.txt
とか、Microsoft のサポートページとか、覗いてみて下さい。
ちなみに language を記述する場合、JavaScript 以降を省略すると JavaScript1.0 と認識されます。分からない場合は書かないほうがましです。

2. window.event.srcElement これ(window.event, srcElement)は JScript(IE) の独自拡張と、それに追従した Opera がサポートするプロパティで、Firefox その他はサポートしていません。
ついでに、document.all, document.all.item も。

その他ブラウザでは、event オブジェクトは、イベントリスナ内でのみ有効です。

以降、参考までに
3. display:none; を指定した場合、スクリプトを無効にすると、メニューはまったく表示されなくなります。

4. 表示しきれないレイアウトに無理があるので、レイアウト自体を見直してはいかがでしょうか。非表示にしたところで、あまり効果はないかと思います。

5. display:none には、バグがあるので気をつけてください。
    • good
    • 0
この回答へのお礼

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

1.完全に当方の不勉強です。確認させていただきます。

2.のようですね。。。検索した構文を拝借しているだけの身分なのでFirefoxに対応すべく書き直すには勉強が必要なようです。

3.いろいろ検索している途中に気がつきました。Javaオフの場合ナビゲーションが機能しなくなるのは致命的ですね。ただ、いまや手段が目的となっている感があり今後のためにも、どうすればFirefoxでも実現できるかを知りたかったのです。

4.レイアウトを考え直して、固定BOXのほうではなくスクロールバーを表示させるBOXのほうで折りたたみを使うことにしました。アコーディオンJSを使うと上記要件(選択部分以外は閉じる)をみたすのと、Javaオフでも全開状態で表示されるようなのでそちらを使うことにしました。

ただ、上のものをFirefoxにも使えるように書き直すとどうなるのか?というの気になるところです。いろいろ検索しまくりましたが、本を買って体系的に勉強した方が良さそうですね。

お礼日時:2009/03/29 03:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!