スマートフォンでページの途中でモーダルメニューを開閉したときにページ内での位置を保持して再表示させる方法。
※コード内でスクロール位置を先に取得して保存させないと、cssのスタイルが先に実行されて「top: 0px」になってしまい、メニューの開閉でページトップに戻されてしまう。
動作OKのコード(scrollアニメ表示版があります)
const trigger = document.querySelector('.globalMenu');
const body = document.body;
const modal = document.getElementById('globalNavArea');
let scrollPosition = 0;
const toggleNav = () => {
const isOpening = !trigger.classList.contains('is-active'); // 開くかどうかを事前に判定
if (isOpening) {
scrollPosition = window.scrollY; // スクロール位置を先に取得
console.log('保存する scrollPosition:', scrollPosition);
}
const isActive = trigger.classList.toggle('is-active');
body.classList.toggle('is-nav-opened', isActive);
body.classList.toggle('is-nav-close', !isActive);
if (isActive) {
body.style.top = `-${scrollPosition}px`;
modal.scrollTop = 0;
} else {
body.style.top = '';
window.scrollTo(0, scrollPosition);
}
};
trigger.addEventListener('click', toggleNav);
こちらはモーダルウィンドウメニューを開いたときにscrollアニメを5秒間表示させるスクリプト
※メニュー開閉時のページ位置保持も修正されています
// 読み込み完了するまでグローバルメニューを非表示にする
// style.cssで「#globalNav」をdisplay: none;にしておく
window.onload = function () {
document.getElementById('globalNav').style.display = 'block';
// スマホ グローバルメニュー(メニューを開くと5秒間scrollアニメを表示する) ----
const trigger = document.querySelector('.globalMenu');
const body = document.body;
const modal = document.getElementById('globalNavArea');
const scrollNotice = document.querySelector('.sp_block.gnScroll');
let scrollPosition = 0;
let fadeOutTimer = null;
let hideTimer = null;
const toggleNav = () => {
const isOpening = !trigger.classList.contains('is-active');
if (isOpening) {
scrollPosition = window.scrollY;
console.log('保存する scrollPosition:', scrollPosition);
}
const isActive = trigger.classList.toggle('is-active');
body.classList.toggle('is-nav-opened', isActive);
body.classList.toggle('is-nav-close', !isActive);
if (isActive) {
// スクロールを止める
body.style.position = 'fixed';
body.style.top = `-${scrollPosition}px`;
body.style.left = '0';
body.style.right = '0';
modal.scrollTop = 0;
clearTimeout(fadeOutTimer);
clearTimeout(hideTimer);
if (scrollNotice) {
scrollNotice.style.display = 'block';
scrollNotice.classList.remove('fade-out');
fadeOutTimer = setTimeout(() => {
scrollNotice.classList.add('fade-out');
}, 5000);
hideTimer = setTimeout(() => {
scrollNotice.style.display = 'none';
scrollNotice.classList.remove('fade-out');
}, 5500);
}
} else {
// スクロールを戻す
body.style.position = '';
body.style.top = '';
body.style.left = '';
body.style.right = '';
window.scrollTo(0, scrollPosition);
clearTimeout(fadeOutTimer);
clearTimeout(hideTimer);
if (scrollNotice) {
scrollNotice.style.display = 'none';
scrollNotice.classList.remove('fade-out');
}
}
};
trigger.addEventListener('click', toggleNav);