JavaScriptでタブメニューを作成
解決済
回答 3
投稿
- 評価
- クリップ 0
- VIEW 2,426
前提・実現したいこと
JavaScriptでタブメニューを作成しているのですが、うまく連動させることができません。
数字1,2,3をクリックするとそれに対応するA,B,C以外にclassのhiddenをつけるようにし、対応するもののみ表示させるようにしています。
発生している問題・エラーメッセージ
index.html:47 Uncaught TypeError: Cannot read property 'classList' of undefined
該当のソースコード
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<title></title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="wrapper">
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul class="contents">
<li>A</li>
<li class="hidden">B</li>
<li class="hidden">C</li>
</ul>
</div>
</body>
</html>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
var nav = document.getElementsByClassName("nav"),
nav_menu = nav[0].children,
contents = document.getElementsByClassName("contents"),
con_menu = contents[0].children;
console.log(nav);
console.log(nav_menu);
console.log(contents);
console.log(con_menu);
for(var i = 0 ; i < nav_menu.length ; i++){
nav_menu[i].onclick = function(){
display(i);
}
}
function display(a){
for(var j = 0 ; con_menu.length ; j++){
con_menu[j].classList.add("hidden");
}
con_menu[a].classList.remove("hidden");
}
</script>
補足情報(言語/FW/ツール等のバージョンなど)
まだあまりJSに関して分かっていないので、分かりやすいアドバイスお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
エラー発生箇所以外にもおかしいところはありますが、とりあえずエラー箇所だけ……
display内のループが無限ループになっているため、con_menu[3]を参照しエラーになっています。
con_menu.lengthではなく、 j < con_menu.lengthでは?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
この部分 display(i);
を実行するタイミングですでに forループが終わっているため、 i
は nav_menu.length
の値と同じになっています。即時関数などを使うなど、書き方を変えなければ望む挙動にはならないと思います。
nav_menu[i].onclick = function(){
display(i);
}
【JavaScriptで即時関数を使う理由 - Qiita】
http://qiita.com/katsukii/items/cfe9fd968ba0db603b1e
【即時関数のメリットと主な用途|もっこりJavaScript|ANALOGIC(アナロジック)】
http://analogic.jp/immediate-function/
yusakauniさんの指摘されている箇所とここを直せば多分動きますよ。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
0
こんにちは。
こんなかんじですかね
li{
cursor: pointer;
}
.hidden{
display:none;
}
</s
for(var i = 0 ; i < nav_menu.length ; i++){
(function(arg){
nav_menu[i].addEventListener("click",function(){
display(arg);
});
})(i);
}
function display(a){
console.log(a);
for(var j = 0 ; j < con_menu.length ; j++){
con_menu[j].classList.add("hidden");
}
con_menu[a].classList.remove("hidden");
}
forでぶん回してる値を渡しても最後の値しか取れないので
クロージャーにしてわたすみたいな
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.37%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる