こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

JavaScriptでアコーディオンメニューを作る

こちらでよくお世話になっています。
JavaScriptに詳しい方、どうか教えてください。
当方、まだまだJavaScriptは初心者です。

以下のようなHTMLがあって、
コンテンツ部分を普段は非表示で
タイトル部分をクリックしたら、
その下の表示・非表示が切り替わるようにしたいと考えています。
(アコーディオンの感じです。)
-------------------------

<div id="title1">タイトル1</div>
<table id="contents1">
 <tr><td>コンテンツ1</td></tr>
</table>

<div id="title2">タイトル2</div>
<table id="contents2">
 <tr><td>コンテンツ2</td></tr>
</table>

<div id="title3">タイトル3</div>
<table id="contents3">
 <tr><td>コンテンツ3</td></tr>
</table>


ちなみに、それぞれタイトルとコンテンツがセットになっていて、
titleのid名の末尾の番号と
そこをクリックしたら、開閉するtableのid名の末尾の番号を一致させています。

※このタイトルとコンテンツは動的に増えたり減ったりします。


プラグインを入れないで
自分でjavascriptを組みたいと考えているのですが
どのようにすればよいのか、分からず
こちらで質問をさせていただきました。

var divList = document.getElementsByTagName('div');
for(i=0; i<divList.length; i++){

}

のようにやっていくのだろうとは思うのですが
for文の中をどのように書いたらよいかを
ご教授いただけたら助かります。

どうぞ宜しくお願いいたします。

投稿日時 - 2012-11-12 15:47:24

QNo.7794111

すぐに回答ほしいです

質問者が選んだベストアンサー

構造が確定ということであれば敢えて文句をつけることはありません。
divとtableに相関関係がない以上、idをつかってひもづけるのが妥当ですね
かなり雑ですが、以下参考にしてください。
(本来であればクラス名の競合・排他処理など必要です)

<script>
window.onload=function(){
hideTable();
}
function hideTable(){
var tables=document.getElementsByTagName("table");
for(var i=0;i<tables.length;i++){
var t=tables[i];
var reg=new RegExp("^contents[0-9]+$");
if(reg.exec(t.id)){
t.className="hide";
}
}
}
try{
document.addEventListener ('click',function(e){clickfunc(e)},true);
}catch(e){
document.attachEvent('onclick',function(e){clickfunc(e)});
}
function clickfunc(e){
var t = (e.srcElement || e.target);
var reg=new RegExp("^title([0-9]+)$");
if(t.nodeName=="DIV" && (r=reg.exec(t.id))){
hideTable();
document.getElementById("contents"+r[1]).className="";
}
}


</script>
<style>
.hide{
display:none;
}
</style>
<div id="title1">タイトル1</div>
<table id="contents1">
<tr><td>コンテンツ1</td></tr>
</table>

<div id="title2">タイトル2</div>
<table id="contents2">
<tr><td>コンテンツ2</td></tr>
</table>

<div id="title3">タイトル3</div>
<table id="contents3">
<tr><td>コンテンツ3</td></tr>
</table>

投稿日時 - 2012-11-12 19:18:28

お礼

スクリプトまで書いていただきありがとうございます。

正規表現を使って、idの値を取得する方法があるんですね。
実は、スクリプトで分かっていない所もあるんですが
勉強して、読み解きたいと思います。

ですが、実は、書いていただいた方法で
期待通りに動かず、残念です。
他に何かしらの処理が必要なのか、
何か干渉しているのか…

ただ、書いていただいのを参考にしつつ
ちょっと別の方法で何とかできました。

大変参考になり、勉強させていただきました。
取り急ぎ御礼申し上げます。

投稿日時 - 2012-11-13 13:03:40

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

処理の中で同じ扱いをするものには個別のIDを付けて識別しない方がよろしいと思います。数が可変とのことなのでならなおさらでしょうか。
できれば全体をくくる要素に一箇所だけidを付けておいて、あとは必要に応じてclass設定を行なうか、あるいは、HTMLの構成さえうまく作ってあれば位置関係のみで判断可能になるのでclassも不要になりそうに思います。
その意味からも、ANo1様の提示なさっているマークアップの方が一般的かと。

とはいうものの、変更ができないようなので…
 >var divList = document.getElementsByTagName('div');
 >for(i=0; i<divList.length; i++){
ドキュメント内の全div要素を拾っていますので、まず、対象になるdivだけを絞り込んでおいたほうが賢明かと思います。
そういう意味からもラップ要素を特定できた方が賢明です。
そのままなら、idが「tile##」のdivを検出することになろうかと…
一方で、対象のidが「tilte##」、「contents##」ってのもあまりにもなので、スクリプトを作成してもそのままでは再利用もできないような気がします。


とはいうものの、あれこれ言うだけでは進まないでしょうから、

ライブラリを使わずに似たことを行なう解説をしているサイトがありました。
スクリプトの内容としては決してお薦めするものではありませんが、まったく手がつかないようですので手掛かりにでもなれば。
(クリックではなく、ホバーで動作するようになっています)
http://plusone.jpn.org/javascript/sample/acc/acomenu/acomenu.html

上にも書きましたが、このサンプルの方法に捕われずに、要素のidに頼らないで処理できる方法を、また、onclick属性をあちこちに書かずにすむ方法を考えてみることをお勧めします。

投稿日時 - 2012-11-12 19:47:38

お礼

設計する上でのポイントを教えていただき、
ありがとうございます。
それも大変、丁寧で分かりやすいです。

作り込む上で、どのように作っていくかが
まだまだ見通せず、スクリプトを書く前に
手がつかないのは、まさにそのとおりです。
それには、もっと、いろいろな場所で
書きこまなくてはダメですね。

大変、参考になりました。

ありがとうございました。

投稿日時 - 2012-11-13 13:12:51

ANo.1

>自分でjavascriptを組みたい

立派な心がけだとは思いますが、構造が雑。
tableを使うのは必須でしょうか?
普通はul,liやdl,dt,ddを使いますが・・・

投稿日時 - 2012-11-12 16:12:47

補足

ご指摘ありがとうございます。

ですが、残念ながら、tableを使うのは必須なのです。
動的に出来ているサイトで
中のHTMLの仕組みを変えられないというか、
今回は変えないでやらなければいけない理由がありまして
tableを使いたいと考えています。

投稿日時 - 2012-11-12 16:30:43

あなたにオススメの質問