@Hypnos696

Как исправить скачок вверх страницы при открытии бургер-меню?

Здравствуйте.

У верхней шапки сайта задал position: fixed.
При открытии меню в любом месте на сайте, происходит скрол ("за кадром") наверх страницы.
При закрытии бургер-меню, страница скролится вниз до позиции на момент открытия меню.
Использую готовую сборку GULP с ютуба.

Бургер меню реализовано вот так:
import { disableScroll } from '../functions/disable-scroll';
import { enableScroll } from '../functions/enable-scroll';

(function(){
  const burger = document?.querySelector('[data-burger]');
  const menu = document?.querySelector('[data-menu]');
  const menuItems = document?.querySelectorAll('[data-menu-item]');
  const overlay = document?.querySelector('[data-menu-overlay]');

  burger?.addEventListener('click', (e) => {
    burger?.classList.toggle('burger--active');
    menu?.classList.toggle('menu--active');

    if (menu?.classList.contains('menu--active')) {
      burger?.setAttribute('aria-expanded', 'true');
      burger?.setAttribute('aria-label', 'Закрыть меню');
      disableScroll();
    } else {
      burger?.setAttribute('aria-expanded', 'false');
      burger?.setAttribute('aria-label', 'Открыть меню');
      enableScroll();
    }
  });

  overlay?.addEventListener('click', () => {
    burger?.setAttribute('aria-expanded', 'false');
    burger?.setAttribute('aria-label', 'Открыть меню');
    burger.classList.remove('burger--active');
    menu.classList.remove('menu--active');
    enableScroll();
  });

  menuItems?.forEach(el => {
    el.addEventListener('click', () => {
      burger?.setAttribute('aria-expanded', 'false');
      burger?.setAttribute('aria-label', 'Открыть меню');
      burger.classList.remove('burger--active');
      menu.classList.remove('menu--active');
      enableScroll();
    });
  });
})();


Отключение скрола:
import vars from '../_vars';

export const disableScroll = () => {
  const fixBlocks = document?.querySelectorAll('.fixed-block');
  const pagePosition = window.scrollY;
  const paddingOffset = `${(window.innerWidth - vars.bodyEl.offsetWidth)}px`;

  vars.htmlEl.style.scrollBehavior = 'none';
  fixBlocks.forEach(el => { el.style.paddingRight = paddingOffset; });
  vars.bodyEl.style.paddingRight = paddingOffset;
  vars.bodyEl.classList.add('dis-scroll');
  vars.bodyEl.dataset.position = pagePosition;
  vars.bodyEl.style.top = `-${pagePosition}px`;
}


Включение скрола:
import vars from '../_vars';

export const enableScroll = () => {
  const fixBlocks = document?.querySelectorAll('.fixed-block');
  const body = document.body;
  const pagePosition = parseInt(vars.bodyEl.dataset.position, 10);
  fixBlocks.forEach(el => { el.style.paddingRight = '0px'; });
  vars.bodyEl.style.paddingRight = '0px';

  vars.bodyEl.style.top = 'auto';
  vars.bodyEl.classList.remove('dis-scroll');
  window.scroll({
    top: pagePosition,
    left: 0
  });
  vars.bodyEl.removeAttribute('data-position');
  vars.htmlEl.style.scrollBehavior = 'smooth';
}


Опытным путем выяснил, что проблема возникает из-за свойства position: fixed, которое задается для body при отключении скрола, через класс:
.dis-scroll {
  position: fixed;
  left: 0;
  top: 0;
  overflow: hidden;
  width: 100%;
  height: 100vh;
  overscroll-behavior: none;
}


Собственно вопрос:
Как исправить данный момент?
Если убрать position: fixed, то ничего не ломается и все ок.
Но оно же там не просто так.
Я узнал что так нужно для исправления какого то бага на ios, но не уверен.

Как исправить понятно, но как исправить правильно?
  • Вопрос задан
  • 251 просмотр
Решения вопроса 1
@Hypnos696 Автор вопроса
Нашел в чем проблема.

Во включении скрола.
Нашел ответ в комментариях к этому видео:
https://www.youtube.com/watch?v=TmVu9j7l0kI&ab_cha...

Дело в строчке
vars.htmlEl.style.scrollBehavior = 'smooth';

В видео есть объяснение почему так сделано.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы