@antimodern

Эффективной блокировки скролла (при этом без смещений) не существует?

Господа, я просто затрахался искать силвер буллит.
Видимо он не существует? Похоже на какой-то заговор.

Я уже сбился со счета сколько способов блокировки скролла при открытии модалки. при этом без смещений контента экрана я перепробовал. Все они оказались говном. Сегодняшний баг, когда одна из методик поломала Intersection Observer (лолшто?? как эти вещи связаны, да?) был последней каплей.

Требования:
1. блокировка скролла
2. отсутсвие смещений контента страницы, включая fixed элементы
3. оверлей должен быть не на весь экран, а учитывать место скроллбара (в идеале - нативный disabled scrollbar)

Резюмируя, наиболее эффективными способы я для себя выделил следующие:

1. Классика. На боди цепляем оверфлоу hidden. Изи фикс же! И на сдачу получаем смещение всей страницы на место исчезнувшего скролла. Вы такие наверное щас, лул, нубас какой, а мы же умные, вычисляем размер скроллбара в браузере и добавляем маржин/паддинг на его место ёпта! Вы гениальны скажу я Вам в ответ, но это не поможет к fixed элементам страницы. Для того чтобы они не смещались нужно к каждому fixed элементу добавить этот чертов марджин/паддинг. Но вы наверное умные, и можете предложить вариант всем fixed элементам добавлять определенный класс в момент верстки, и потом находить все эти элементы и всем им добавлять этот чертов марджин/паддинг. Вариант хороший, отвечу я вам. Но что делать с самим fixed фуллскрин оверлеем, который все равно будет вылазить на весь экран, включая место скроллбара (там, если вы еще со мной, если помните теперь вместо него марджин/паддинг, иммитирующий его наличие)??? Вы ответа наверное не знаете, а я вот позавчера нашел (столкнувшись с багом). Вернее даже не ответ, а очередной баг/хак, который можно эксплуатировать, чтобы fixed элемент был относительно родителя, а не как положено - относитльно всего вьюпрота. Нужно вынести родитель оверлея в отдельный слой, например добавив например will-change: transform. Пи3*ец, да? Не много ли телодвижений, для какой-то примитивной задачи, с кучей непредвиденных последствий, которые непременно будут ждать вас в будущем?

UPD: пошло активное перечисление плагинов. Остановитесь!

1.1. некоторые суперпопулярные плагины для кулхацкеров используют именно этот способ https://github.com/willmcpo/body-scroll-lock (правда без самого важного о чем я спрашиваю - что делать со смещением fixed элементов страницы и как сделать чтобы оверлей не перекрывал все страницу, но если вы не умеете добавить класс на боди - этот плагин ваш выбор)

1.2 оп, вот еще один плагин вылез - https://github.com/FL3NKEY/scroll-lock Этот немного поумнее, он знает что на fixed элементы не работает трюк с паддингом/марджином на боди. Этот плагин предлагает ручками перечислить все fixed элементы. бугага. Кроме того он не решает проблему что сам оверлей будет на весь экран, не учитывая положение скроллабара (да, я ищу идеальное решение)

2. Вариант для джаваскрипт ниндзь. Добавляем на боди наш любимый оверфлоу hidden, при этом задаем ему высоту 100vh, а на html элемент фигачим overflow-y scroll. При этом получаем реально офигенный результат, тот что нужен - скроллбар блокируется, но не исчезает, на его место прилетает скролл, размером в высоту вьюпорта. Отлично, но в довесок прилетает несколько неприятностей: 1) если вызвать такую блокировку прокрутив страницу вниз, то она улетает на верх (ведь у нас страницы становится 100vh). Упс! Но вы же джаваскрипт ниндзи, мы вычисляем pageYOffset и фигачим положение top в его величину на момент отключения скролла, а потом в момент включения скролла убираем top и делаем scrollTo в это положение! Фух, миссия выполнима! Или нет? 2) А вот тут плавно перемещаемся к моей сешгодняшней последней капле. Я остановился на этом способе блокировки, т.к. внешний результат отличный. Сегодня замечены были некоторые непонятные баги с элементами на которых висит Intersection Observer и детектит когда они во вьюпорте. Все висло после отключения скроллабара. Ответ оказался прост - в момент отключения скроллбара таким способом ВСЕ элементы страницы оказываются во вьюпорте. Да что ж такое %;?№*)))

Вопрос риторический скорее, т.к. как я почти уверен - нормального, кроссбраузерного решения, которое не имеет последтсвий просто не существует. Это я еще не говорил о скролле на мобильных устройствах (сложности с отлючением ивента скролла на iOs и проклятое смещение размеров экрана в мобильных браузерах про скролле туда-сюда).

Но все же - что посоветуете? Пока что я оставновился на варианте - не блокировать вообще нафиг ничего, с меня пока хватит.
  • Вопрос задан
  • 1348 просмотров
Пригласить эксперта
Ответы на вопрос 3
@nvdfxx
Senior Pomidor developer
html {
    overflow-y: scroll
}

body {
    height: 100vh;
    overflow: hidden
}

ну еще можно стили повесить на скроллбар, чтоб прозрачным становился
Ответ написан
@alsofiev
body {
overflow: hidden;
padding-right: 15px;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
17 апр. 2024, в 00:48
35000 руб./за проект
17 апр. 2024, в 00:13
800 руб./за проект
17 апр. 2024, в 00:06
240000 руб./за проект