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

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

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

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

775閲覧

クリックイベントによる、要素の表示/非表示切り替え

darekatasukete

総合スコア2

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2022/12/06 05:03

前提

JavaScriptの練習の一環でとあるサイトの模写を行っているのですが、
行き詰ってしまったのでお知恵を拝借させていただきたいです。

スタートメニューの表示を作りたく、下記の機能を実装したいです。

①スタートメニューをクリックすると、ボタン各種が現れる。
②ボタンをクリックすると、ボタン自体のスタイルが切り替わるとともに、表示されるサブメニューの種類が切り替わる。
この時、ボタン2-Aとボタン2-Bはどちらもサブメニュー2を表示するボタンである。この2ボタン間で交互にクリックしても、サブメニューの表示は変わらない。
③デフォルト(スタートメニューをクリックした直後)は、ボタン2-Aが選択され、サブメニュー2が開いた状態である。
④選択状態にあるボタンをさらにクリックすると、ボタンのスタイルが元に戻るとともに、サブメニューの表示も消える。

実現したいこと

ボタン自体のスタイル切替はクリックイベントのクラス名toggleで実装したのですが、それに連動するサブメニューの表示切替のうまい方法が分からなくなってしまったので、ご教授いただきたいです。

該当のソースコード

html

1<!doctype html> 2<html> 3 <head> 4 <meta charset="utf-8"> 5 <title>renshu</title> 6 <link href="style.css" rel="stylesheet" type="text/css"> 7 </head> 8 9 <body id="body"> 10 <div class="start-menu-box"> 11 <div class="start-menu">スタートメニュー</div> 12 </div> 13 <div class="menu-box"> 14 <div class="btn-1-box"> 15 <div class="btn-1">ボタン1</div> 16 <div> 17 <div class="btn-1-submenu"> 18 <ul> 19 <li>サブメニュー1</li> 20 <li>サブメニュー1</li> 21 <li>サブメニュー1</li> 22 <li>サブメニュー1</li> 23 <li>サブメニュー1</li> 24 <li>サブメニュー1</li> 25 </ul> 26 </div> 27 </div> 28 29 </div><!--.btn-1--> 30 31 <div class="btn-2-box"> 32 <div class="btn-2-a">ボタン2-A</div> 33 <div class="btn-2-b">ボタン2-B</div> 34 35 <div> 36 <div class="btn-2-submenu"> 37 <ul> 38 <li>サブメニュー2</li> 39 <li>サブメニュー2</li> 40 <li>サブメニュー2</li> 41 <li>サブメニュー2</li> 42 <li>サブメニュー2</li> 43 <li>サブメニュー2</li> 44 </ul> 45 </div> 46 </div> 47 48 </div><!--.btn-2-box--> 49 50 <div class="btn-3-box"> 51 <div class="btn-3">ボタン3</div> 52 <div> 53 <div class="btn-3-submenu"> 54 <ul> 55 <li>サブメニュー3</li> 56 <li>サブメニュー3</li> 57 <li>サブメニュー3</li> 58 <li>サブメニュー3</li> 59 <li>サブメニュー3</li> 60 <li>サブメニュー3</li> 61 </ul> 62 </div> 63 </div> 64 65 </div><!--.btn-3--> 66 </div> 67 <script src="script.js"></script> 68 </body> 69</html>

css

