目次
原因
二重に DOMContentLoaded イベントが登録されていた。
重複する登録は、無効化されたり競合を引き起こす可能性がある。
DOMContentLoaded イベント
- HTMLの基本的なDOM(Document Object Model)構造が完全に解析された時点で発生。
- 画像やスタイルシートなどの外部リソースを待たずに早く発生。
$(function() {})
- jQueryの省略記法
- $(document).ready(function() {})の短縮版
- DOMContentLoadedのタイミングで実行される。
// jQueryの方法(省略記法)
$(function() {
console.log("jQuery: DOMがロードされました!");
});
// 純粋なJavaScriptの方法
document.addEventListener("DOMContentLoaded", function() {
console.log("JS: DOMがロードされました!");
});
$(function() {}) は jQuery が必要なので、もし jQuery を読み込んでいない場合は動作しない。
DOMContentLoaded はJavaScriptなので、どんな環境でも使える。
load イベント
- ページのすべてのコンテンツが読み込まれた後に発生。
- 画像や外部リソースの読み込みも完了してから実行したい時に使う。
サブメニューリンクのリンク遷移が無効化されていた。
親メニューをクリックすると、サブメニューが開閉する機能を実現するために、e.preventDefault()を使用。
このコードは「リンクをクリックしても通常の動作(リンク遷移)をキャンセル」するもの。
結果として、サブメニュー内のリンクもキャンセルされている状態になっていた。
解決方法
親メニューの開閉機能とサブメニュー内リンクの遷移を分けて処理すれば解決。
親メニューがクリックされたときだけ、サブメニューを開閉する動作を実装。
サブメニュー内のリンクは、親メニューの処理に影響を受けず、リンク先に正しく飛ぶようにした。
menuItems.forEach(menuItem => {
menuItem.addEventListener('click', function (e) {
const parentItem = menuItem.closest('li'); // 親の<li>要素を取得
const subMenu = parentItem.querySelector('.sub-menu'); // サブメニューを取得
// 親メニュークリック時の動作(サブメニュー開閉)
if (subMenu && e.target === menuItem) {
e.preventDefault(); // 親メニューのデフォルト動作を無効化
subMenu.classList.toggle('open'); // 開閉クラスを切り替え
}
});
});
// サブメニュー内リンクのクリック動作
document.querySelectorAll('.sub-menu a').forEach(subMenuLink => {
subMenuLink.addEventListener('click', function (e) {
e.stopPropagation(); // 親メニューに影響を防ぐ
// リンク動作はそのまま維持
});
});