PageSourceSearch

https://hatas-g.net/wp/wp-content/themes/hatas/new/js/new.js?v=20260930

js hatas-g.net collected 2026-10-05 11:45:26 UTC 5,532 bytes, 106 lines download raw bytes

1/* new.js  新TOP・新記事詳細の共通スクリプト(jQuery非依存) */
2(function () {
3  'use strict';
4
5  /* ---------- SPドロワー ---------- */
6  var btn = document.getElementById('nh-menu-btn');
7  var closeBtn = document.getElementById('nh-menu-close');
8  var drawer = document.getElementById('nh-drawer');
9  var overlay = document.getElementById('nh-drawer-overlay');
10
11  function openDrawer() {
12    if (!drawer) return;
13    drawer.classList.add('is-open');
14    overlay && overlay.classList.add('is-open');
15    document.body.classList.add('nh-drawer-open');
16    drawer.setAttribute('aria-hidden', 'false');
17    btn && btn.setAttribute('aria-expanded', 'true');
18  }
19  function closeDrawer() {
20    if (!drawer) return;
21    drawer.classList.remove('is-open');
22    overlay && overlay.classList.remove('is-open');
23    document.body.classList.remove('nh-drawer-open');
24    drawer.setAttribute('aria-hidden', 'true');
25    btn && btn.setAttribute('aria-expanded', 'false');
26  }
27  btn && btn.addEventListener('click', openDrawer);
28  closeBtn && closeBtn.addEventListener('click', closeDrawer);
29  overlay && overlay.addEventListener('click', closeDrawer);
30  document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeDrawer(); });
31  /* PC 幅(1080px 以上)に広げたらドロワーを閉じる(body の overflow:hidden が残らないように) */
32  if (window.matchMedia) {
33    var mqPc = window.matchMedia('(min-width: 1080px)');
34    var onMq = function (e) { if (e.matches) closeDrawer(); };
35    if (mqPc.addEventListener) { mqPc.addEventListener('change', onMq); } else if (mqPc.addListener) { mqPc.addListener(onMq); }
36  }
37
38  /* ---------- 固定ヘッダーの影 ---------- */
39  var hd = document.getElementById('nh-header');
40  if (hd) {
41    var onScroll = function () { hd.classList.toggle('is-stuck', window.scrollY > 8); };
42    window.addEventListener('scroll', onScroll, { passive: true }); onScroll();
43    /* 実測のヘッダー高さを --nh-header-off に入れる(メディア版はカテゴリ列の分だけ高く、タブレットでは折り返す) */
44    var setHeaderOff = function () { document.documentElement.style.setProperty('--nh-header-off', hd.offsetHeight + 'px'); };
45    if ('ResizeObserver' in window) { new ResizeObserver(setHeaderOff).observe(hd); } else { window.addEventListener('resize', setHeaderOff); }
46    setHeaderOff();
47  }
48
49  /* ---------- スクロールで現れる要素(.nh-reveal) ---------- */
50  var reveals = document.querySelectorAll('.nh-reveal');
51  if ('IntersectionObserver' in window && reveals.length) {
52    var io = new IntersectionObserver(function (entries) {
53      entries.forEach(function (en) {
54        if (en.isIntersecting) { en.target.classList.add('is-in'); io.unobserve(en.target); }
55      });
56    }, { rootMargin: '0px 0px -10% 0px' });
57    reveals.forEach(function (el) { io.observe(el); });
58  } else {
59    reveals.forEach(function (el) { el.classList.add('is-in'); });
60  }
61
62  /* ---------- 横スクロールのカード列(.nh-scroller)のドット ---------- */
63  document.querySelectorAll('.nh-scroller').forEach(function (sc) {
64    var track = sc.querySelector('.nh-scroller__track');
65    var dots = sc.querySelectorAll('.nh-scroller__dot');
66    if (!track || !dots.length) return;
67    track.addEventListener('scroll', function () {
68      var i = Math.round(track.scrollLeft / track.clientWidth);
69      dots.forEach(function (d, k) { d.classList.toggle('is-on', k === i); });
70    }, { passive: true });
71  });
72
73  /* ---------- 11月版プルダウン(.nh-gnav__dd) ----------
74     マウスのホバーは CSS のまま。タッチ環境(hover: none)では親リンクの1回目のタップで開閉だけ行い、
75     2回目のタップで遷移する。フォーカスが外れたとき・外側をタップしたとき・Esc で閉じる。 */
76  var dds = document.querySelectorAll('.nh-gnav__dd');
77  if (dds.length) {
78    var noHover = window.matchMedia ? window.matchMedia('(hover: none)').matches : false;
79    var setDd = function (dd, open) {
80      dd.classList.toggle('is-open', open);
81      var a = dd.querySelector('.nh-gnav__item--has-sub');
82      a && a.setAttribute('aria-expanded', open ? 'true' : 'false');
83    };
84    var closeAllDd = function (except) { dds.forEach(function (dd) { if (dd !== except) setDd(dd, false); }); };
85    dds.forEach(function (dd) {
86      var trigger = dd.querySelector('.nh-gnav__item--has-sub');
87      if (!trigger) return;
88      trigger.addEventListener('click', function (e) {
89        if (!noHover) return;                              /* マウス環境はホバーで開いているので通常どおり遷移 */
90        if (dd.classList.contains('is-open')) return;      /* 2回目のタップは遷移 */
91        e.preventDefault();
92        closeAllDd(dd);
93        setDd(dd, true);
94      });
95      /* キーボード操作:focus-within で CSS が開くので aria-expanded を合わせる。フォーカスが外に出たら閉じる */
96      dd.addEventListener('focusin', function () { trigger.setAttribute('aria-expanded', 'true'); });
97      dd.addEventListener('focusout', function (e) { if (!dd.contains(e.relatedTarget)) setDd(dd, false); });
98    });
99    document.addEventListener('click', function (e) {
100      var t = e.target;
101      if (t && t.closest && t.closest('.nh-gnav__dd')) return;
102      closeAllDd(null);
103    });
104    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeAllDd(null); });
105  }
106})();

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.