1@charset "utf-8"; 2/* CSS Document */ 3 4*{ 5 margin: 0; 6 padding:0; 7} 8 9div{ 10 box-sizing: border-box; 11} 12 13.start-menu-box{ 14 width: 800px; 15 height:600px; 16 margin:auto; 17 background-color: burlywood; 18 border-radius: 32px; 19 display: flex; 20 justify-content: center; 21 align-items: center; 22 cursor: pointer; 23 position: relative; 24 z-index:2; 25} 26 27.start-menu-box-opend{ 28 transform: translateY(-100%); 29 opacity: 0; 30} 31 32.menu-box{ 33 width:800px; 34 height:100px; 35 margin:auto; 36 margin-top: -600px; 37 position: relative; 38 display:grid; 39 grid-template-columns:1fr 1fr 1fr; 40} 41 42.btn-1{ 43 border-radius: 32px; 44 height: 100%; 45 border: solid 1px #333; 46 background-color: blue; 47 text-align: center; 48 cursor: pointer; 49} 50 51.btn-2-box{ 52 display:grid; 53 grid-template-columns:1fr 1fr 0; 54} 55 56.btn-2-a, 57.btn-2-b{ 58 background-color:aqua; 59 border: solid 1px #333; 60 border-radius: 32px; 61 text-align: center; 62 cursor: pointer; 63} 64 65.btn-3{ 66 border-radius: 32px; 67 height: 100%; 68 border: solid 1px #333; 69 background-color:cornflowerblue; 70 text-align: center; 71 cursor: pointer; 72} 73 74.btn-1-submenu, 75.btn-2-submenu, 76.btn-3-submenu{ 77 width: 80%; 78 height:500px; 79 border-radius: 32px; 80 display: flex; 81 align-items: center; 82 justify-content: center; 83} 84 85.btn-1-submenu{ 86 background-color: blue; 87 position: absolute; 88 top:100%; 89 opacity: 0; 90 pointer-events: none; 91} 92 93.btn-2-submenu{ 94 background-color:aqua; 95 position: absolute; 96 top:100%; 97 left:0; 98 right:0; 99 opacity: 0; 100 pointer-events: none; 101} 102 103.btn-3-submenu{ 104 background-color:cornflowerblue; 105 position: absolute; 106 top:100%; 107 left:0; 108 opacity: 0; 109 pointer-events: none; 110} 111 112ul{ 113 list-style: none; 114} 115 116.btn-selected{ 117 background-color: #ccc; 118 border: solid 5px #ff0; 119} 120 121.submenu-selected{ 122 opacity: 1; 123 pointer-events: initial; 124} 125

JavaScript

1//スタートメニューの取得 2const btnStartMenu = document.querySelector(".start-menu-box"); 3 4const menuBoxOpen = function(){ 5 btnStartMenu.addEventListener("click", function(){ 6 btnStartMenu.classList.add('start-menu-box-opend'); 7 }); 8}; 9 10menuBoxOpen(); 11 12 13 14//ボタン各種、サブメニューの各種の取得 15const btn_1 = document.querySelector(".btn-1"); 16const btn_2_A = document.querySelector(".btn-2-a"); 17const btn_2_B = document.querySelector(".btn-2-b"); 18const btn_3 = document.querySelector(".btn-3"); 19const submenu_1 = document.querySelector(".btn-1-submenu"); 20const submenu_2 = document.querySelector(".btn-2-submenu"); 21const submenu_3 = document.querySelector(".btn-3-submenu"); 22 23 24//デフォルトはボタン1選択状態 25btn_2_A.classList.add('btn-selected'); 26submenu_2.classList.add('submenu-selected'); 27 28 29 30const menuBtnSelect = function(){ 31 btn_1.addEventListener("click", function(){ 32 btn_1.classList.toggle('btn-selected'); 33 submenu_1.classList.add('submenu-selected'); 34 if(btn_2_A.classList.contains('btn-selected')){ 35 btn_2_A.classList.remove('btn-selected'); 36 } 37 if(btn_2_B.classList.contains('btn-selected')){ 38 btn_2_B.classList.remove('btn-selected'); 39 } 40 if(btn_3.classList.contains('btn-selected')){ 41 btn_3.classList.remove('btn-selected'); 42 } 43 if(submenu_2.classList.contains('submenu-selected')){ 44 submenu_2.classList.remove('submenu-selected'); 45 } 46 if(submenu_3.classList.contains('submenu-selected')){ 47 submenu_3.classList.remove('submenu-selected'); 48 } 49 }); 50 51 btn_2_A.addEventListener("click", function(){ 52 btn_2_A.classList.toggle('btn-selected'); 53 submenu_2.classList.add('submenu-selected'); 54 if(btn_1.classList.contains('btn-selected')){ 55 btn_1.classList.remove('btn-selected'); 56 } 57 if(btn_2_B.classList.contains('btn-selected')){ 58 btn_2_B.classList.remove('btn-selected'); 59 } 60 if(btn_3.classList.contains('btn-selected')){ 61 btn_3.classList.remove('btn-selected'); 62 } 63 if(submenu_1.classList.contains('submenu-selected')){ 64 submenu_1.classList.remove('submenu-selected'); 65 } 66 if(submenu_3.classList.contains('submenu-selected')){ 67 submenu_3.classList.remove('submenu-selected'); 68 } 69 }); 70 71 btn_2_B.addEventListener("click", function(){ 72 btn_2_B.classList.toggle('btn-selected'); 73 submenu_2.classList.add('submenu-selected'); 74 if(btn_1.classList.contains('btn-selected')){ 75 btn_1.classList.remove('btn-selected'); 76 } 77 if(btn_2_A.classList.contains('btn-selected')){ 78 btn_2_A.classList.remove('btn-selected'); 79 } 80 if(btn_3.classList.contains('btn-selected')){ 81 btn_3.classList.remove('btn-selected'); 82 } 83 if(submenu_1.classList.contains('submenu-selected')){ 84 submenu_1.classList.remove('submenu-selected'); 85 } 86 if(submenu_3.classList.contains('submenu-selected')){ 87 submenu_3.classList.remove('submenu-selected'); 88 } 89 }); 90 91 btn_3.addEventListener("click", function(){ 92 btn_3.classList.toggle('btn-selected'); 93 submenu_3.classList.add('submenu-selected'); 94 if(btn_1.classList.contains('btn-selected')){ 95 btn_1.classList.remove('btn-selected'); 96 } 97 if(btn_2_A.classList.contains('btn-selected')){ 98 btn_2_A.classList.remove('btn-selected'); 99 } 100 if(btn_2_B.classList.contains('btn-selected')){ 101 btn_2_B.classList.remove('btn-selected'); 102 } 103 if(submenu_1.classList.contains('submenu-selected')){ 104 submenu_1.classList.remove('submenu-selected'); 105 } 106 if(submenu_2.classList.contains('submenu-selected')){ 107 submenu_2.classList.remove('submenu-selected'); 108 } 109 }); 110 111}; 112 113menuBtnSelect();

試したこと

現状のコードではボタンの切り替えとともにサブメニューの表示が移動するのみで、ボタン再クリックによってサブメニューを非表示にする機能が実装できていない状態です。

サブメニューの表示非表示切り替えの仕組みをclassList.toggleにするなど試してみたのですが、ボタン2-A,2-B間の表示条件やデフォルトの選択状態などが絡んでうまく出来ず、、

何卒よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

本題とは関係ありませんが、opend ではなく opened です。


まず、コードが少し冗長になっているので、classの切り替え処理を工夫しましょう。

「クリックしたボタンにclassを付ける→他のボタンのclassを外す」ではなく、「一旦すべてのボタンのclassを外す→クリックしたボタンにclassを付ける」とすると、最初の処理を関数にまとめることでコードを短くできます。

js

1//一旦すべてのボタン・サブメニューのclassを外す 2const removeSelect = function () { 3 btn_1.classList.remove("btn-selected"); 4 submenu_1.classList.remove("submenu-selected"); 5 btn_2_A.classList.remove("btn-selected"); 6 btn_2_B.classList.remove("btn-selected"); 7 submenu_2.classList.remove("submenu-selected"); 8 btn_3.classList.remove("btn-selected"); 9 submenu_3.classList.remove("submenu-selected"); 10};

そして、各ボタンを押したときは、押したボタンが既に選択されているかどうかで条件分岐させましょう。

  • 既に選択されているなら、removeSelect()を実行
  • 選択されていないなら、removeSelect()を実行した上で押したボタン及び対応するサブメニューにclassを追加

これで、サブメニューを切り替える・閉じる処理ができます。

js

1const menuBtnSelect = function () { 2 btn_1.addEventListener("click", function () { 3 let selected = btn_1.classList.contains("btn-selected"); 4 removeSelect(); 5 //選択されていなかったらclassを追加 6 if (!selected) { 7 btn_1.classList.add("btn-selected"); 8 submenu_1.classList.add("submenu-selected"); 9 } 10 }); 11 12 //...(他のボタンも同様) 13};

投稿2022/12/06 08:03

編集2022/12/06 08:07
luuguas

総合スコア490

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

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

darekatasukete

2022/12/07 03:16

ありがとうございます!いただいたコードを使って実装できました! 大変勉強になりました、丁寧に教えていただき感謝です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問