PageSourceSearch

https://komekaigi.dev/2025/js/main.js

js komekaigi.dev collected 2026-09-26 04:37:36 UTC 3,053 bytes, 86 lines download raw bytes

1/**
2 * KomeKaigi メイン JavaScript
3 * モバイルメニューや共通機能を管理
4 */
5(function(window, document) {
6    'use strict';
7
8    // アイコン定義
9    const ICONS = {
10        MENU_OPEN: '<svg class="w-6 h-6 text-primary fill-none stroke-current" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>',
11        MENU_CLOSE: '<svg class="w-6 h-6 text-primary fill-none stroke-current" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>'
12    };
13
14    /**
15     * モバイルメニューの初期化
16     */
17    function initializeMobileMenu() {
18        const mobileMenuButton = document.getElementById('mobile-menu-button');
19        const mobileMenu = document.getElementById('mobile-menu');
20        
21        if (!mobileMenuButton || !mobileMenu) {
22            return;
23        }
24
25        mobileMenuButton.addEventListener('click', () => {
26            toggleMobileMenu(mobileMenu, mobileMenuButton);
27        });
28
29        const menuLinks = mobileMenu.querySelectorAll('a');
30        menuLinks.forEach(link => {
31            link.addEventListener('click', () => {
32                closeMobileMenu(mobileMenu, mobileMenuButton);
33            });
34        });
35    }
36
37    /**
38     * モバイルメニューのトグル
39     * @param {HTMLElement} menu - メニュー要素
40     * @param {HTMLElement} button - メニューボタン要素
41     */
42    function toggleMobileMenu(menu, button) {
43        menu.classList.toggle('hidden');
44        
45        const isOpen = !menu.classList.contains('hidden');
46        updateMenuButtonIcon(button, isOpen);
47        updateMenuButtonAria(button, isOpen);
48    }
49
50    /**
51     * モバイルメニューを閉じる
52     * @param {HTMLElement} menu - メニュー要素
53     * @param {HTMLElement} button - メニューボタン要素
54     */
55    function closeMobileMenu(menu, button) {
56        menu.classList.add('hidden');
57        updateMenuButtonIcon(button, false);
58        updateMenuButtonAria(button, false);
59    }
60
61    /**
62     * メニューボタンのアイコンを更新
63     * @param {HTMLElement} button - メニューボタン要素
64     * @param {boolean} isOpen - メニューが開いているかどうか
65     */
66    function updateMenuButtonIcon(button, isOpen) {
67        button.innerHTML = isOpen ? ICONS.MENU_OPEN : ICONS.MENU_CLOSE;
68    }
69
70    /**
71     * メニューボタンのARIA属性を更新
72     * @param {HTMLElement} button - メニューボタン要素
73     * @param {boolean} isOpen - メニューが開いているかどうか
74     */
75    function updateMenuButtonAria(button, isOpen) {
76        button.setAttribute('aria-label', isOpen ? 'メニューを閉じる' : 'メニューを開く');
77        button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
78    }
79
80    // 初期化
81    document.addEventListener('DOMContentLoaded', function() {
82        initializeMobileMenu();
83    });
84
85})(window, document);
86

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.