PageSourceSearch

https://www.keio-tamagawa-pj.com/wp-content/themes/k-tama/assets/js/top.js?ver=1764755012

js keio-tamagawa-pj.com collected 2026-10-05 07:32:30 UTC 7,317 bytes, 271 lines download raw bytes

1/* ============================================================
2    Modal slider
3============================================================ */
4function modalReportSlider() {
5  var mySwiper = new Swiper(".js-report", {
6    direction: "horizontal",
7    centeredSlides: true,
8
9    navigation: {
10      nextEl: ".swiper-button-next-modal",
11      prevEl: ".swiper-button-prev-modal",
12    },
13
14    speed: 1000,
15    effect: "fade",
16    fadeEffect: { crossFade: true },
17
18    on: {
19      init: function () {
20        updateAccessibility(this);
21      },
22      slideChange: function () {
23        updateAccessibility(this);
24
25        setTimeout(function () {
26          document.querySelector(".modal__wrap").scrollTo({
27            top: 0,
28            // behavior: 'smooth'
29          });
30        }, 100);
31
32        // playText(this);
33      },
34    },
35  });
36
37  document.querySelectorAll(".report__list--item").forEach((item) => {
38    item.addEventListener("click", function (event) {
39      event.preventDefault();
40
41      let dataNumber = this.dataset.slide;
42      let slideIndex = parseInt(dataNumber, 10) - 1;
43
44      mySwiper.slideToLoop(slideIndex, 500);
45
46      document.querySelector(".modal").classList.add("is-open");
47      document.querySelector("body").classList.add("has-modal");
48      // playText(mySwiper);
49    });
50  });
51
52  document
53    .querySelectorAll(".report .image__report .position-dot")
54    .forEach((item) => {
55      item.addEventListener("click", function (event) {
56        event.preventDefault();
57
58        let dataNumber = this.dataset.number;
59        let slideIndex = parseInt(dataNumber, 10) - 1;
60
61        mySwiper.slideToLoop(slideIndex, 500);
62
63        document.querySelector(".modal").classList.add("is-open");
64        document.querySelector("body").classList.add("has-modal");
65        // playText(mySwiper);
66      });
67    });
68
69  document.querySelector(".close").addEventListener("click", function () {
70    document.querySelector(".modal").classList.remove("is-open");
71    document.querySelector("body").classList.remove("has-modal");
72  });
73
74  function updateAccessibility(swiper) {
75    swiper.slides.forEach((slide, index) => {
76      if (index === swiper.realIndex) {
77        slide.setAttribute("aria-hidden", "false");
78        slide.setAttribute("tabindex", "0");
79      } else {
80        slide.setAttribute("aria-hidden", "true");
81        slide.setAttribute("tabindex", "-1");
82      }
83    });
84
85    // ナビゲーションボタンのaria-label設定
86    const nextBtn = document.querySelector(".swiper-button-next-modal");
87    const prevBtn = document.querySelector(".swiper-button-prev-modal");
88    if (nextBtn) nextBtn.setAttribute("aria-label", "次のスライド");
89    if (prevBtn) prevBtn.setAttribute("aria-label", "前のスライド");
90  }
91
92  function playText(swiper) {
93    const activeSlide = swiper.slides[swiper.activeIndex];
94    // activeSlide.querySelectorAll('.text-vertical').forEach((entry) => {
95    //     if (!entry.classList.contains('animated')) {
96    //         revealText(entry, entry.dataset.delay * 5);
97    //         entry.classList.add('animated');
98    //     }
99    // })
100
101    setTimeout(function () {
102      let last = +new Date();
103      const tick = function () {
104        activeSlide.querySelector(".list__item").style.opacity =
105          +activeSlide.querySelector(".list__item").style.opacity +
106          (new Date() - last) / 400;
107        last = +new Date();
108
109        if (+activeSlide.querySelector(".list__item").style.opacity < 1) {
110          requestAnimationFrame(tick);
111        }
112      };
113
114      tick();
115    }, 1000);
116  }
117
118  if (window.innerWidth <= 768) {
119    document.querySelectorAll(".modal__item").forEach((item, index) => {
120      item.insertBefore(
121        item.querySelector("h3.title"),
122        item.querySelector(".flex__wrap"),
123      );
124    });
125  }
126}
127
128/* ============================================================
129   Load More
130============================================================ */
131
132function leadmore() {
133  const items = document.querySelectorAll(".news__item");
134  const btn = document.getElementById("leadmore");
135  if (!btn) return;
136
137  const btnWrap = btn.closest(".btn-leadmore-wrap");
138
139  const updateLastRowClasses = () => {
140    items.forEach((item) => item.classList.remove("is-last-row"));
141
142    const hasHiddenItems = Array.from(items).some((item) =>
143      item.classList.contains("is-hidden"),
144    );
145
146    if (hasHiddenItems) return;
147
148    const visibleItems = Array.from(items).filter(
149      (item) => !item.classList.contains("is-hidden"),
150    );
151    const count = visibleItems.length;
152
153    if (count === 0) return;
154
155    // 最後の要素には常に付与
156    visibleItems[count - 1].classList.add("is-last-row");
157
158    // 偶数個なら最後から2番目にも付与(2列表示対応)
159    if (count % 2 === 0 && count >= 2) {
160      visibleItems[count - 2].classList.add("is-last-row");
161    }
162  };
163
164  if (items.length === 0) {
165    if (btnWrap) btnWrap.style.display = "none";
166    return;
167  }
168
169  let visibleCount = 4;
170
171  items.forEach((item) => item.classList.add("is-hidden"));
172
173  for (let i = 0; i < visibleCount; i++) {
174    if (items[i]) items[i].classList.remove("is-hidden");
175  }
176
177  updateLastRowClasses();
178
179  btn.addEventListener("click", function (e) {
180    e.preventDefault();
181
182    const start = visibleCount;
183    const end = visibleCount + 4;
184
185    for (let i = start; i < end; i++) {
186      if (items[i]) {
187        const item = items[i];
188        item.classList.add("is-fading");
189        item.classList.remove("is-hidden");
190
191        setTimeout(() => {
192          item.classList.remove("is-fading");
193        }, 20);
194      }
195    }
196
197    visibleCount += 4;
198
199    updateLastRowClasses();
200
201    if (visibleCount >= items.length) {
202      if (btnWrap) {
203        btnWrap.style.display = "none";
204      }
205    }
206  });
207}
208
209/* ============================================================
210   Empty News List
211============================================================ */
212function checkEmptyNewsList() {
213  const list = document.querySelector(".news__list");
214  const pickupContent = document.querySelector(".pickup");
215  if (!list) return;
216
217  const items = list.querySelectorAll(".news__item");
218
219  if (items.length === 0) {
220    pickupContent.remove();
221  }
222}
223
224/* ============================================================
225    init Function
226============================================================ */
227
228modalReportSlider();
229leadmore();
230checkEmptyNewsList();
231
232setTimeout(() => {
233  setupObserver();
234}, 200);
235
236function linkHover(sourceSelector, targetSelector, sourceAttr, targetAttr) {
237  const sourceElements = document.querySelectorAll(sourceSelector);
238
239  sourceElements.forEach((sourceEl) => {
240    const id = sourceEl.dataset[sourceAttr];
241
242    const targetEl = document.querySelector(
243      `${targetSelector}[data-${targetAttr}="${id}"]`,
244    );
245    if (!targetEl) return;
246
247    sourceEl.addEventListener("mouseenter", () => {
248      targetEl.classList.add("hover");
249    });
250
251    sourceEl.addEventListener("mouseleave", () => {
252      targetEl.classList.remove("hover");
253    });
254  });
255}
256
257// Link dots to list items
258linkHover(
259  ".report .image__report .position-dot",
260  ".report__list--item",
261  "number",
262  "slide",
263);
264
265// Link list items to dots
266linkHover(
267  ".report__list--item",
268  ".report .image__report .position-dot",
269  "slide",
270  "number",
271);

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.