document.addEventListener('DOMContentLoaded', () => { const stickyElement = document.getElementById('moveitem'); const container = stickyElement.closest('.movearea'); const stopElement = document.querySelector('.bgContent02'); if (!stickyElement || !container || !stopElement) return; const stickyHeight = stickyElement.offsetHeight; const FIX_TARGET_Y = window.innerHeight * 0.5; const INITIAL_TOP_OFFSET = 90; const ADJUSTMENT_OFFSET = 140; const ADJUSTMENT_OFFSET02 = 800; let initialLeftPosition; let START_Y_ABS; let END_Y_ABS; let lastWidth = window.innerWidth; const calculatePositions = () => { const wasFixed = stickyElement.classList.contains('is-fixed'); const wasAbsoluteEnd = stickyElement.classList.contains('is-absolute-end'); stickyElement.classList.remove('is-fixed', 'is-absolute-end'); stickyElement.style.left = ''; stickyElement.style.right = ''; stickyElement.style.top = ''; stickyElement.style.bottom = ''; START_Y_ABS = container.getBoundingClientRect().top + window.scrollY + INITIAL_TOP_OFFSET + ADJUSTMENT_OFFSET; END_Y_ABS = stopElement.getBoundingClientRect().top + window.scrollY - stickyHeight + ADJUSTMENT_OFFSET02; initialLeftPosition = stickyElement.getBoundingClientRect().left; if (wasFixed) stickyElement.classList.add('is-fixed'); if (wasAbsoluteEnd) stickyElement.classList.add('is-absolute-end'); applyState(); }; const applyState = () => { const currentScrollY = window.scrollY; const START_THRESHOLD = START_Y_ABS - FIX_TARGET_Y; const END_THRESHOLD = END_Y_ABS - FIX_TARGET_Y; if (currentScrollY >= START_THRESHOLD && currentScrollY < END_THRESHOLD) { stickyElement.classList.add('is-fixed'); stickyElement.classList.remove('is-absolute-end'); stickyElement.style.left = `${initialLeftPosition}px`; stickyElement.style.right = 'auto'; } else if (currentScrollY >= END_THRESHOLD) { stickyElement.classList.add('is-absolute-end'); } else { stickyElement.classList.remove('is-fixed'); stickyElement.classList.remove('is-absolute-end'); stickyElement.style.left = ''; stickyElement.style.right = ''; stickyElement.style.top = ''; stickyElement.style.bottom = ''; } }; const throttle = (func, limit) => { let inThrottle; return function() { const context = this; const args = arguments; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } } } const debounce = (func, delay) => { let timeoutId; return function() { const context = this; const args = arguments; clearTimeout(timeoutId); timeoutId = setTimeout(() => { func.apply(context, args); }, delay); }; }; const reloadPage = () => { const currentWidth = window.innerWidth; // 1. 横幅が960px以下なら何もしない if (currentWidth <= 960) { lastWidth = currentWidth; return; } // 2. 横幅が以前と変わっている場合のみリロードする // これにより、スマホのスクロール(高さ変更)によるリロードを防ぎます if (currentWidth !== lastWidth) { window.location.reload(); } // 最後に現在の幅を保存 lastWidth = currentWidth; }; window.addEventListener('scroll', throttle(applyState, 16)); window.addEventListener('resize', debounce(reloadPage, 300)); calculatePositions(); });