|
| 1 | +import Swup from 'swup'; |
| 2 | +import SwupHeadPlugin from '@swup/head-plugin'; |
| 3 | +import SwupScriptsPlugin from '@swup/scripts-plugin'; |
| 4 | + |
| 5 | +const swup = new Swup({ |
| 6 | + containers: ['#site-header', 'main'], |
| 7 | + plugins: [ |
| 8 | + new SwupHeadPlugin(), |
| 9 | + new SwupScriptsPlugin({ head: false, body: true, optin: true }) |
| 10 | + ] |
| 11 | +}); |
| 12 | + |
| 13 | +// テーマ切り替え(フェードアウト開始時にdata-theme変更 → CSS transitionが走る) |
| 14 | +swup.hooks.on('animation:out:start', (visit) => { |
| 15 | + document.body.dataset.theme = visit.to.url === '/' ? 'dark' : 'light'; |
| 16 | +}); |
| 17 | + |
| 18 | +// コンテンツ差し替え後、レイアウト完了を待ってからフェードイン開始 |
| 19 | +swup.hooks.before('animation:in:start', () => { |
| 20 | + return new Promise(resolve => { |
| 21 | + requestAnimationFrame(() => requestAnimationFrame(resolve)); |
| 22 | + }); |
| 23 | +}); |
| 24 | + |
| 25 | +// スクリプトcleanup(ページ離脱時にタイマー・リスナー除去) |
| 26 | +swup.hooks.on('visit:start', () => { |
| 27 | + if (window.__pageCleanup) { |
| 28 | + window.__pageCleanup(); |
| 29 | + window.__pageCleanup = null; |
| 30 | + } |
| 31 | +}); |
| 32 | + |
| 33 | +// モバイルメニュー(イベントデリゲーションで差し替え後も動作) |
| 34 | +document.addEventListener('click', (e) => { |
| 35 | + if (e.target.closest('#mobile-menu-button')) { |
| 36 | + const menu = document.getElementById('mobile-menu'); |
| 37 | + if (menu) menu.classList.toggle('hidden'); |
| 38 | + } |
| 39 | +}); |
0 commit comments