質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

メニュー

メニューは、UIにおける仕組みであり、ユーザに機能の表示と実行する手段を与えます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

2回答

767閲覧

javascript tabメニュー

koko122102

総合スコア39

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

メニュー

メニューは、UIにおける仕組みであり、ユーザに機能の表示と実行する手段を与えます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2021/12/18 14:27

表題の通りjavascriptでtabメニューを作ってみました。自分でほとんど調べることなく作ったのですが、修正するべきところ、もっと効率的な書き方があればご教授いただきたいです。
自分の能力では、これが悪い書き方なのか分からず困っています。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <link rel="stylesheet" href="style.css"> 8 <link rel="stylesheet" href="reset.css"> 9 <title>Document</title> 10</head> 11<body> 12 13 <div class="container"> 14 <nav class="nav"> 15 <ul class="nav-list"> 16 <li class="nav-items active">Tab1</li> 17 <li class="nav-items">Tab2</li> 18 <li class="nav-items">Tab3</li> 19 <li class="nav-items">Tab4</li> 20 </ul> 21 </nav> 22 <div class="content active">tab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容です</div> 23 <div class="content">tab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容です</div> 24 <div class="content">tab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容です</div> 25 <div class="content">tab3の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容です</d4v> 26 </div> 27 28 29 30 31 <script src="main.js"></script> 32</body> 33</html>

scss

