実現したいこと
htmlとjsでモバイル版ハンバーガーメニューを作成したい
htmlとcss,jsでサイトを制作しており、レスポンシブやスライド、メニュー制御にjsを使用している。
前提
サイト内htmlそれぞれに対して、【style.js】を経由して画面サイズ判定後【header.html】or【mobiheader.html】とcssを適用する形式でサイトを構築している。
レスポンシブ自体は正常に動作している。
chrome開発者ツールで手動操作を行った内容を統合して【mobimenu.js】を作製したが動作しない。
実現したい動作としては
①メニューボタンをクリック(タップ)すると親メニューが展開
②親メニューをクリックすると子メニューが展開
③メニュー範囲外をクリックするとすべて消える
を実現したいが、動作しない
開発者ツールでクリックイベント登録などをすれば動く
該当のソースコード
【mobimenu.js】
document.addEventListener("DOMContentLoaded", function () {
console.log("✅ DOMContentLoaded が発火しました!");
const menuButton = document.getElementById("menu-button"); const menuContainer = document.getElementById("menu-container"); if (!menuButton || !menuContainer) { console.error("❌ menu-button または menu-container が見つかりません!"); return; } // 大メニューの開閉 menuButton.addEventListener("click", function () { menuContainer.classList.toggle("open"); console.log("📂 menu-container のクラス一覧:", menuContainer.classList); }); // サブメニューの開閉 document.querySelectorAll(".menu-item.has-submenu > a").forEach(item => { item.addEventListener("click", function (event) { event.preventDefault(); event.stopPropagation(); this.parentElement.classList.toggle("open"); console.log("📂 submenu の親要素クラス一覧:", this.parentElement.classList); }); }); // メニュー外をクリックしたら閉じる document.addEventListener("click", function (event) { if (!menuContainer.contains(event.target) && event.target !== menuButton) { menuContainer.classList.remove("open"); document.querySelectorAll(".menu-item.has-submenu").forEach(item => { item.classList.remove("open"); }); console.log("❌ メニューを閉じました!"); } });
});
試したこと
コンソールログの確認や、networkタブの確認で、jsファイルが読み込まれていることは確認している。
① menu-button のイベントを強制リセット&再登録したら、親メニューは開閉するようになった
② 子メニューの click イベントを再登録し、開閉するか確認
③ メニュー外クリックで閉じる処理を再登録し、閉じるか確認
以上を確認してから上記のjsに書き換えたものの、リセットをかけるとまた動かなくなってしまった。
補足情報
使用したいmobiheader.htmlの構造
<script src="/js/mobimenu.js" defer> </script> </body> </html>alt="モバイルバナー"> </div> <button id="menu-button" class="menu-button">メニュー</button> <nav id="menu-container" class="menu-container"> <ul class="menu"> <li class="menu-item">ホーム</li> <li class="menu-item has-submenu"> 当社について <ul class="submenu"> <li><a href="gaiyou.html">概要</a></li> <li><a href="about">施設について</a></li> </ul> </li> <li class="menu-item has-submenu"> お知らせ <ul class="submenu"> <li><a href="notice1.html">お知らせ1</a></li> <li><a href="notice2.html">お知らせ2</a></li> </ul> </li> <li class="menu-item has-submenu"> アクセス <ul class="submenu"> <li><a href="map.html">周辺地図</a></li> <li><a href="ac2.html">交通機関</a></li> </ul> </li> </ul> </nav> </header> </div> </div> <script>
モバイル用のcss【mobistyle.css】
/* 全体のリセット */
- {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 画面幅に応じて、サイドバーを消す */
@media (max-width: 768px) {
.sidebar-left, .sidebar-right, .spacer {
display: none !important;
width: 0 !important;
position: absolute !important;
}
}
/* html と body の高さを100%に設定し、スクロールを防ぐ */
html, body {
height: 100%;
overflow-x: hidden;
display: flex;
flex-direction: column;
}
/* ボディの基本スタイル */
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
color: #333;
}
/* ヘッダー・フッターの初期設定 */
#header-container, #footer-container {
visibility: hidden;
width: 100%;
}
/* メインコンテンツのレイアウト */
.main-container {
flex: 1;
display: flex;
flex-direction: column;
}
.main-content {
flex-grow: 1;
width: 100%;
}
/* スライドショーのスタイル */
.slideshow-container {
position: relative;
width: 100%;
height: auto;
overflow: hidden;
}
.slides {
display: flex;
transition: transform 3s ease-in-out;
}
.slide {
flex: 0 0 100%;
width: 100%;
}
.slides img {
width: 100%;
height: auto;
object-fit: contain;
}
.overlay-image {
position: absolute;
top: 10%;
left: 0;
width: 80%;
pointer-events: none;
}
/* 重要告知ボックス */
.important-message {
background-color: yellow;
padding: 10px;
text-align: center;
font-weight: bold;
color: blue;
transition: opacity 0.3s ease-in-out;
}
.important-message:hover {
opacity: 0.5;
}
/* 最新情報セクション */
.news, .updates {
width: 90%;
margin: 20px auto;
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;
padding: 15px;
}
.news-header, .updates-header {
background-color: purple;
color: white;
padding: 10px;
font-size: 1.5em;
text-align: center;
}
.news-content, .updates-content {
background-color: #FFFACD;
color: black;
padding: 15px;
font-size: 1em;
line-height: 1.6;
}
.news-divider, .updates-divider {
width: 90%;
height: 2px;
background-color: red;
margin: 15px auto;
}
.new-label {
color: purple;
font-weight: bold;
}
/* フッターレイアウト */
#footer-container {
position: relative;
width: 100%;
background: #333;
color: white;
text-align: center;
padding: 20px 0;
}
.footer-links {
text-align: center;
margin-bottom: 20px;
}
.footer-links a {
margin: 0 15px;
text-decoration: none;
color: black;
}
.footer-box {
width: 90%;
background-color: yellow;
margin: 0 auto;
padding: 10px;
}
.footer-box p {
color: blue;
font-weight: bold;
}

回答1件
あなたの回答
tips
プレビュー