スマホでモーダルメニューを開閉する時にページ内での位置を保持させる

Filed under: JavaScript — kdcs @ 25年10月9日 木曜日

スマートフォンでページの途中でモーダルメニューを開閉したときにページ内での位置を保持して再表示させる方法。

※コード内でスクロール位置を先に取得して保存させないと、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);

サイト内検索

カテゴリー

最近の投稿

« |スマホでモーダルメニューを開閉する時にページ内での位置を保持させる| »
↑上に戻る