1 2.container{ 3 width: 500px; 4 margin: 300px auto; 5} 6 7.nav{ 8 9 &-list{ 10 display: flex; 11 12 } 13 14 15 &-items{ 16 background-color: gray; 17 color:white; 18 border-radius: 5px 5px 0px 0px; 19 padding: 5px; 20 cursor: pointer; 21 &:nth-of-type(n+2){ 22 margin-left: 5px; 23 } 24 25 &.active{ 26 background-color: rgb(36, 35, 35); 27 } 28 } 29 30} 31 32.content{ 33 display: none; 34 border: 1px solid #000; 35 text-align: center; 36 padding: 10px; 37 38 &.active{ 39 display: block; 40 41 } 42}

js

1 2document.addEventListener('DOMContentLoaded',function(){ 3 4 let navBtn = document.querySelectorAll('.nav-items') 5 navBtn.forEach(btn =>{ 6 btn.addEventListener('click', event => btnChange(event,navBtn)) 7 }) 8 9}) 10 11function btnChange(event,btn){ 12 btn.forEach(Btn =>{ 13 Btn.classList.remove('active'); 14 }) 15 let nowBtn = event.target; 16 nowBtn.classList.add('active'); 17 btn = [...btn]; 18 contentAppear(btn,nowBtn); 19} 20 21function contentAppear(btn,nowBtn){ 22 let contents = document.querySelectorAll('.content'); 23 contents = [...contents]; 24 contents.forEach(content =>{ 25 content.classList.remove('active'); 26 }); 27 28 const activeNumber = btn.indexOf(nowBtn); 29 contents[activeNumber].classList.add('active'); 30 31 32 33}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自分でほとんど調べることなく作った

素晴らしいと思いますよ

修正するべきところ、もっと効率的な書き方

ということなので、一言では終わりません。

  1. DOMContentLoaded のイベントを使わずとも </body>タグの直前にスクリプトを埋め込めばよい。
  2. navBtn の個々にイベントを張り付けず、 document で監視すれば1つで済む。

  しかも、document でイベントを監視するのであれば、DOMContentLoaded を待たずして head要素の中のscript 要素の中で張り付けられる。
3. btn.forEach(Btn =>{Btn.classList.remove('active');}) アクティブになっている要素は1つなのだから無駄。
4. navBtn = document.querySelectorAll('.nav-items') 最初から配列にしておけば?
というか 関数 btnChange、contentAppear に btn を引き連れて呼び出すくらいなら、グローバル変数にでも入れておけばよい
5. let contents = document.querySelectorAll('.content');も最初から配列に
6. document.querySelectorAll('.active').forEach (e=> e.classList.remove ('active'));
btn と content の2つを集めて一気に行う

  1. css で .content:not(.active){ display: none;} とすると1行で便利ですよ

こういうのを作っていて感じたと思いますが、この手のモノはボタン群とコンテンツ群の対となっています
もしオブジェクト指向的な作り方をするのであれば、設計図は共通化させられると思います

table 要素の中の th群と と tbody群を対にでも可能です
(寝ぼけているかもしれないのでこれにて)

html&Javascript

1<!DOCTYPE html> 2<meta charset="UTF-8"> 3<title></title> 4<style> 5 6.container{ 7 width: 500px; 8 margin: 300px auto; 9} 10 11.nav-list { 12 display: flex; 13 list-style: none; 14} 15 16 17.nav-items { 18 background-color: gray; 19 color:white; 20 border-radius: 5px 5px 0px 0px; 21 padding: 5px; 22 cursor: pointer; 23 margin-right: 5px; 24 25} 26 27.nav-items.active{ 28 background-color: rgb(36, 35, 35); 29} 30 31 32.content{ 33 border: 1px solid #000; 34 text-align: center; 35 padding: 10px; 36} 37 38.content:not(.active){ 39 display: none; 40} 41</style> 42<body> 43<div class="container"> 44 <nav class="nav"> 45 <ul class="nav-list"> 46 <li class="nav-items active">Tab1</li> 47 <li class="nav-items">Tab2</li> 48 <li class="nav-items">Tab3</li> 49 <li class="nav-items">Tab4</li> 50 </ul> 51 </nav> 52 <div class="content active">tab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容です</div> 53 <div class="content">tab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容です</div> 54 <div class="content">tab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容です</div> 55 <div class="content">tab3の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容です</div> 56</div> 57<hr> 58 59<table border="1"> 60 <thead><tr><th class="nav-items active">Tbody1<th class="nav-items">Tbody2<th class="nav-items">Tbody3 61 <tbody class="content active"><tr><td>1<td>2<td>3 62 <tbody class="content"><tr><td>A<td>B<td>C 63 <tbody class="content"><tr><td><td><td>64</table> 65 66 67<script> 68 69class TabMenu { 70 constructor ([...btn], [...content]) { 71 this.btn = btn; 72 this.content = content; 73 this.idx = btn.reduce ((r, e, i)=> e.classList.contains ('active') ? i: r, null); 74 75 document.addEventListener ('click', this, false); 76 } 77 78 79 isButton (btn) { 80 return this.btn.includes (btn); 81 } 82 83 84 handleEvent (event) { 85 let e = event.target; 86 if (this.isButton (e)) 87 this.active = e; 88 } 89 90 91 set active (e) { 92 let 93 {btn, content, idx} = this, 94 i = btn.indexOf (e); 95 96 if (-1 < i) { 97 [btn[idx], content[idx]].forEach (e=> e.classList.remove ('active')); 98 [e, content[i]].forEach (e=> e.classList.add ('active')); 99 this.idx = i; 100 } 101 } 102} 103//________________ 104 105new TabMenu ( 106 document.querySelectorAll ('.container li.nav-items'), 107 document.querySelectorAll ('.container div.content'), 108); 109 110new TabMenu ( 111 document.querySelectorAll ('table .nav-items'), 112 document.querySelectorAll ('table .content'), 113); 114 115</script> 116 117 118

投稿2021/12/18 16:57

編集2021/12/18 17:07
babu_babu_baboo

総合スコア616

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

タブメニューの場合排他的な処理なのでラジオボタンとcssだけでもいけます

CSS

1<style> 2[name=tab]{display:none;} 3.nav-list{ 4display:flex; 5list-style:none; 6margin:0; 7padding:0; 8} 9#t1:checked ~ * [for=t1], 10#t2:checked ~ * [for=t2], 11#t3:checked ~ * [for=t3], 12#t4:checked ~ * [for=t4] 13{color:red;} 14#t1:checked ~ * :not([data-target=t1]).content, 15#t2:checked ~ * :not([data-target=t2]).content, 16#t3:checked ~ * :not([data-target=t3]).content, 17#t4:checked ~ * :not([data-target=t4]).content 18{display:none;} 19</style> 20<input type="radio" name="tab" id="t1" checked> 21<input type="radio" name="tab" id="t2"> 22<input type="radio" name="tab" id="t3"> 23<input type="radio" name="tab" id="t4"> 24<div class="container"> 25<nav class="nav"> 26<ul class="nav-list"> 27<li class="nav-items"><label for="t1">Tab1</label></li> 28<li class="nav-items"><label for="t2">Tab2</label></li> 29<li class="nav-items"><label for="t3">Tab3</label></li> 30<li class="nav-items"><label for="t4">Tab4</label></li> 31</ul> 32</nav> 33<div class="content" data-target="t1">tab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容ですtab1の内容です</div> 34<div class="content" data-target="t2">tab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容ですtab2の内容です</div> 35<div class="content" data-target="t3">tab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容ですtab3の内容です</div> 36<div class="content" data-target="t4">tab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容ですtab4の内容です</d4v> 37</div>

投稿2021/12/20 03:23

yambejp

総合スコア114572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問