- Более придвинутый алгоритм обработки touch событий
- Поддержка горизонтальной прокрутки
- Поддержка вложенных прокручиваемых элементов
- Поддержка вложенных textarea и contenteditable
- Новый API
npm install scroll-lock
# или
yarn add scroll-lock//es6 import
import { disablePageScroll, enablePageScroll } from 'scroll-lock';
//или
import scrollLock from 'scroll-lock';
scrollLock.disablePageScroll();
//...
//require
const scrollLock = require('scroll-lock');
scrollLock.disablePageScroll();
//...<script src="path/to/scroll-lock.min.js"></script>
<script>
scrollLock.disablePageScroll();
//...
</script>Дальше в примерах будет использован es6 import, но эти методы также будут доступны из объекта scrollLock.
Когда вы вызываете метод disablePageScroll, также прокрутка отключается в iOS и других touch устройствах (суть проблемы). Но прокрута на touch устройствах будет отключена на всех элементов, для этого надо явно указать, какой элемент будет прокручиваться на странице.
import { disablePageScroll, enablePageScroll } from 'scroll-lock';
//Получим элемент, который должен прокручиваться при отключеной прокрутки страницы
const $scrollableElement = document.querySelector('.my-scrollable-element');
//Передадим элемент аргументом и отключим прокрутку на странице
disablePageScroll($scrollableElement);
//Также передадим аргументом элемент и активируем прокрутку на странице
enablePageScroll($scrollableElement);Или же вы можете указать атрибут data-scroll-lock-scrollable прокручиваемому элементу.
<div class="my-scrollable-element" data-scroll-lock-scrollable></div>Если в прокручиваемом элементе будут вложены textarea или contenteditable то не переживайте, они будут прокручиваться без явного указания.
Когда вызывается метод disablePageScroll, scroll-lock указывает overflow: hidden; для body, тем самым скрывая полосу прокрутки. В некоторых ОС полоса прокрутки имеет свою физическую ширину на странице, тем самым мы получае эффект "смещения":

Что бы предотвратить это, scroll-lock высчитывает ширину полосы прокрутки при вызове метода disablePageScroll и заполняет пробел для элемента body.

