PageSourceSearch

https://sanseito.jp/nppoj/wp-content/themes/wp_310/nav-config.js

js sanseito.jp collected 2026-10-02 05:01:43 UTC 30,739 bytes, 802 lines download raw bytes

1/**
2 * nav-config.js
3 * 参政党 グローバルナビ 一元管理ファイル
4 *
5 * ■ 使い方
6 *   WordPress (head.php) :
7 *     <div id="snav"></div> を設置し、このファイルを読み込む
8 *
9 *   はてなブログ ヘッダ :
10 *     <div id="snav"></div>
11 *   はてなブログ フッタ :
12 *     <script src="https://sanseito.jp/nppoj/wp-content/themes/wp_310/nav-config.js"></script>
13 *
14 * ■ リンクを追加・変更するときは NAV_DATA だけ編集する
15 */
16
17(function () {
18
19  /* ==========================================================
20     1. ベースURL
21     WP環境では head に <meta name="snav-base" content="..."> を
22     出力しておくと自動取得。なければ https://sanseito.jp にフォールバック。
23  ========================================================== */
24  var BASE = (function () {
25    var m = document.querySelector('meta[name="snav-base"]');
26    return m ? m.content.replace(/\/$/, '') : 'https://sanseito.jp';
27  })();
28
29  /* ==========================================================
30     2. ナビデータ定義
31     - key      : メガメニューのクラス名 (mega_xxx) に対応
32     - label    : 表示ラベル
33     - href     : トップリンク。null のときは # になりドロップダウンのみ
34     - groups   : PC メガメニュー・SP アコーディオンの列グループ
35                  各 group は items の配列
36     - items    の各要素:
37         label   : 表示テキスト (HTML可。spanなど)
38         href    : リンク先。BASE で始まる場合は BASE + パス で書く
39         dot     : true のとき .dot クラスを付与(字下げリンク)
40         ext     : true のとき target="_blank" rel="noopener noreferrer"
41         labelEl : label の代わりに生のHTML文字列を渡したいとき
42         skip    : true のとき .skip クラスを付与
43         isSpan  : true のとき <a> ではなく <span>(ラベル見出し用)
44         wide    : true のとき ul に .wide クラスを付与(グループ単位)
45  ========================================================== */
46  var NAV_DATA = [
47    {
48      key: 'mega_about',
49      label: '私たち…',
50      href: null,
51      groups: [
52        {
53          items: [
54            { label: '参政党ってどんな党?', href: BASE + '/why_sanseito' },
55            { label: '参政党はこんな政党です。',       href: BASE + '/why_sanseito/#this_is',  dot: true },
56            { label: '参政党はこんな国を目指しています。', href: BASE + '/why_sanseito/#we_aim_for', dot: true },
57            { label: '参政党ではこんな人たちががんばっています。', href: BASE + '/why_sanseito/#our_info', dot: true },
58          ]
59        },
60        {
61          items: [
62            { label: '参政党について',   href: BASE + '/about' },
63            { label: '理念 綱領',       href: BASE + '/about/#philosophy', dot: true },
64            { label: '規約',             href: BASE + '/about/#terms',      dot: true },
65            { label: '広報物',           href: BASE + '/bulletin/',         dot: true },
66            { label: 'ボードメンバー',   href: BASE + '/about/#board',      dot: true },
67          ]
68        },
69        {
70          items: [
71            { label: '組織', isSpan: true },
72            { label: '県連合会', href: BASE + '/2020/community', dot: true },
73            { label: '支部',     href: BASE + '/2020/community', dot: true },
74          ]
75        },
76        {
77          items: [
78            { label: '橙鳳会( 継続寄付 )', href: BASE + '/2020/continuous_donation/' },
79            { label: 'ご寄付',             href: 'https://congrant.com/project/sanseito/6104', ext: true },
80            { label: 'チャーリー・カーク氏へ', href: BASE + '/in_memory_of_charlie_kirk/' },
81            { label: 'よくある質問',       href: BASE + '/before-contact/' },
82          ]
83        },
84      ]
85    },
86    {
87      key: 'mega_member',
88      label: 'メンバー',
89      href: BASE + '/member',
90      groups: [
91        {
92          items: [
93            { label: 'メンバー',       href: BASE + '/member' },
94            { label: 'ボードメンバー', href: BASE + '/member/#board', dot: true },
95          ]
96        },
97        {
98          items: [
99            { label: '衆議院議員',       href: BASE + '/member/#hor', dot: true },
100            { label: '参議院議員',       href: BASE + '/member/#hoc', dot: true },
101            { label: '都道府県議会議員', href: BASE + '/member/#pa',  dot: true },
102          ]
103        },
104        {
105          items: [
106            { label: '区議会議員',       href: BASE + '/member/#t23wc', dot: true },
107            { label: '市議会議員',       href: BASE + '/member/#cc',    dot: true },
108            { label: '町議会・村議会議員', href: BASE + '/member/#tvc', dot: true },
109          ]
110        },
111        {
112          wide: true,
113          items: [
114            { label: '公認候補予定者', isSpan: true },
115            { label: '地方議員選挙', href: BASE + '/2020/candidate', dot: true },
116          ]
117        },
118      ]
119    },
120    {
121      key: 'mega_news',
122      label: 'News',
123      href: BASE + '/news',
124      groups: [
125        {
126          items: [
127            { label: 'すべて',   href: BASE + '/news' },
128            { label: 'お知らせ', href: BASE + '/news/cat/infomation' },
129          ]
130        },
131        {
132          items: [
133            { label: '国会質疑', href: BASE + '/news/cat/parliamentary_qa_session' },
134            { label: '国会報告', href: BASE + '/news/cat/diet_report' },
135          ]
136        },
137        {
138          items: [
139            { label: '質問主意書', href: BASE + '/news/cat/question' },
140            { label: '記者会見',   href: BASE + '/news/cat/press_conference' },
141          ]
142        },
143        {
144          items: [
145            { label: '議員ブログ', href: BASE + '/news/cat/lawmaker' },
146            { label: '海外情報',   href: BASE + '/news/cat/translated_articles' },
147          ]
148        },
149      ]
150    },
151    {
152      key: 'mega_sns',
153      label: 'SNS',
154      href: null,
155      groups: [
156        {
157          items: [
158            { label: '公式YouTube', href: 'https://www.youtube.com/@sanseito-official', ext: true },
159            { label: '国会質問チャンネル',      href: 'https://www.youtube.com/@sanseito-kokkai', ext: true },
160            { label: 'サブチャンネル',      href: 'https://www.youtube.com/@sanseito_the_second', ext: true },
161          ]
162        },
163        {
164          items: [
165            { labelEl: '公式X', href: 'https://twitter.com/sansei411', ext: true },
166            { labelEl: '青年局X', href: 'https://x.com/sanseito_seinen', ext: true },
167            { label: 'Facebook', href: 'https://www.facebook.com/sanseito2020', ext: true },
168          ]
169        },
170        {
171          items: [
172            { label: '公式Instagram ',   href: 'https://www.instagram.com/sanseito/', ext: true },
173            { label: '青年局Instagram', href: 'https://www.instagram.com/sanseito_seinenkyoku/', ext: true },
174            { label: 'ギャラリーInstagram', href: 'https://www.instagram.com/sanseito_gallery/', ext: true },
175          ]
176        },
177        {
178          items: [
179            { label: 'TikTok', href: 'https://www.tiktok.com/@sanseito?lang=ja-JP', ext: true },
180            { label: 'LINE',   href: 'https://linevoom.line.me/user/_db41kk5azi1BiJqUApKpije1a115fPKSpXdfG_s', ext: true, skip: true },
181          ]
182        },
183      ]
184    },
185    {
186      key: 'mega_policy',
187      label: '政策',
188      href: BASE + '/political_measures/',
189      groups: [
190        {
191          items: [
192            { label: '3つの重点政策', href: BASE + '/political_measures/' },
193          ]
194        },
195        {
196          items: [
197            { label: '1.教育・人づくり',     href: BASE + '/political_measures/#education' },
198            { label: '2.食と健康・環境保全', href: BASE + '/political_measures/#food_health' },
199            { label: '3.国のまもり',         href: BASE + '/political_measures/#protection' },
200          ]
201        },
202        {
203          items: [
204            { label: '参政党政策カタログ',  href: BASE + '/political_measures_2025/' },
205            { label: '新日本憲法(構想案)', href: BASE + '/new_japanese_constitution//' },
206          ]
207        },
208      ]
209    },
210    {
211      key: 'mega_activity',
212      label: '活動',
213      href: null,
214      groups: [
215        {
216          items: [
217            { label: '街頭演説',       href: 'https://info.sanseito.jp/' },
218            { label: '国会活動まとめ', href: BASE + '/diet_activity' },
219          ]
220        },
221        {
222          items: [
223            { label: '参政党政治塾',   href: BASE + '/seijijuku/',      ext: true },
224            { label: '給食プロジェクト', href: BASE + '/kyushoku_project/', ext: true },
225          ]
226        },
227        {
228          items: [
229            { label: '終戦80年談話',      href: BASE + '/statement_on_the_80th/' },
230            { label: 'DIYタイムズを読む', href: BASE + '/read_diy_times/' },
231          ]
232        },
233      ]
234    },
235    {
236      key: 'mega_event',
237      label: 'イベント',
238      href: null,
239      groups: [
240        {
241          items: [
242            { label: 'イベント',         href: 'https://info.sanseito.jp/' },
243            { label: '神谷代表イベント', href: 'https://info.sanseito.jp/entry/kamiya-s', ext: true },
244          ]
245        },
246        {
247          items: [
248            { label: 'ちむぐくる沖縄 -9.13この島を想う日-', href: BASE + '/okinawa_2026', ext: true },
249            { label: '候補者募集説明会', href: 'https://info.sanseito.jp/entry/koubo-event', ext: true },
250          ]
251        },
252        {
253          items: [
254           { label: 'DIYスクール7', href: BASE + '/diyschool7th/', ext: true },
255           { label: 'プロジェクト600',  href: BASE + '/project600/' },
256           { label: '日本人ファーストプロジェクト', href: BASE + '/japanese_first_project/' },
257          ]
258        },
259      ]
260    },
261    {
262      key: 'mega_join',
263      label: '参加する',
264      href: null,
265      groups: [
266        {
267          items: [
268            { label: '党員になる', href: BASE + '/participation' },
269            { label: '運営党員',   href: BASE + '/participation#join_sanseito', dot: true },
270            { label: '一般党員',   href: BASE + '/participation#join02',        dot: true },
271          ]
272        },
273        {
274          items: [
275            { label: 'カジュアルに参加する', href: BASE + '/participation' },
276            { label: 'サポーター',           href: BASE + '/participation#join_free', dot: true },
277          ]
278        },
279        {
280          items: [
281            { label: '橙鳳会(継続寄付)', href: BASE + '/2020/continuous_donation/' },
282            { label: 'ご寄付',             href: 'https://congrant.com/project/sanseito/6104', ext: true },
283          ]
284        },
285        {
286          items: [
287            { label: '党職員募集',                    href: BASE + '/recruitment-of-party-officials/' },
288            { label: 'ポスター申込',                  href: BASE + '/poster_entry/' },
289          ]
290        },
291      ]
292    },
293    {
294      key: 'mega_koubo',
295      label: '候補者公募',
296      href: null,
297      groups: [
298        {
299          items: [
300            { label: '議員の入党・候補者公募', href: BASE + '/recruitment/' },
301            { label: '地方選候補者公募',       href: BASE + '/koubo/' },
302          ]
303        },
304      ]
305    },
306    {
307      key: 'mega_login',
308      label: '党員ページ',
309      href: null,
310      groups: [
311        {
312          items: [
313            { label: '党員ログイン', href: 'https://member.kaihipay.jp/stores/sanseito/me/login', ext: true },
314            { label: 'DIYナビ',     href: 'https://learn.sanseito.online/sanseitolms/users/login', ext: true },
315          ]
316        }
317      ]
318    },
319  ];
320
321  /* ==========================================================
322     3. HTML ビルダー
323  ========================================================== */
324
325  /** アンカー or スパンを1つ生成 */
326  function buildLink(item) {
327    if (item.isSpan) {
328      return '<span>' + (item.labelEl || item.label) + '</span>';
329    }
330    var cls = item.dot ? ' class="dot"' : '';
331    var ext = item.ext ? ' target="_Blank" rel="noopener noreferrer"' : '';
332    var gtm = ' data-gtm-click="グロナビサブ_' + item.label + '"';
333    return '<a href="' + item.href + '"' + cls + ext + gtm + '>'
334      + (item.labelEl || item.label) + '</a>';
335  }
336
337  /** グループ配列 → <ul class="megaMenu-list"> の文字列を生成 */
338  function buildGroups(groups) {
339    return groups.map(function (g) {
340      var ulCls = 'megaMenu-list' + (g.wide ? ' wide' : '');
341      var items = g.items.map(function (item) {
342        var liCls = 'megaMenu-item' + (item.skip ? ' skip' : '');
343        return '<li class="' + liCls + '">' + buildLink(item) + '</li>';
344      }).join('');
345      return '<ul class="' + ulCls + '">' + items + '</ul>';
346    }).join('');
347  }
348
349  /** PC メガメニュー全体の HTML */
350  function buildPcMegaMenu() {
351    var blocks = NAV_DATA.map(function (nav) {
352      return '<div class="block_wrap ' + nav.key + '">'
353        + '<div class="megaBlock">'
354        + buildGroups(nav.groups)
355        + '</div></div>';
356    }).join('');
357
358    return '<div class="megaMenu accordion-content">'
359      + '<div class="inner">' + blocks + '</div>'
360      + '</div>';
361  }
362
363  /** PC ナビ上部リスト */
364  function buildPcNavList() {
365    var items = NAV_DATA.map(function (nav) {
366      var href = nav.href || '#';
367      var gtm = nav.href ? ' data-gtm-click="グロナビ_' + nav.label + '"' : '';
368      var liCls = 'header-item' + (nav.key === 'mega_login' ? ' login' : '');
369      return '<li class="' + liCls + '">'
370        + '<a href="' + href + '" class="mega ' + nav.key + '" data-mega="' + nav.key + '"' + gtm + '>'
371        + nav.label + '</a></li>';
372    }).join('');
373
374    return '<ul class="header-list">' + items + '</ul>';
375  }
376
377  /** SP ナビ(アコーディオン込み)*/
378  function buildSpNav() {
379    var items = NAV_DATA.map(function (nav) {
380      var accordion = '<div class="megaMenu accordion-content">'
381        + '<div class="megaBlock t_line">'
382        + buildGroups(nav.groups)
383        + '</div></div>';
384
385      var liCls = 'header-item' + (nav.key === 'mega_login' ? ' login' : '');
386      return '<li class="' + liCls + '">'
387        + '<a href="#" class="mega ' + nav.key + ' accordion-header" data-mega="' + nav.key + '">'
388        + nav.label + '</a>'
389        + accordion
390        + '</li>';
391    }).join('');
392
393    return '<ul class="header-list">' + items + '</ul>';
394  }
395
396  /** ナビ全体の HTML を組み立てて #snav に注入 */
397  function buildNav() {
398    var logoSrc = 'https://sanseito.jp/nppoj/wp-content/themes/wp_310/images/logo.svg?20250910';
399
400    /* WP環境では <meta name="snav-logo"> でロゴパスを上書き可能 */
401    var logoMeta = document.querySelector('meta[name="snav-logo"]');
402    if (logoMeta) logoSrc = logoMeta.content;
403
404    var html = '<div class="head_nav js-header">'
405
406      /* ロゴ */
407      + '<h1><a href="' + BASE + '">'
408      + '<img class="h_logo js-logo" style="aspect-ratio:115/48;" src="' + logoSrc + '" alt="参政党">'
409      + '</a></h1>'
410
411      /* ハンバーガー */
412      + '<div class="hamburger"><span></span><span></span><span></span></div>'
413
414      /* PC ナビ(JS で is_mobile 相当の判定は CSS に任せる) */
415      + '<nav class="header-nav">'
416      + buildPcNavList()
417      + buildPcMegaMenu()
418      + '</nav>'
419
420      /* SP ナビ */
421      + '<nav class="header-nav_sp">'
422      + buildSpNav()
423      + '</nav>'
424
425      + '</div>'; /* .head_nav */
426
427    var wrapper = document.querySelector('.head_nav_box') || document.getElementById('snav');
428    if (!wrapper) return;
429
430    /* #snav のときはラッパーdivも生成 */
431    if (wrapper.id === 'snav') {
432      wrapper.className = 'head_nav_box';
433    }
434    wrapper.innerHTML = html;
435
436    /* ページロード時に .megaMenu の height を明示的にリセット
437       BFCache や前ページのホバー状態が残るのを防ぐ */
438    var megaMenu = wrapper.querySelector('.header-nav .megaMenu');
439    if (megaMenu) megaMenu.style.height = '0';
440  }
441
442  /* --nav-h:ヘッダー白帯の実高さをCSS変数に書き出す(MVの padding-top が参照)
443     SVGロード前の0/不足を避けるため load でも再計測、resize でも追従 */
444  function updateNavH() {
445    var navBox = document.querySelector('.head_nav_box');
446    if (!navBox) return;
447    var h = navBox.getBoundingClientRect().height;
448    if (h > 0) {
449      document.documentElement.style.setProperty('--nav-h', h + 'px');
450    }
451  }
452
453  /* ==========================================================
454     4. JS 制御(jQuery完全不使用・ネイティブJS)
455  ========================================================== */
456  function initNav() {
457
458    /* ---- slideToggle / fadeOut の代替実装 ---- */
459    function slideToggle(el, duration) {
460      duration = duration || 300;
461      if (!el) return;
462      if (el.style.display === 'none' || el.style.display === '') {
463        el.style.display = 'block';
464        el.style.overflow = 'hidden';
465        var h = el.scrollHeight;
466        el.style.height = '0';
467        el.style.transition = 'height ' + duration + 'ms ease';
468        requestAnimationFrame(function () {
469          el.style.height = h + 'px';
470        });
471        el.addEventListener('transitionend', function handler() {
472          el.style.height = '';
473          el.style.overflow = '';
474          el.style.transition = '';
475          el.removeEventListener('transitionend', handler);
476        });
477      } else {
478        el.style.overflow = 'hidden';
479        el.style.height = el.scrollHeight + 'px';
480        el.style.transition = 'height ' + duration + 'ms ease';
481        requestAnimationFrame(function () {
482          el.style.height = '0';
483        });
484        el.addEventListener('transitionend', function handler() {
485          el.style.display = 'none';
486          el.style.height = '';
487          el.style.overflow = '';
488          el.style.transition = '';
489          el.removeEventListener('transitionend', handler);
490        });
491      }
492    }
493
494    function fadeOut(el, duration) {
495      duration = duration || 200;
496      if (!el) return;
497      el.style.transition = 'opacity ' + duration + 'ms ease';
498      el.style.opacity = '0';
499      el.addEventListener('transitionend', function handler() {
500        el.style.display = 'none';
501        el.style.opacity = '';
502        el.style.transition = '';
503        el.removeEventListener('transitionend', handler);
504      });
505    }
506
507    function fadeIn(el, duration) {
508      duration = duration || 200;
509      if (!el) return;
510      el.style.display = 'block';
511      el.style.opacity = '0';
512      el.style.transition = 'opacity ' + duration + 'ms ease';
513      requestAnimationFrame(function () {
514        el.style.opacity = '1';
515      });
516      el.addEventListener('transitionend', function handler() {
517        el.style.transition = '';
518        el.removeEventListener('transitionend', handler);
519      });
520    }
521
522    function animateScrollTo(target, duration) {
523      duration = duration || 800;
524      var start = window.scrollY;
525      var end   = target;
526      var startTime = null;
527      function step(ts) {
528        if (!startTime) startTime = ts;
529        var progress = Math.min((ts - startTime) / duration, 1);
530        /* ease in-out */
531        var ease = progress < 0.5
532          ? 2 * progress * progress
533          : -1 + (4 - 2 * progress) * progress;
534        window.scrollTo(0, start + (end - start) * ease);
535        if (progress < 1) requestAnimationFrame(step);
536      }
537      requestAnimationFrame(step);
538    }
539
540    /* ---- メガメニュー 位置・サイズ計算 ---- */
541    var cachedNavH  = 0;
542    var cachedNavOH = 0;
543
544    function set_mega() {
545      var navList  = document.querySelector('.header-nav .header-list');
546      var jsHeader = document.querySelector('.js-header');
547      var navBox   = document.querySelector('.head_nav_box');
548      var megaInner= document.querySelector('.header-nav .megaMenu .inner');
549      var megaMenu = document.querySelector('.header-nav .megaMenu');
550      var whiteBg  = document.querySelector('.header_white_bg');
551
552      if (!navList || !jsHeader || !navBox) return false;
553
554      var hlw  = navList.getBoundingClientRect().width;
555      var jshr = parseFloat(window.getComputedStyle(jsHeader).paddingRight) || 0;
556      var hnbh = navBox.getBoundingClientRect().height;
557      var hnboh= navBox.offsetHeight;
558
559      if (hnbh === 0) return false;
560
561      cachedNavH  = hnbh;
562      cachedNavOH = hnboh;
563
564      var mmw = (hlw + jshr + 5) + 'px';
565      if (megaInner) megaInner.style.width = mmw;
566      if (megaMenu) {
567        megaMenu.style.paddingTop = cachedNavH + 'px';
568        megaMenu.style.height = '0';
569      }
570      if (whiteBg) whiteBg.style.height = cachedNavOH + 'px';
571      return true;
572    }
573
574    function set_mega_retry(count) {
575      count = count || 0;
576      if (set_mega()) return;
577      if (count < 20) setTimeout(function () { set_mega_retry(count + 1); }, 100);
578    }
579
580    set_mega_retry();
581    window.addEventListener('resize', function () {
582      cachedNavH = 0;
583      set_mega_retry();
584    });
585    window.addEventListener('load', function () {
586      set_mega_retry();
587      /* ページID 1517:MyASPのJSが遅延読み込みされるため段階的に再取得 */
588      if (document.body.classList.contains('page-id-1517')) {
589        [200, 500, 1000, 2000, 3000].forEach(function (ms) {
590          setTimeout(function () { cachedNavH = 0; set_mega_retry(); }, ms);
591        });
592      }
593    });
594
595    /* ---- PC:ホバーでメガメニュー開閉 ---- */
596    var datamega = '';
597
598    function getMegaBlockHeight(key) {
599      var el = document.querySelector('.block_wrap.' + key);
600      if (!el) return 0;
601      var prevVis = el.style.visibility;
602      var prevDis = el.style.display;
603      el.style.visibility = 'hidden';
604      el.style.display    = 'block';
605      var h = el.offsetHeight;
606      el.style.visibility = prevVis;
607      el.style.display    = prevDis;
608      return h;
609    }
610
611    function closeAllBlocks() {
612      document.querySelectorAll('.header-nav .block_wrap').forEach(function (el) {
613        el.style.display = 'none';
614      });
615      document.querySelectorAll('.header-nav .header-item a.mega').forEach(function (el) {
616        el.classList.remove('on');
617      });
618      var headerList = document.querySelector('.header-list');
619      if (headerList) headerList.classList.remove('on');
620      var megaMenu = document.querySelector('.header-nav .megaMenu');
621      if (megaMenu) megaMenu.style.height = '0';
622    }
623
624    function reset_mega(dm) {
625      if (!dm) return;
626      closeAllBlocks();
627    }
628
629    document.addEventListener('mouseenter', function (e) {
630      if (!e.target || !e.target.closest) return;
631      var trigger = e.target.closest('.header-nav .header-item a.mega');
632      if (!trigger) return;
633
634      closeAllBlocks();
635      trigger.classList.add('on');
636      datamega = trigger.getAttribute('data-mega');
637
638      if (datamega) {
639        var blockH = getMegaBlockHeight(datamega);
640        var h = blockH + cachedNavH + 40;
641        var megaMenu = document.querySelector('.header-nav .megaMenu');
642        if (megaMenu) megaMenu.style.height = h + 'px';
643        var blockEl = document.querySelector('.block_wrap.' + datamega);
644        if (blockEl) blockEl.style.display = 'block';
645      }
646
647      var headerList = document.querySelector('.header-list');
648      if (headerList) headerList.classList.add('on');
649    }, true); /* capture:true でネストした要素も確実に拾う */
650
651    var navBox = document.querySelector('.head_nav_box');
652    if (navBox) {
653      navBox.addEventListener('mouseleave', function () {
654        closeAllBlocks();
655        datamega = '';
656      });
657    }
658
659    /* ---- スクロール:ヘッダ挙動 ---- */
660    var prevScroll = 0;
661    window.addEventListener('scroll', function () {
662      var cur = window.scrollY;
663      var dir = cur > prevScroll ? 'down' : 'up';
664      var headNavBox = document.querySelector('.head_nav_box');
665      if (headNavBox) {
666        headNavBox.classList.remove('scrolling-up', 'scrolling-down');
667        headNavBox.classList.add('scrolling-' + dir);
668        if (cur > 300) {
669          headNavBox.classList.add('non_opt');
670        } else {
671          headNavBox.classList.remove('non_opt', 'scrolling-down');
672        }
673      }
674      prevScroll = cur;
675
676      var totop = document.querySelector('.totop');
677      if (totop) {
678        if (cur > 300) { fadeIn(totop, 200); }
679        else           { fadeOut(totop, 200); }
680      }
681    });
682
683    /* ---- SP:ハンバーガー ---- */
684    document.addEventListener('click', function (e) {
685      if (!e.target || !e.target.closest) return;
686      var btn = e.target.closest('.hamburger');
687      if (!btn) return;
688      btn.classList.toggle('active');
689      var spNav = document.querySelector('.header-nav_sp');
690      if (spNav) spNav.classList.toggle('active', btn.classList.contains('active'));
691    });
692
693    /* ---- SP:アコーディオン ---- */
694    document.addEventListener('click', function (e) {
695      if (!e.target || !e.target.closest) return;
696      var header = e.target.closest('.header-nav_sp .accordion-header');
697      if (!header) return;
698      header.classList.toggle('active');
699      var content = header.nextElementSibling;
700      if (content && content.classList.contains('accordion-content')) {
701        slideToggle(content, 300);
702      }
703    });
704
705    /* ---- SP:ページ内リンク クリック時にメニューを閉じる ---- */
706    document.addEventListener('click', function (e) {
707      if (!e.target || !e.target.closest) return;
708      var link = e.target.closest('.insidelink a');
709      if (!link) return;
710      var headerItem = link.closest('.header-item');
711      if (!headerItem) return;
712      var accHeader = headerItem.querySelector('.accordion-header');
713      var mega = accHeader ? accHeader.getAttribute('data-mega') : null;
714
715      var spNav = document.querySelector('.header-nav_sp');
716      var hamburger = document.querySelector('.hamburger');
717      if (spNav) spNav.classList.remove('active');
718      if (hamburger) hamburger.classList.remove('active');
719
720      if (mega) {
721        var megaEl = headerItem.querySelector('.' + mega);
722        if (megaEl) megaEl.classList.remove('active');
723        var accContent = headerItem.querySelector('.' + mega + ' + .megaMenu.accordion-content');
724        if (accContent) slideToggle(accContent, 300);
725      }
726    });
727
728    /* ---- トップへ戻る ---- */
729    document.addEventListener('click', function (e) {
730      if (!e.target || !e.target.closest) return;
731      if (e.target.closest('.totop')) {
732        e.preventDefault();
733        animateScrollTo(0, 500);
734      }
735    });
736
737    /* ---- スムーズスクロール(ナビ内・totop・insidelink のみ対象) ---- */
738    document.addEventListener('click', function (e) {
739      if (!e.target || !e.target.closest) return;
740      var link = e.target.closest('a[href^="#"]');
741      if (!link) return;
742      /* MyASPフォーム内のリンクは除外 */
743      if (link.closest('form') || link.closest('.content_form')) return;
744      var href = link.getAttribute('href');
745      if (href === '#') { e.preventDefault(); animateScrollTo(0, 800); return; }
746      var target = document.querySelector(href);
747      if (!target) return;
748      e.preventDefault();
749      var targetY = target.getBoundingClientRect().top + window.scrollY;
750      /* 上方向へ移動する場合はヘッダーが表示されるため、ヘッダーの高さ分だけ手前で止める */
751      if (targetY < window.scrollY) {
752        var headNavBoxEl = document.querySelector('.head_nav_box');
753        if (headNavBoxEl) {
754          targetY = Math.max(0, targetY - headNavBoxEl.offsetHeight);
755        }
756      }
757      animateScrollTo(targetY, 800);
758    });
759
760  }
761
762  /* ==========================================================
763     5. BFCache 対策
764     ブラウザの戻る/進むキャッシュで復元されたとき、
765     前ページでホバーして height がセットされた .megaMenu を
766     リセットして閉じた状態に戻す
767  ========================================================== */
768  window.addEventListener('pageshow', function (e) {
769    if (e.persisted) {
770      /* BFCache から復元されたとき */
771      var megaMenu = document.querySelector('.header-nav .megaMenu');
772      var blockWraps = document.querySelectorAll('.block_wrap');
773      if (megaMenu) megaMenu.style.height = '0';
774      blockWraps.forEach(function (el) { el.style.display = 'none'; });
775      /* ナビリストの on クラスもリセット */
776      var headerList = document.querySelector('.header-list');
777      if (headerList) headerList.classList.remove('on');
778      document.querySelectorAll('.header-item a.mega').forEach(function (el) {
779        el.classList.remove('on');
780      });
781    }
782  });
783
784  /* ==========================================================
785     6. 実行
786  ========================================================== */
787  if (document.readyState === 'loading') {
788    document.addEventListener('DOMContentLoaded', function () {
789      buildNav();
790      initNav();
791      updateNavH();
792    });
793  } else {
794    buildNav();
795    initNav();
796    updateNavH();
797  }
798  /* SVGロード完了後・リサイズ時にも白帯高さを再計測して --nav-h を更新 */
799  window.addEventListener('load', updateNavH);
800  window.addEventListener('resize', updateNavH);
801
802})();

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.