1/** 2 * Figaro Infinite Scroll JavaScript 3 * ç¡éã¹ã¯ãã¼ã«æ©è½ã®å®è£ 4 * 5 * @package Figaro_Infinite_Scroll 6 */ 7 8(function() { 9 'use strict'; 10 11 /** 12 * ç¡éã¹ã¯ãã¼ã«ã¯ã©ã¹ 13 */ 14 class InfiniteScroll { 15 constructor() { 16 // PHPããæ¸¡ããããã¼ã¿ 17 this.data = window.figaroInfiniteScroll || {}; 18 this.articleIds = this.data.articleIds || []; 19 this.triggerThreshold = this.data.triggerThreshold || 0.7; 20 this.apiUrl = this.data.apiUrl || ''; 21 22 // ç¶æ 管ç 23 this.currentIndex = 0; 24 this.isLoading = false; 25 this.observer = null; 26 this.articleObserver = null; 27 this.lastScrollTime = 0; 28 this.scrollThrottle = 100; // 100msééã§URLæ´æ°ãã§ã㯠29 30 // åæå 31 this.init(); 32 } 33 34 /** 35 * åæå 36 */ 37 init() { 38 if (this.articleIds.length === 0) { 39 return; 40 } 41 42 // ååã®è¨äºã»ã¯ã·ã§ã³ãç£è¦å¯¾è±¡ã« 43 this.observeCurrentArticle(); 44 45 // 1è¨äºç®ï¼ã©ã³ãã£ã³ã°è¨äºï¼ãURLæ´æ°ç£è¦å¯¾è±¡ã« 46 const firstArticle = document.querySelector('.p-detail'); 47 if (firstArticle) { 48 this.observeArticleForUrlUpdate(firstArticle); 49 } 50 51 // ã¹ã¯ãã¼ã«ã¤ãã³ããªã¹ãã¼ã追å ï¼URLæ´æ°ç¨ï¼ 52 window.addEventListener('scroll', () => this.handleScroll(), { passive: true }); 53 54 // ååã®URLæ´æ°ãã§ã㯠55 this.updateCurrentArticleUrl(); 56 } 57 58 /** 59 * ç¾å¨ã®è¨äºã»ã¯ã·ã§ã³ãç£è¦ 60 */ 61 observeCurrentArticle() { 62 // è¨äºã®æä¸é¨è¦ç´ ï¼ãã³ãããªã¹ãï¼ãç£è¦å¯¾è±¡ã« 63 const breadcrumbs = document.querySelectorAll('.breadcrumb__wrapper'); 64 if (breadcrumbs.length === 0) { 65 return; 66 } 67 68 const lastBreadcrumb = breadcrumbs[breadcrumbs.length - 1]; 69 70 // Intersection Observerã使 71 if (this.observer) { 72 this.observer.disconnect(); 73 } 74 75 this.observer = new IntersectionObserver( 76 (entries) => this.handleIntersection(entries), 77 { 78 root: null, 79 rootMargin: '0px', 80 threshold: 0.6 // ãã³ãããªã¹ãã60%è¦ãããçºç« 81 } 82 ); 83 84 this.observer.observe(lastBreadcrumb); 85 } 86 87 /** 88 * Intersection Observer ã®ã³ã¼ã«ãã㯠89 * 90 * @param {IntersectionObserverEntry[]} entries 91 */ 92 handleIntersection(entries) { 93 entries.forEach(entry => { 94 // è¦ç´ ãç»é¢ã«å ¥ã£ããæ¬¡ã®è¨äºãèªã¿è¾¼ã¿ 95 // isLoadingãã§ãã¯ã§äºéçºç«ã鲿¢ 96 if (entry.isIntersecting && !this.isLoading) { 97 this.loadNextArticle(); 98 } 99 }); 100 } 101 102 103 /** 104 * 次ã®è¨äºãèªã¿è¾¼ã¿ 105 */ 106 async loadNextArticle() { 107 // ãã¼ãã£ã³ã°ä¸ã¾ãã¯è¨äºãæ®ã£ã¦ããªãå ´åã¯ä½ãããªã 108 if (this.isLoading || this.currentIndex >= this.articleIds.length) { 109 // Observerãç ´æ£ãã¦ç£è¦ã忢 110 if (this.observer) { 111 this.observer.disconnect(); 112 } 113 return; 114 } 115 116 this.isLoading = true; 117 const nextArticle = this.articleIds[this.currentIndex]; 118 // nextArticleãundefinedã®å ´åã¯æ©æãªã¿ã¼ã³ 119 if (!nextArticle) { 120 this.isLoading = false; 121 return; 122 } 123 124 // ãã«ããµã¤ãå½¢å¼ï¼ãªãã¸ã§ã¯ãï¼ãã¬ã¬ã·ã¼å½¢å¼ï¼æ´æ°ï¼ããå¤å® 125 const isMultisite = typeof nextArticle === 'object' && nextArticle !== null && nextArticle.site_id && nextArticle.post_id; 126 const siteId = isMultisite ? nextArticle.site_id : 1; // ã¬ã¬ã·ã¼å½¢å¼ã¯ã¡ã¤ã³ãµã¤ã (blog_id=1) 127 const postId = isMultisite ? nextArticle.post_id : nextArticle; 128 129 // ãããã°ãã° 130 console.log('[Infinite Scroll] nextArticle:', nextArticle); 131 console.log('[Infinite Scroll] isMultisite:', isMultisite); 132 console.log('[Infinite Scroll] siteId:', siteId, 'postId:', postId); 133 134 try { 135 // ãã«ããµã¤ã対å¿: blog_idãå«ãURLãæ§ç¯ 136 const apiEndpoint = isMultisite ? `${this.apiUrl}${siteId}/${postId}` : `${this.apiUrl}${postId}`; 137 console.log('[Infinite Scroll] API Endpoint:', apiEndpoint); 138 const response = await fetch(apiEndpoint, { 139 method: 'GET', 140 headers: { 141 'Content-Type': 'application/json' 142 } 143 }); 144 145 if (!response.ok) { 146 throw new Error(`HTTP error! status: ${response.status}`); 147 } 148 149 const data = await response.json(); 150 151 if (data.success && data.html) { 152 // ã¡ã¿æ å ±ãå«ãã¦è¨äºã追å 153 const meta = { 154 title: data.title, 155 description: data.description, 156 og_image: data.og_image, 157 dataLayer: data.dataLayer, 158 post_id: postId // åºåç¨ã«è¨äºIDã追å 159 }; 160 this.appendArticle(data.html, meta); 161 this.currentIndex++; 162 163 // æ°ããè¨äºãç£è¦å¯¾è±¡ã« 164 this.observeCurrentArticle(); 165 } else { 166 console.error('Failed to load article:', data); 167 } 168 } catch (error) { 169 console.error('Error loading article:', error); 170 } finally { 171 this.isLoading = false;
172 } 173 } 174 175 /** 176 * è¨äºHTMLãDOMã«è¿½å 177 * 178 * @param {string} html 179 * @param {object} meta - è¨äºã®ã¡ã¿æ å ±ï¼title, url, description, og_imageï¼ 180 */ 181 appendArticle(html, meta) { 182 // æå¾ã®è¨äºè¦ç´ ãæ¢ã 183 const articles = document.querySelectorAll('.p-detail'); 184 if (articles.length === 0) { 185 console.error('article element not found'); 186 return; 187 } 188 189 const lastArticle = articles[articles.length - 1]; 190 191 // æ°ããè¨äºè¦ç´ ã使 192 const tempDiv = document.createElement('div'); 193 tempDiv.innerHTML = html.trim(); 194 const newArticle = tempDiv.firstChild; 195 196 // ã¡ã¿æ å ±ãdata屿§ã¨ãã¦ä¿å 197 if (meta) { 198 newArticle.dataset.metaTitle = meta.title || ''; 199 newArticle.dataset.metaDescription = meta.description || ''; 200 newArticle.dataset.metaOgImage = meta.og_image || ''; 201 newArticle.dataset.datalayer = JSON.stringify(meta.dataLayer || {}); 202 } 203 204 // 追å èªè¾¼ããè¨äºã«padding-topãè¨å®ï¼PC:60pxãSP:8vwï¼ 205 const paddingTop = window.innerWidth >= 768 ? '60px' : '8vw'; 206 newArticle.style.paddingTop = paddingTop; 207 208 // ãã§ã¼ãã¤ã³ç¨ã®ã¹ã¿ã¤ã« 209 newArticle.style.opacity = '0'; 210 newArticle.style.transform = 'translateY(20px)'; 211 newArticle.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; 212 213 // GAMåçã¹ãããç¨ã®åºåã»ã¯ã·ã§ã³ã使 214 const pageIndex = this.currentIndex + 1; // 次ã®ãã¼ã¸çªå·ï¼1ãã¼ã¹ï¼ 215 const postId = meta && meta.post_id ? meta.post_id : 'unknown'; 216 217 const adSection = document.createElement('div'); 218 adSection.className = 'b-ad gam-ad-slot-infinity-scroll'; 219 220 // PCç¨ã¹ããã 221 const pcAdDiv = document.createElement('div'); 222 pcAdDiv.id = `div-gpt-ad-pc-infinity-article-${postId}-${pageIndex}`; 223 pcAdDiv.className = 'gam-ad-slot gam-ad-slot-pc'; 224 pcAdDiv.style.minWidth = '300px'; 225 pcAdDiv.style.textAlign = 'center'; 226 pcAdDiv.style.fontSize = '0'; 227 228 // SPç¨ã¹ããã 229 const spAdDiv = document.createElement('div'); 230 spAdDiv.id = `div-gpt-ad-sp-infinity-article-${postId}-${pageIndex}`; 231 spAdDiv.className = 'gam-ad-slot gam-ad-slot-sp'; 232 spAdDiv.style.minWidth = '300px'; 233 spAdDiv.style.textAlign = 'center'; 234 spAdDiv.style.fontSize = '0'; 235 236 // adSection.appendChild(pcAdDiv); 237 // adSection.appendChild(spAdDiv); 238 239 // åºåãå ã«æ¿å ¥ 240 lastArticle.insertAdjacentElement('afterend', adSection); 241 242 // åºåã®å¾ã«è¨äºãæ¿å ¥ 243 adSection.insertAdjacentElement('afterend', newArticle); 244 245 // GAMåçã¹ãããå¼ã³åºãï¼å°ãé å»¶ãããï¼ 246 setTimeout(() => { 247 if (typeof dynamic_whatpagerAD === 'function') { 248 dynamic_whatpagerAD(postId, pageIndex); 249 } else { 250 console.warn('dynamic_whatpagerAD function not defined'); 251 } 252 253 // Showcase 1stï¼æ¬æç´ä¸ï¼åºåã®åçå¼ã³åºã 254 if (typeof dynamic_showcase1stAD === 'function') { 255 dynamic_showcase1stAD(postId); 256 } 257 258 // Billboard 3rd / Showcase 3rdï¼ãã³ããåï¼åºåã®åçå¼ã³åºã 259 if (typeof dynamic_3rdAD === 'function') { 260 dynamic_3rdAD(postId); 261 } 262 }, 100); 263 264 // å°ãé å»¶ããã¦ãã§ã¼ãã¤ã³ 265 setTimeout(() => { 266 newArticle.style.opacity = '1'; 267 newArticle.style.transform = 'translateY(0)'; 268 }, 50); 269 270 // URLæ´æ°ç¨ã®ç£è¦ãéå§ 271 this.observeArticleForUrlUpdate(newArticle); 272 273 // ã®ã£ã©ãªã¼/ã¹ã©ã¤ãã¼ãããã¯ã®ååæå 274 this.reinitializeModules(newArticle); 275 276 // ç®æ¬¡ãããã¯ã®åæå 277 this.initTableOfContents(newArticle); 278 279 // SNSåãè¾¼ã¿ã®åå¦ç 280 // innerHTMLã§æ¿å ¥ãã<script>ã¯å®è¡ãããªããããåãããã¤ãã®ã¹ã¯ãªãããæç¤ºçã«å¼ã³ç´ã 281 this.reinitializeInstagramEmbeds(newArticle); 282 this.reinitializeTikTokEmbeds(newArticle); 283 this.reinitializeTwitterEmbeds(newArticle); 284 285 // ãã¼ã¸ã£ã¼ãããã¯ã®åºåç£è¦ãéå§ 286 if (window.figaroPagerAdLoader && typeof window.figaroPagerAdLoader.observePagers === 'function') { 287 window.figaroPagerAdLoader.observePagers(newArticle); 288 } 289 } 290 291 /** 292 * Instagramåãè¾¼ã¿ã®åå¦ç 293 * 追å ãããè¨äºå ã® blockquote.instagram-media ã iframe åãã 294 * 295 * @param {HTMLElement} article - æ°ãã追å ãããè¨äºè¦ç´ 296 */ 297 reinitializeInstagramEmbeds(article) { 298 if (!article.querySelector('blockquote.instagram-media')) { 299 return; 300 } 301 302 if (window.instgrm && window.instgrm.Embeds && typeof window.instgrm.Embeds.process === 'function') { 303 window.instgrm.Embeds.process(); 304 return; 305 } 306 307 // embed.jsãæªãã¼ãã®å ´åã¯åçã«æ³¨å ¥ï¼èªã¿è¾¼ã¿å®äºæã«processãèªåå®è¡ãããï¼ 308 if (!document.querySelector('script[src*="instagram.com/embed.js"]')) { 309 const script = document.createElement('script'); 310 script.src = 'https://www.instagram.com/embed.js'; 311 script.async = true; 312 document.body.appendChild(script); 313 } 314 } 315 316 /** 317 * TikTokåãè¾¼ã¿ã®åå¦ç 318 * 追å ãããè¨äºå ã® blockquote.tiktok-embed ã iframe åãã 319 * 320 * TikTokã«ã¯å ¬å¼ã®åæç»APIããªããããscriptã¿ã°ãåæ³¨å ¥ãã¦DOMå ¨ä½ãåã¹ãã£ã³ããã 321 * 322 * @param {HTMLElement} article - æ°ãã追å ãããè¨äºè¦ç´ 323 */ 324 reinitializeTikTokEmbeds(article) { 325 if (!article.querySelector('blockquote.tiktok-embed')) { 326 return; 327 } 328 329 // æ¢åã®embed.jsãåé¤ãã¦åæ³¨å ¥ããï¼åæ³¨å ¥æã«DOMå ¨ä½ãåã¹ãã£ã³ããï¼ 330 const existing = document.querySelector('script[src*="tiktok.com/embed.js"]'); 331 if (existing) { 332 existing.remove(); 333 } 334 335 const script = document.createElement('script'); 336 script.src = 'https://www.tiktok.com/embed.js'; 337 script.async = true; 338 document.body.appendChild(script); 339 } 340 341 /** 342 * Twitter/Xåãè¾¼ã¿ã®åå¦ç 343 * 追å ãããè¨äºå ã® blockquote.twitter-tweet ã iframe åãã 344 * 345 * @param {HTMLElement} article - æ°ãã追å ãããè¨äºè¦ç´ 346 */ 347 reinitializeTwitterEmbeds(article) { 348 if (!article.querySelector('blockquote.twitter-tweet')) { 349 return; 350 } 351 352 // twttr.widgets.load(scope) ã§ã¹ã³ã¼ãæå®ã®å夿ãå¯è½ï¼idempotentï¼ 353 if (window.twttr && window.twttr.widgets && typeof window.twttr.widgets.load === 'function') { 354 window.twttr.widgets.load(article); 355 return; 356 } 357 358 // widgets.jsãæªãã¼ãã®å ´åã¯åçã«æ³¨å ¥ï¼èªã¿è¾¼ã¿å®äºæã«å ¨blockquoteãå¦çããï¼ 359 if (!document.querySelector('script[src*="platform.twitter.com/widgets.js"]')) { 360 const script = document.createElement('script'); 361 script.src = 'https://platform.twitter.com/widgets.js'; 362 script.async = true; 363 document.body.appendChild(script); 364 } 365 } 366 367 /** 368 * ã®ã£ã©ãªã¼/ã¹ã©ã¤ãã¼ã¢ã¸ã¥ã¼ã«ã®ååæå 369 * 370 * @param {HTMLElement} article - æ°ãã追å ãããè¨äºè¦ç´ 371 */ 372 reinitializeModules(article) { 373 // ã«ã¹ã¿ã ã¤ãã³ãããã£ã¹ããã 374 // 注æ: DOMContentLoadedã¤ãã³ãã¯ãã£ã¹ãããããªã 375 // ï¼æ°ããInfiniteScrollã¤ã³ã¹ã¿ã³ã¹ã使ããã¦ãã¾ãããï¼ 376 const contentAddedEvent = new CustomEvent('contentAdded', { 377 detail: { element: article }, 378 bubbles: true 379 }); 380 article.dispatchEvent(contentAddedEvent); 381 382 // å°ãé å»¶ãã¦ãããapp.jsãèªååæåããã®ãå¾ ã¤ 383 // app.jsãMutationObserverã使ã£ã¦ããå¯è½æ§ããããã 384 setTimeout(() => {
385 // ããã§ãåæåããã¦ããªãå ´åã¯æåã§è©¦ã¿ã 386 const moduleElements = article.querySelectorAll('[data-module]'); 387 moduleElements.forEach(element => { 388 const moduleName = element.getAttribute('data-module'); 389 390 // ãã§ã«åæåããã¦ããããã§ãã¯ï¼Splideã®å ´åï¼ 391 if (moduleName === 'ArticleSlide' && element.classList.contains('is-initialized')) { return; 392 } 393 // ã°ãã¼ãã«ã«åæå颿°ãåå¨ããã°ãããå¼ã¶ 394 if (typeof window.initModule === 'function') { window.initModule(element, moduleName); 395 } 396 // ã¾ãã¯ãã¢ã¸ã¥ã¼ã«åã«åºã¥ãã¦åå¥ã«åæå 397 else { this.initializeModuleByName(element, moduleName); 398 } 399 }); 400 }, 100); // 100mså¾ æ© 401 } 402 403 /** 404 * ç®æ¬¡ï¼Table of Contentsï¼ãããã¯ã®åæå 405 * ç¡éã¹ã¯ãã¼ã«ã§è¿½å ãããè¨äºå ã®è¦åºãã«IDãä»ä¸ãã 406 * ç®æ¬¡ãªã³ã¯ã®ã¹ã ã¼ã¹ã¹ã¯ãã¼ã«ãè¨å®ãã 407 * 408 * @param {HTMLElement} article - æ°ãã追å ãããè¨äºè¦ç´ 409 */ 410 initTableOfContents(article) { 411 const tocBlock = article.querySelector('.b-toc'); 412 if (!tocBlock) return; 413 414 // è¨äºå ã®ã³ã³ãã³ãã¨ãªã¢ãåå¾ 415 const content = article.querySelector('.entry-content, .wp-block-post-content, .p-detail__main, main'); 416 if (!content) return; 417 418 // è¦åºããåå¾ï¼ç®æ¬¡ãããã¯å ã®è¦åºãã¯é¤å¤ï¼ 419 const headings = content.querySelectorAll('h2, h3'); 420 let h2Index = 0; 421 let h3Index = 0; 422
423 headings.forEach(function(heading) { 424 if (heading.closest('.b-toc')) return; 425 426 let id; 427 if (heading.tagName === 'H2') { 428 h2Index++; 429 h3Index = 0; 430 id = 'content' + String(h2Index).padStart(2, '0'); 431 } else if (heading.tagName === 'H3') { 432 h3Index++; 433 id = 'content' + String(h2Index).padStart(2, '0') + '-' + String(h3Index).padStart(2, '0'); 434 } 435 436 // è¦åºããå«ã親ã»ã¯ã·ã§ã³ã«IDãä»ä¸ 437 const parentSection = heading.closest('section, .section'); 438 if (parentSection && !parentSection.id) { 439 parentSection.id = id; 440 } else if (!parentSection) { 441 if (!heading.id) { 442 heading.id = id; 443 } 444 } 445 }); 446 447 // ç®æ¬¡ãªã³ã¯ã«ã¹ã ã¼ã¹ã¹ã¯ãã¼ã«ãè¨å® 448 const tocLinks = tocBlock.querySelectorAll('.b-toc__item a[href^="#"]'); 449 tocLinks.forEach(function(link) { 450 link.addEventListener('click', function(e) { 451 const href = this.getAttribute('href'); 452 if (!href || href === '#') return; 453 454 const targetId = href.substring(1); 455 // åãè¨äºå ã®è¦ç´ ãæ¤ç´¢ 456 const targetElement = article.querySelector('#' + targetId); 457 458 if (targetElement) { 459 e.preventDefault(); 460 targetElement.scrollIntoView({ 461 behavior: 'smooth', 462 block: 'start' 463 }); 464 } 465 }); 466 }); 467 } 468 469 /** 470 * ã¢ã¸ã¥ã¼ã«åã«åºã¥ãã¦åå¥ã«åæå 471 * 472 * @param {HTMLElement} element 473 * @param {string} moduleName 474 */ 475 initializeModuleByName(element, moduleName) { 476 // app.jsã®ã¢ã¸ã¥ã¼ã«ã¯ã©ã¹ãã°ãã¼ãã«ããåå¾ãã¦ä½¿ç¨ 477 const moduleClasses = window.moduleClasses || {}; 478 479 // app.jsã®ã¯ã©ã¹ãåå¨ããå ´åã¯ãããä½¿ç¨ 480 if (moduleClasses[moduleName]) { 481 try { 482 new moduleClasses[moduleName](element); 483 return; 484 } catch (error) { 485 console.error(`Failed to initialize ${moduleName} with app.js class:`, error); 486 // ãã©ã¼ã«ããã¯ã¨ãã¦å¾æ¥ã®åæåã試ã¿ã 487 } 488 } 489 490 // ãã©ã¼ã«ããã¯: ç´æ¥åæå 491 switch (moduleName) { 492 case 'CardSlide': 493 this.initSwiper(element); 494 break; 495 case 'ArticleSlide': 496 this.initSplide(element); 497 break; 498 case 'InlineModal': 499 this.initInlineModal(element); 500 break; 501 case 'VisualAccordion': 502 this.initVisualAccordion(element); 503 break; 504 case 'TagSlide': 505 case 'TagSlide02': 506 case 'TopMvSlide': 507 case 'TabSlide': 508 case 'EditSlide': 509 case 'PicksSlide': 510 case 'ThumbSlide': 511 case 'SpSlide': 512 case 'AllSlide': 513 case 'PickupSlide': 514 this.initSlick(element); 515 break; 516 default: } 517 } 518 519 /** 520 * Swiper ã®åæå 521 * 522 * @param {HTMLElement} element 523 */ 524 initSwiper(element) { 525 // Swiper v11 ã®ã°ãã¼ãã«å¤æ°ãç¢ºèª 526 const SwiperClass = window.Swiper || Swiper; 527 if (typeof SwiperClass !== 'undefined') { 528 try { 529 const swiper = new SwiperClass(element, { 530 slidesPerView: 'auto', 531 spaceBetween: 0, 532 freeMode: true, 533 navigation: { 534 nextEl: element.querySelector('.swiper-button-next'), 535 prevEl: element.querySelector('.swiper-button-prev'), 536 }, 537 }); } catch (error) { 538 console.error('Swiper initialization failed:', error); 539 } 540 } else { 541 console.warn('Swiper library not found'); 542 } 543 } 544 545 /** 546 * Splide ã®åæå 547 * 548 * @param {HTMLElement} element 549 */ 550 initSplide(element) { 551 // Splide ã®ã°ãã¼ãã«å¤æ°ãç¢ºèª 552 const SplideClass = window.Splide || (typeof Splide !== 'undefined' ? Splide : null); 553 if (SplideClass === null) { 554 console.warn('Splide library not found'); 555 return; 556 } 557 558 try { 559 // ã¡ã¤ã³ã¹ã©ã¤ãã®è¦ç´ ãåå¾ (ãµã ãã¤ã«ã®Splideãé¤ã) 560 const mainSplideEl = element.querySelector('.splide:not(.b-article--thumb__splide)'); 561 // ãµã ãã¤ã«ã¹ã©ã¤ãã®è¦ç´ ãåå¾ 562 const thumbSplideEl = element.querySelector('.b-article--thumb__splide'); 563 const hasThumbnail = !!thumbSplideEl; 564 565 if (!mainSplideEl) { 566 console.warn('Main splide element not found in ArticleSlide'); 567 return; 568 } 569 570 // ã¹ã©ã¤ãå ã®ç»åããã¹ã¦åå¾ 571 const images = mainSplideEl.querySelectorAll('img'); 572 const imagePromises = Array.from(images).map(img => { 573 if (img.complete) { 574 return Promise.resolve(); 575 } 576 return new Promise((resolve, reject) => { 577 img.addEventListener('load', resolve); 578 img.addEventListener('error', resolve); // ã¨ã©ã¼ã§ãç¶è¡ 579 // ã¿ã¤ã ã¢ã¦ãè¨å®ï¼5ç§ï¼ 580 setTimeout(resolve, 5000); 581 }); 582 }); 583 584 // ãã¹ã¦ã®ç»åèªã¿è¾¼ã¿å®äºãå¾ ã£ã¦ããSplideãåæå 585 Promise.all(imagePromises).then(() => {
586 // ã¡ã¤ã³ã¹ã©ã¤ãã®ãªãã·ã§ã³ (app.js ã® ArticleSlide ã¨åãè¨å®) 587 const mainOptions = { 588 type: 'loop', 589 autoplay: false, 590 speed: 500, 591 pagination: false, 592 arrows: true, 593 autoHeight: true 594 }; 595 596 // ã¡ã¤ã³ã¹ã©ã¤ãã®åæå 597 const splideMain = new SplideClass(mainSplideEl, mainOptions); 598 599 // ãµã ãã¤ã«ãããå ´å 600 if (hasThumbnail) { 601 // ãµã ãã¤ã«ã¹ã©ã¤ãã®ãªãã·ã§ã³ (app.js ã¨åãè¨å®) 602 const thumbOptions = { 603 type: 'loop', 604 rewind: true, 605 autoWidth: true, 606 pagination: false, 607 arrows: false, 608 isNavigation: true, 609 focus: '0', 610 breakpoints: { 611 767: { 612 perPage: 3 613 } 614 } 615 }; 616 617 // ãµã ãã¤ã«ã¹ã©ã¤ãã®åæåã¨åæ 618 const splideThumb = new SplideClass(thumbSplideEl, thumbOptions); 619 splideMain.sync(splideThumb); 620 splideThumb.mount(); 621 } 622 623 splideMain.mount(); 624 625 // mountå¾ã«è¤æ°årefreshãå®è¡ãã¦ç¢ºå®ã«é«ããåè¨ç® 626 const refreshSplide = () => { 627 if (splideMain && typeof splideMain.refresh === 'function') { 628 splideMain.refresh(); 629 } 630 }; 631 632 // 段éçã«refreshãå®è¡ 633 setTimeout(refreshSplide, 100); 634 setTimeout(refreshSplide, 300); 635 setTimeout(refreshSplide, 500); 636 637 // ã¢ãã¼ä½ç½®ãæåã§èª¿æ´ 638 const adjustArrows = () => { 639 const activeSlide = mainSplideEl.querySelector('.splide__slide.is-active'); 640 const mainImage = activeSlide ? activeSlide.querySelector('.b-article--slide__img') : null; 641 const prevArrow = element.querySelector('.splide__arrow--prev'); 642 const nextArrow = element.querySelector('.splide__arrow--next'); 643 644 if (mainImage && prevArrow && nextArrow) { 645 const imgHeight = mainImage.offsetHeight; 646 const imgTopOffset = mainImage.offsetTop; 647 const arrowOffset = prevArrow.offsetHeight / 2; 648 const newTop = imgTopOffset + (imgHeight / 2) - arrowOffset; 649 650 prevArrow.style.top = `${newTop}px`; 651 nextArrow.style.top = `${newTop}px`; 652 } 653 }; 654 655 // ã¢ãã¼ä½ç½®èª¿æ´ã段éçã«å®è¡ 656 setTimeout(adjustArrows, 150); 657 setTimeout(adjustArrows, 350); 658 setTimeout(adjustArrows, 550); 659 }); 660 } catch (error) { 661 console.error('Splide initialization failed:', error); 662 } 663 } 664 665 666 /** 667 * Slick ã®åæå 668 * 669 * @param {HTMLElement} element 670 */ 671 initSlick(element) { if (typeof jQuery !== 'undefined' && typeof jQuery.fn.slick !== 'undefined') { 672 try { 673 jQuery(element).slick({ 674 slidesToShow: 1, 675 slidesToScroll: 1, 676 arrows: true, 677 dots: false, 678 infinite: true, 679 }); } catch (error) { 680 console.error('Slick initialization failed:', error); 681 } 682 } else { 683 console.warn('Slick library not found'); 684 } 685 } 686 687 /** 688 * InlineModal ã®åæå 689 * app.jsã®ã°ãã¼ãã«ãªã¹ãã¼ã¯æ¢ã«ç»é²æ¸ã¿ã¨æ³å®ãã 690 * æ°ããããªã¬ã¼ãã¿ã³ã«å¯¾ãã¦ã®ã¿clickã¤ãã³ãã追å 691 * 692 * @param {HTMLElement} element - .js-InlineModal-btn è¦ç´ 693 */ 694 initInlineModal(element) { 695 try { 696 const modalId = element.dataset.modalOpen; 697 const group = element.dataset.modalGroup; 698 let groupModals = []; 699 700 if (group) { 701 groupModals = document.querySelectorAll( 702 `.js-InlineModal-wrapper[data-modal-group="${group}"]` 703 ); 704 } 705 706 // clickã¤ãã³ãã追å ï¼app.jsã®InlineModal.open()ãå¼ã³åºãæ³å®ï¼ 707 element.addEventListener('click', (e) => { 708 e.preventDefault(); 709 710 // app.jsã®InlineModalãå©ç¨å¯è½ãªå ´åã¯ãããä½¿ç¨ 711 if (typeof window.InlineModal !== 'undefined' && typeof window.InlineModal.open === 'function') { 712 window.InlineModal.open(modalId, groupModals); 713 } else { 714 // ãã©ã¼ã«ããã¯: ã·ã³ãã«ãªã¢ã¼ãã«è¡¨ç¤º 715 console.warn('InlineModal from app.js not found, using fallback'); 716 const targetModal = document.querySelector(`.js-InlineModal-wrapper[data-modal="${modalId}"]`); 717 if (targetModal) { 718 targetModal.classList.add('is-open'); 719 document.body.style.overflow = 'hidden'; 720 } 721 } 722 }); } catch (error) { 723 console.error('InlineModal initialization failed:', error); 724 } 725 } 726
727 /** 728 * VisualAccordion ã®åæå 729 * HTMLããã¸ã§ã¯ãã®VisualAccordion.jsãåèã«å®è£ 730 * 731 * @param {HTMLElement} rootElement - data-module="VisualAccordion"ãæã¤è¦ç´ 732 */ 733 initVisualAccordion(rootElement) { 734 try { 735 const isOpenClass = 'is-open'; 736 const isFadingClass = 'is-fading'; 737 const FADE_DURATION = 200; // ms 738 const SLIDE_DURATION = 300; // ms 739 740 const mainVisualImg = rootElement.querySelector('.js-main-visual'); 741 const visualLink = rootElement.querySelector('.js-visual-link'); 742 const triggers = rootElement.querySelectorAll('.js-toggle-trigger'); 743 const allItems = rootElement.querySelectorAll('[data-img-src]'); 744 const firstItem = allItems[0]; 745 746 let initialImageSrc = ''; 747 let initialLinkHref = '#'; 748 749 // ãããã¼è¦ç´ ã®æç¡ããã§ã㯠750 const hasHeader = rootElement.querySelector('.b-accordion__header'); 751 752 // åæå¤ã®åå¾ 753 if (rootElement.dataset.initialImgSrc) { 754 initialImageSrc = rootElement.dataset.initialImgSrc; 755 initialLinkHref = rootElement.dataset.initialLinkHref || '#'; 756 } else if (firstItem) { 757 initialImageSrc = firstItem.dataset.imgSrc || ''; 758 initialLinkHref = firstItem.dataset.href || '#'; 759 } 760 761 // ãã¸ã¥ã¢ã«æ´æ°é¢æ° 762 const updateVisual = (newSrc, newHref) => { 763 const imgContainer = mainVisualImg ? mainVisualImg.parentNode : null; 764 if (mainVisualImg && newSrc && imgContainer) { 765 imgContainer.classList.add(isFadingClass); 766 setTimeout(() => { 767 mainVisualImg.src = newSrc; 768 if (visualLink) { 769 visualLink.href = newHref; 770 } 771 imgContainer.classList.remove(isFadingClass); 772 }, FADE_DURATION); 773 } 774 }; 775 776 // ã¹ã©ã¤ããã¦ã³é¢æ° 777 const slideDown = (el) => { 778 el.style.removeProperty('display'); 779 let display = window.getComputedStyle(el).display; 780 if (display === 'none') display = 'block'; 781 el.style.display = display; 782 let height = el.scrollHeight; 783 784 el.style.overflow = 'hidden'; 785 el.style.height = 0; 786 el.style.paddingTop = 0; 787 el.style.paddingBottom = 0; 788 el.style.marginTop = 0; 789 el.style.marginBottom = 0; 790 791 el.offsetHeight; // reflow 792 793 el.style.transitionProperty = 'height, margin, padding'; 794 el.style.transitionDuration = SLIDE_DURATION + 'ms'; 795 el.style.transitionTimingFunction = 'ease'; 796 el.style.height = height + 'px'; 797 798 setTimeout(() => { 799 el.style.removeProperty('height'); 800 el.style.removeProperty('overflow'); 801 el.style.removeProperty('transition-duration'); 802 el.style.removeProperty('transition-property'); 803 el.style.removeProperty('transition-timing-function'); 804 el.style.removeProperty('padding-top'); 805 el.style.removeProperty('padding-bottom'); 806 el.style.removeProperty('margin-top'); 807 el.style.removeProperty('margin-bottom'); 808 }, SLIDE_DURATION); 809 }; 810 811 // ã¹ã©ã¤ãã¢ãã颿° 812 const slideUp = (el) => { 813 el.style.height = el.offsetHeight + 'px'; 814 el.offsetHeight; // reflow 815 el.style.transitionProperty = 'height, margin, padding'; 816 el.style.transitionDuration = SLIDE_DURATION + 'ms'; 817 el.style.transitionTimingFunction = 'ease'; 818 el.style.overflow = 'hidden'; 819 el.style.height = 0; 820 el.style.paddingTop = 0; 821 el.style.paddingBottom = 0; 822 el.style.marginTop = 0; 823 el.style.marginBottom = 0; 824 825 setTimeout(() => { 826 el.style.display = 'none'; 827 el.style.removeProperty('height'); 828 el.style.removeProperty('padding-top'); 829 el.style.removeProperty('padding-bottom'); 830 el.style.removeProperty('margin-top'); 831 el.style.removeProperty('margin-bottom'); 832 el.style.removeProperty('overflow'); 833 el.style.removeProperty('transition-duration'); 834 el.style.removeProperty('transition-property'); 835 el.style.removeProperty('transition-timing-function'); 836 }, SLIDE_DURATION); 837 }; 838 839 // ã¢ã³ã¼ãã£ãªã³ãéã 840 const openAccordion = (item) => { 841 const content = item.querySelector('.js-toggle-content'); 842 if (!content) return; 843 844 const newSrc = item.dataset.imgSrc; 845 const newHref = item.dataset.href || '#'; 846 847 updateVisual(newSrc, newHref); 848 slideDown(content); 849 item.classList.add(isOpenClass); 850 }; 851 852 // ã¢ã³ã¼ãã£ãªã³ãéãã 853 const closeAccordion = (item) => { 854 const content = item.querySelector('.js-toggle-content'); 855 if (!content) return; 856 857 slideUp(content); 858 item.classList.remove(isOpenClass); 859 }; 860 861 // å ¨ã¦éãã¦ããããã§ã㯠862 const checkAllClosed = () => { 863 const openItems = rootElement.querySelectorAll(`.${isOpenClass}`); 864 if (openItems.length === 0) { 865 updateVisual(initialImageSrc, initialLinkHref); 866 } 867 }; 868 869 // ã¤ãã³ããªã¹ãã¼è¨å®
870 triggers.forEach(trigger => { 871 trigger.addEventListener('click', (event) => { 872 event.preventDefault(); 873 874 const currentItem = trigger.closest('[data-img-src]'); 875 if (!currentItem) return; 876 877 const isCurrentlyOpen = currentItem.classList.contains(isOpenClass); 878 879 // ä»ã®ã¢ã¤ãã ãéãã 880 allItems.forEach(item => { 881 if (item !== currentItem) { 882 closeAccordion(item); 883 } 884 }); 885 886 // ç¾å¨ã®ã¢ã¤ãã ã®éé 887 if (isCurrentlyOpen) { 888 closeAccordion(currentItem); 889 } else { 890 openAccordion(currentItem); 891 } 892 893 checkAllClosed(); 894 }); 895 }); 896 897 // åæç¶æ è¨å®ï¼ãããã¼ããªãããã¤ãªã¹ãã¢ã¤ãã ãåå¨ããå ´åãæåã®ã¢ã¤ãã ãèªåã§éã 898 if (!hasHeader && firstItem) { 899 openAccordion(firstItem); 900 } else { 901 updateVisual(initialImageSrc, initialLinkHref); 902 } } catch (error) { 903 console.error('VisualAccordion initialization failed:', error); 904 } 905 } 906 907 908 /** 909 * è¨äºããã¥ã¼ãã¼ãã«å ¥ã£ããURLæ´æ° 910 * 911 * @param {HTMLElement} article 912 */ 913 observeArticleForUrlUpdate(article) { 914 // è¨äºä¸é¨ç£è¦ç¨ã®Observerã使ï¼å ±æï¼ 915 if (!this.articleObserver) { 916 this.articleObserver = new IntersectionObserver( 917 (entries) => this.handleArticleIntersection(entries), 918 { 919 root: null, 920 rootMargin: '0px', 921 threshold: 0 // è¨äºã1pxã§ãç»é¢ã«å ¥ã£ããURLæ´æ° 922 } 923 ); 924 } 925 926 this.articleObserver.observe(article); 927 } 928 929 /** 930 * è¨äºã®å¯è¦æ§å¤åãå¦çï¼URLæ´æ°ï¼ 931 * 932 * @param {IntersectionObserverEntry[]} entries 933 */ 934 handleArticleIntersection(entries) { 935 // ã¹ã¯ãã¼ã«æã¨åããã¸ãã¯ãå®è¡ 936 this.updateCurrentArticleUrl(); 937 } 938 939 /** 940 * ã¹ã¯ãã¼ã«ã¤ãã³ããã³ãã©ã¼ï¼throttleä»ãï¼ 941 */ 942 handleScroll() { 943 const now = Date.now(); 944 if (now - this.lastScrollTime < this.scrollThrottle) { 945 return; 946 } 947 this.lastScrollTime = now; 948 this.updateCurrentArticleUrl(); 949 } 950 951 /** 952 * ç¾å¨ç»é¢ä¸ç«¯ã«æãè¿ãè¨äºã®URLã«æ´æ° 953 */ 954 updateCurrentArticleUrl() { 955 // ç»é¢å ã®ãã¹ã¦ã®è¨äºãåå¾ãã¦ãæãä¸ã«ããè¨äºãç¹å® 956 const allArticles = document.querySelectorAll('.p-detail'); 957 let topMostArticle = null; 958 let topMostPosition = Infinity; 959 960 allArticles.forEach((article, index) => { 961 const rect = article.getBoundingClientRect(); 962 963 // ç»é¢å ã«ããè¨äºï¼ä¸ç«¯ãç»é¢ä¸ç«¯ããä¸ãä¸ç«¯ãç»é¢ä¸ç«¯ããä¸ï¼ 964 if (rect.top < window.innerHeight && rect.bottom > 0) { 965 // ç»é¢ä¸ç«¯ã«æãè¿ãè¨äºã鏿 966 const distanceFromTop = Math.abs(rect.top); 967 if (distanceFromTop < topMostPosition) { 968 topMostPosition = distanceFromTop; 969 topMostArticle = article; 970 } 971 } 972 }); 973 974 // æãä¸ã«ããè¨äºã®URLã«æ´æ° 975 if (topMostArticle) { 976 const url = topMostArticle.dataset.url; 977 const title = topMostArticle.dataset.title; 978 979 if (url) { 980 this.updateUrl(url, title, topMostArticle); 981 } 982 } 983 } 984 985 /** 986 * URLã¨ã¡ã¿æ å ±ãæ´æ° 987 * 988 * @param {string} url - è¨äºURL 989 * @param {string} title - è¨äºã¿ã¤ãã« 990 * @param {HTMLElement} article - è¨äºè¦ç´ 991 */ 992 updateUrl(url, title, article) { 993 // related=true ãã©ã¡ã¼ã¿ã追å ï¼2è¨äºç®ä»¥éï¼ 994 const articleIndex = Array.from(document.querySelectorAll('.p-detail')).indexOf(article); 995 let newUrl = url; 996 997 if (articleIndex > 0) { 998 // 2è¨äºç®ä»¥é㯠?related=true ã追å 999 newUrl = url + (url.includes('?') ? '&' : '?') + 'related=true'; 1000 } 1001 1002 // ç¾å¨ã®URLã¨åãå ´åã¯æ´æ°ããªã 1003 if (window.location.href === newUrl) { 1004 return; 1005 } 1006 1007 // 2è¨äºç®ä»¥éã®å ´åï¼ç¾è¡ãµã¤ã仿§ã«æºæ ï¼dataLayer â URLæ´æ° â gtmRelatedPageï¼ 1008 if (articleIndex > 0) { 1009 // 1. dataLayerã«cxenseãã¼ã¿ç¸å½ãpush 1010 this.pushDataLayer(article); 1011 1012 // 2. URLãæ´æ°ï¼å±¥æ´ãç½®ãæãï¼ 1013 window.history.replaceState( 1014 { path: newUrl }, 1015 '', 1016 newUrl 1017 ); 1018 1019 // 3. ã¿ã¤ãã«ãæ´æ° 1020 if (title) { 1021 document.title = title; 1022 } 1023 1024 // 4. ã¡ã¿ã¿ã°ãæ´æ° 1025 this.updateMetaTags(article); 1026 1027 // 5. gtmRelatedPageã¤ãã³ããéä¿¡ 1028 window.dataLayer = window.dataLayer || []; 1029 window.dataLayer.push({ 1030 'event': 'gtmRelatedPage', 1031 'page_location': newUrl, 1032 'page_title': title || document.title 1033 }); 1034 1035 console.log('gtmRelatedPage event pushed:', newUrl); 1036 } else { 1037 // 1è¨äºç®ï¼ã©ã³ãã£ã³ã°è¨äºï¼ã®å ´åï¼ã¤ãã³ãéä¿¡ãªã 1038 window.history.replaceState( 1039 { path: newUrl }, 1040 '', 1041 newUrl 1042 ); 1043 1044 if (title) { 1045 document.title = title; 1046 } 1047 1048 this.updateMetaTags(article); 1049 } 1050 } 1051 1052 /** 1053 * ã¡ã¿ã¿ã°ãæ´æ° 1054 * 1055 * @param {HTMLElement} article 1056 */ 1057 updateMetaTags(article) { 1058 const description = article.dataset.metaDescription; 1059 const ogImage = article.dataset.metaOgImage; 1060 const title = article.dataset.title; 1061 const url = article.dataset.url; 1062 1063 // description 1064 if (description) { 1065 let metaDesc = document.querySelector('meta[name="description"]'); 1066 if (metaDesc) { 1067 metaDesc.setAttribute('content', description); 1068 } 1069 1070 let ogDesc = document.querySelector('meta[property="og:description"]'); 1071 if (ogDesc) { 1072 ogDesc.setAttribute('content', description); 1073 } 1074 } 1075 1076 // og:image 1077 if (ogImage) { 1078 let ogImageTag = document.querySelector('meta[property="og:image"]'); 1079 if (ogImageTag) { 1080 ogImageTag.setAttribute('content', ogImage); 1081 } 1082 } 1083 1084 // og:title 1085 if (title) { 1086 let ogTitle = document.querySelector('meta[property="og:title"]'); 1087 if (ogTitle) { 1088 ogTitle.setAttribute('content', title); 1089 } 1090 } 1091 1092 // og:urlï¼1è¨äºç®ã¯å ã®URLã2è¨äºç®ä»¥éã¯related=trueä»ãï¼ 1093 if (url) { 1094 let ogUrl = document.querySelector('meta[property="og:url"]'); 1095 if (ogUrl) { 1096 const articleIndex = Array.from(document.querySelectorAll('.p-detail')).indexOf(article); 1097 let newUrl = url; 1098 if (articleIndex > 0) { 1099 newUrl = url + (url.includes('?') ? '&' : '?') + 'related=true'; 1100 } 1101 ogUrl.setAttribute('content', newUrl); 1102 } 1103 } 1104 } 1105 1106 /**
1107 * dataLayerã«ãã¼ã¿ãéä¿¡ 1108 * 1109 * @param {HTMLElement} article 1110 */ 1111 pushDataLayer(article) { 1112 try { 1113 const datalayerJson = article.dataset.datalayer; 1114 if (!datalayerJson) { 1115 return; 1116 } 1117 1118 const datalayerData = JSON.parse(datalayerJson); 1119 1120 // window.dataLayerãåå¨ããªãå ´åã¯åæå 1121 window.dataLayer = window.dataLayer || []; 1122 1123 // dataLayerã«push 1124 window.dataLayer.push(datalayerData); 1125 1126 console.log('dataLayer pushed:', datalayerData); 1127 } catch (error) { 1128 console.error('Error pushing dataLayer:', error); 1129 } 1130 } 1131 } 1132 1133 // åæå颿° 1134 function init() { 1135 // æç¨¿è©³ç´°ãã¼ã¸ã®ã¿å®è¡ 1136 if (document.body.classList.contains('single-post') || document.body.classList.contains('single')) { 1137 new InfiniteScroll(); 1138 } 1139 } 1140 1141 // DOMèªã¿è¾¼ã¿å®äºå¾ã«åæå 1142 if (document.readyState === 'loading') { 1143 // ã¾ã èªã¿è¾¼ã¿ä¸ã®å ´åã¯ã¤ãã³ããªã¹ãã¼ç»é² 1144 document.addEventListener('DOMContentLoaded', init); 1145 } else { 1146 // æ¢ã«èªã¿è¾¼ã¿å®äºãã¦ããå ´åã¯å³åº§ã«å®è¡ 1147 init(); 1148 } 1149 1150})();
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.