Но это не работает для элементов с позиционированием fixed. Для этого надо явно указать, какому ещё элементу нужно заполнить пробел.
import { addFillGapTarget, addFillGapSelector } from 'scroll-lock';
//селектор
addFillGapSelector('.my-fill-gap-selector');
//элемент
const $fillGapElement = document.querySelector('.my-fill-gap-element');
addFillGapTarget($fillGapElement);Или же вы можете указать атрибут data-scroll-lock-fill-gap.
<div class="my-fill-gap-element" data-scroll-lock-fill-gap></div>Вызов метода disablePageScroll создает очередь вызовов. Если вы вызовите метод disablePageScroll два раза подряд, а потом enablePageScroll, прокрутка страницы не активируется, т.к. метод enablePageScroll нужно будет вызвать второй раз.
Если вам по каким то причинам надо активировать прокрутку страницы вне очереди, используйте метод clearQueueScrollLocks:
import { disablePageScroll, clearQueueScrollLocks } from 'scroll-lock';
disablePageScroll();
disablePageScroll();
disablePageScroll();
disablePageScroll();
enablePageScroll();
console.log(getScrollState()); //false
clearQueueScrollLocks();
enablePageScroll();
console.log(getScrollState()); //trueСкрывает полосу прокрутки и отключает прокрутку страницы.
scrollableTarget- (HTMLElement | NodeList | HTMLElement array) прокручиваемый элемент
import { disablePageScroll } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
disablePageScroll($scrollableElement);Показывает полосу прокрутки и активирует прокрутку страницы.
scrollableTarget- (HTMLElement | NodeList | HTMLElement array) прокручиваемый элемент
import { enablePageScroll } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
enablePageScroll($scrollableElement);Возвращает состояние полосы прокрутки страницы.
import { disablePageScroll, getScrollState } from 'scroll-lock';
console.log(getScrollState()); //true
disablePageScroll();
console.log(getScrollState()); //falseОчищает значение очереди.
import { disablePageScroll, enablePageScroll, clearQueueScrollLocks, getScrollState } from 'scroll-lock';
disablePageScroll();
disablePageScroll();
disablePageScroll();
disablePageScroll();
enablePageScroll();
console.log(getScrollState()); //false
clearQueueScrollLocks();
enablePageScroll();
console.log(getScrollState()); //trueВозвращает ширину полосы прокрутки.
onlyExists- (Boolean) если полоса прокрутки найдена
Стандартное значение:false
import { getPageScrollBarWidth } from 'scroll-lock';
document.body.style.overflow = 'scroll';
console.log(getPageScrollBarWidth()); //Number
disablePageScroll();
console.log(getPageScrollBarWidth(true)); //Number
document.body.style.overflow = 'hidden';
console.log(getPageScrollBarWidth()); //Number
console.log(getPageScrollBarWidth(true)); //0Возвращает ширину полосы прокрутки в данный момент.
import { disablePageScroll, getCurrentPageScrollBarWidth } from 'scroll-lock';
console.log(getCurrentPageScrollBarWidth()); //Number
disablePageScroll();
console.log(getCurrentPageScrollBarWidth()); //0Делает элементы с этим селектором прокручиваемыми.
scrollableSelector- (String | String array) селектор прокручиваемых элементов
Начальное значение:['[data-scroll-lock-scrollable]']
import { disablePageScroll, addScrollableSelector } from 'scroll-lock';
addScrollableSelector('.my-scrollable-selector');
disablePageScroll();Делает элементы с этим селектором не прокручиваемыми.
scrollableSelector- (String | String array) селектор прокручиваемых элементов
import { removeScrollableSelector } from 'scroll-lock';
removeScrollableSelector('.my-scrollable-selector');Делает элемент прокручиваемым.
scrollableSelector- (HTMLElement | NodeList | HTMLElement array) прокручиваемый элемент
import { disablePageScroll, addScrollableTarget } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
addScrollableTarget($scrollableElement);
disablePageScroll();Делает элемент не прокручиваемым.
scrollableSelector- (HTMLElement | NodeList | HTMLElement array) прокручиваемый элемент
import { removeScrollableTarget } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
removeScrollableTarget($scrollableElement);Делает элементы с этим селектором не прокручиваемыми в любом случае.
lockableSelector- (String | String array) селектор не прокручиваемых элементов
Initial value:['[data-scroll-lock-lockable]']
import { disablePageScroll, addLockableSelector } from 'scroll-lock';
addLockableSelector('.my-lockable-selector');
disablePageScroll();Делает элемент не прокручиваемым в любом случае.
lockableTarget- (HTMLElement | NodeList | HTMLElement array) не прокручиваемый элемент
import { disablePageScroll, addLockableTarget } from 'scroll-lock';
const $lockableElement = document.querySelector('.my-lockable-element');
addLockableTarget($lockableElement);
disablePageScroll();Заполняет пробелы у элементов с этим селектором.
fillGapSelector- (String | String array) селектор заполненения пробела
Начальное значение:['body', '[data-scroll-lock-fill-gap]']
import { addFillGapSelector } from 'scroll-lock';
addFillGapSelector('.my-fill-gap-selector');Возвращает пробелы у элементов с этим селектором.
fillGapSelector- (String | String array) селектор заполненения пробела
import { removeFillGapSelector } from 'scroll-lock';
removeFillGapSelector('.my-fill-gap-selector');Заполняет пробел у элемента.
fillGapTarget- (HTMLElement | NodeList | HTMLElement array) элемент заполнения пробела
import { addFillGapTarget } from 'scroll-lock';
const $fillGapElement = document.querySelector('.my-fill-gap-element');
addScrollableTarget($fillGapElement);Возвращает пробел у элемента.
fillGapTarget- (HTMLElement | NodeList | HTMLElement array) элемент заполнения пробела
import { removeFillGapTarget } from 'scroll-lock';
const $fillGapElement = document.querySelector('.my-fill-gap-element');
removeFillGapTarget($fillGapElement);Изменяет метод заполнения пробела.
fillGapMethod- (String: 'padding', 'margin', 'width', 'max-width', 'none') метод заполнения пробела
Стандартное значение:padding
import { setFillGapMethod } from 'scroll-lock';
setFillGapMethod('margin');Пересчитывает значения заполненых пробелов.
import { refillGaps } from 'scroll-lock';
refillGaps();