Сцены
Когда на странице появляется плавающий слой, содержимое скользящего плавающего слоя обычно следует ожидать, что содержимое под плавающим слоем не будет прокручиваться, однако это не так.
решать
Сначала зашел на гитхаб поискать, и нашел, что есть пакеты с открытым исходным кодом, решающие эту проблему, и просто и грубо выбрал их напрямую.starсамый высокий (body-scroll-lock) работать! После использования обнаружил некоторые проблемы:
- Полное зависание на Android
- Иногда сторона ios не может быть заблокирована
Проверьте исходный код и обнаружите, что пакет находится вiOSконечное применение禁止touchmoveобрабатывается отдельно, но на другом конце просто даетbodyдобавлятьoverflow: hiddenПростое обращение.
Поэтому я решил написать многотерминальный общий пакет для решения подобных проблем.
Исследование 1: переполнение: скрыто
Когда вы видите прокрутку внизу, вы должны сразу думать обо всемviewportПрокрутка, то если тело установленоoverflow: hidden, содержимое тела в это время только на один экран, и оно точно не будет прокручиваться;
body { overflow: hidden; }
Это решение отлично решает нашу проблему на стороне ПК, но все не так просто;
Попробуйте еще раз на мобильном устройстве:
Исследование 2: положение тела
Я думал установить тело вышеoverflow: hiddenЭто не решает нашу проблему на мобильной стороне.Это потому, что высота тела не задана?
- Установите высоту html и тела на
100%; - Установить абсолютное позиционирование для тела (фиксированное);
Одновременное использование этих двух операций, кажется, полностью удовлетворяет наши потребности;
top值Если нет, то мы окажемся там, где захотим (насколько я умна).
советы: настройки тела
relativeПозиционирование поднимет саму страницу и оставит пустым внизу
Многие эксперименты показали, что эта схемаandroidEnd-to-end отлично достигает желаемых результатов, но вiosТерминал не идеален, каждый раз будет возникать проблема с миганием, хорошие вещи будут приходить и уходить, а затем исследовать решение на терминале ios.
Исследование 3: Запретить touchmove
Если страница заблокированаtouchmoveВозможно ли это? Нечего сказать, просто сделайте это!
Отключить элементы страницы при всплывающем окнеtouchmove
document.addEventListener('touchmove', function (event) {
event.preventDefault()
})
Тест показал, что ожидаемого эффекта не добился, считаю такой результат неприемлемым, запрещён.documentизtouchmoveНе можете остановить прокрутку?
После дальнейших изысканий выясняется, что причина именно в этом свойстве
- Передано третьим параметром пассивного addEventListener
Оказалось, что это была некоторая оптимизация, сделанная браузером.chrome passive-event-listeners
Passive Event Listenersэто новый браузер, предложенный Chromeхарактеристика: веб-разработчик через новое свойствоpassiveчтобы сообщить браузеру, будет ли вызван прослушиватель событий, зарегистрированный на текущей страницеpreventDefaultчтобы предотвратить поведение события по умолчанию, чтобы браузер мог принимать более эффективные решения на основе этой информации для оптимизации производительности страницы. когда атрибутpassiveКогда значение равно true, это означает, что слушатель не будет вызываться внутри.preventDefaultЧтобы предотвратить поведение смахивания по умолчанию, Chrome называет этот тип слушателя пассивным слушателем.
Просто скажите, если вы знаете проблему, дайтеaddEventListenerПередайте третий параметр
document.addEventListener('touchmove', function (event) {
event.preventDefault()
}, { passive: false })
Готово! Внезапно подумалось, если еще нужно прокрутить в плавающем слое, то это будет не ГГ! Итак, можно ли выборочно запретить прокрутку (запретить прокрутку после того, как элемент в плавающем слое прокрутится вверх или вниз). Отдельно обрабатывать элементы, которые необходимо прокручивать в плавающем слое;
targetElement.ontouchmove = function (event) {
const clientY = event.targetTouches[0].clientY - initialClientY
if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
return preventDefault(event)
}
if (targetElement && (targetElement.scrollHeight - 1 - targetElement.scrollTop <= targetElement.clientHeight) && clientY < 0) {
return preventDefault(event)
}
event.stopPropagation()
return true
}
Эта программа находится вiosотлично реализовано вandroidПо-прежнему существует небольшая проблема: когда содержимое плавающего слоя перемещается вверх или вниз, это все равно приводит к некоторому перемещению содержимого страницы.
tua-body-scroll-lock
Окончательное решение здесь!
tua-body-scroll-lockэтоios,androidиPCКаждый конец обрабатывается индивидуально, что гарантирует идеальный результат на каждом конце!
Установить
$ npm i -S tua-body-scroll-lock
# OR
$ yarn add tua-body-scroll-lock
использовать
мобильный
import { lock, unlock } from 'tua-body-scroll-lock'
// 禁止滑动后还需要内部可以滚动的元素(针对移动端ios处理)
const targetElement = document.querySelector("#someElementId");
lock(targetElement)
unlock(targetElement)
Сторона ПК
Советы: Стороне ПК не нужен targetElement, ни targetElement, ни приглашения консоли не могут быть переданы
null
import { lock, unlock } from 'tua-body-scroll-lock'
lock()
unlock()