scroll-lock
Cross-browser JavaScript library to disable scrolling page
Live demo | README на русском
New features 2.0
- More advanced touch event handling algorithm
- Horizontal scrolling support
- Support for nested scrollable elements
- Support for nested textarea and contenteditable
- New API
Installation
Via npm or yarn
npm install scroll-lock
# or
yarn add scroll-lock
import { disablePageScroll, enablePageScroll } from 'scroll-lock';
import scrollLock from 'scroll-lock';
scrollLock.disablePageScroll();
const scrollLock = require('scroll-lock');
scrollLock.disablePageScroll();
Via script tag
<script src="path/to/scroll-lock.min.js"></script>
<script>
scrollLock.disablePageScroll();
</script>
The es6 import will be used further in the examples, but these methods will also be available from the scrollLock
object.
Disable page scrolling
When you call the disablePageScroll
method, scrolling is also disabled in iOS and other touch devices (essence of the problem). But scrolling on touch devices will be disabled on all elements. To do this, you must explicitly specify which element will scroll on the page.
import { disablePageScroll, enablePageScroll } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
disablePageScroll($scrollableElement);
enablePageScroll($scrollableElement);
Alternatively, you can specify the data-scroll-lock-scrollable
attribute of the scrollable element.
<div class="my-scrollable-element" data-scroll-lock-scrollable></div>
textarea
and contenteditable
If a textarea
or contenteditable
is nested in a scrollable element, then do not worry, they will scroll without explicit indication.
Filling the gap
When the disablePageScroll
method is called, the scroll-lock indicates overflow: hidden;
for body
, thereby hiding the scroll bar. In some operating systems, the scroll bar has its physical width on the page, thus we get the effect of "displacement":
To prevent this, scroll-lock calculates the scroll bar width when calling the disablePageScroll
method and fills in the space for the body
element.
But this does not work for elements with fixed
positioning. To do this, you must explicitly indicate which element needs to fill in the space.
import { addFillGapTarget, addFillGapSelector } from 'scroll-lock';
addFillGapSelector('.my-fill-gap-selector');
const $fillGapElement = document.querySelector('.my-fill-gap-element');
addFillGapTarget($fillGapElement);
Or you can specify the data-scroll-lock-fill-gap
attribute.
<div class="my-fill-gap-element" data-scroll-lock-fill-gap></div>
Queue
A call to the disablePageScroll
method creates a queue of calls. If you call the disablePageScroll
method twice in a row, and then enablePageScroll
, the page scrolling is not activated, because the enablePageScroll
method will need to be called a second time.
If for some reason you need to activate scrolling the page out of turn, use the clearQueueScrollLocks
method:
import { disablePageScroll, clearQueueScrollLocks } from 'scroll-lock';
disablePageScroll();
disablePageScroll();
disablePageScroll();
disablePageScroll();
enablePageScroll();
console.log(getScrollState());
clearQueueScrollLocks();
enablePageScroll();
console.log(getScrollState());
API
disablePageScroll(scrollableTarget)
Hides the scroll bar and disables page scrolling.
scrollableTarget
- (HTMLElement | NodeList | HTMLElement array
) scrollable element
import { disablePageScroll } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
disablePageScroll($scrollableElement);
enablePageScroll(scrollableTarget)
Shows the scroll bar and enables page scrolling.
scrollableTarget
- (HTMLElement | NodeList | HTMLElement array
) scrollable element
import { enablePageScroll } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
enablePageScroll($scrollableElement);
getScrollState()
Returns the state of the page scroll bar.
import { disablePageScroll, getScrollState } from 'scroll-lock';
console.log(getScrollState());
disablePageScroll();
console.log(getScrollState());
clearQueueScrollLocks()
Clears the queue value.
import { disablePageScroll, enablePageScroll, clearQueueScrollLocks, getScrollState } from 'scroll-lock';
disablePageScroll();
disablePageScroll();
disablePageScroll();
disablePageScroll();
enablePageScroll();
console.log(getScrollState());
clearQueueScrollLocks();
enablePageScroll();
console.log(getScrollState());
getPageScrollBarWidth(onlyExists)
Returns the width of the scroll bar.
onlyExists
- (Boolean
) only if scroll bar is exists
Default value: false
import { getPageScrollBarWidth } from 'scroll-lock';
document.body.style.overflow = 'scroll';
console.log(getPageScrollBarWidth());
disablePageScroll();
console.log(getPageScrollBarWidth(true));
document.body.style.overflow = 'hidden';
console.log(getPageScrollBarWidth());
console.log(getPageScrollBarWidth(true));
getCurrentPageScrollBarWidth()
Returns the width of the scroll bar to specific moment.
import { disablePageScroll, getCurrentPageScrollBarWidth } from 'scroll-lock';
console.log(getCurrentPageScrollBarWidth());
disablePageScroll();
console.log(getCurrentPageScrollBarWidth());
addScrollableSelector(scrollableSelector)
Makes elements with this selector scrollable.
scrollableSelector
- (String | String array
) scrollable selector
Initial value: ['[data-scroll-lock-scrollable]']
import { disablePageScroll, addScrollableSelector } from 'scroll-lock';
addScrollableSelector('.my-scrollable-selector');
disablePageScroll();
removeScrollableSelector(scrollableSelector)
Makes elements with this selector not scrollable.
scrollableSelector
- (String | String array
) scrollable selector
import { removeScrollableSelector } from 'scroll-lock';
removeScrollableSelector('.my-scrollable-selector');
addScrollableTarget(scrollableTarget)
Makes the element scrollable.
scrollableSelector
- (HTMLElement | NodeList | HTMLElement array
) scrollable element
import { disablePageScroll, addScrollableTarget } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
addScrollableTarget($scrollableElement);
disablePageScroll();
removeScrollableTarget(scrollableTarget)
Makes the element not scrollable.
scrollableSelector
- (HTMLElement | NodeList | HTMLElement array
) scrollable element
import { removeScrollableTarget } from 'scroll-lock';
const $scrollableElement = document.querySelector('.my-scrollable-element');
removeScrollableTarget($scrollableElement);
addLockableSelector(lockableSelector)
Makes elements with this selector lockable.
lockableSelector
- (String | String array
) lockable selector
Initial value: ['[data-scroll-lock-lockable]']
import { disablePageScroll, addLockableSelector } from 'scroll-lock';
addLockableSelector('.my-lockable-selector');
disablePageScroll();
addLockableTarget(lockableTarget)
Makes the element lockable.
lockableTarget
- (HTMLElement | NodeList | HTMLElement array
) lockable element
import { disablePageScroll, addLockableTarget } from 'scroll-lock';
const $lockableElement = document.querySelector('.my-lockable-element');
addLockableTarget($lockableElement);
disablePageScroll();
addFillGapSelector(fillGapSelector)
Fills the gap with elements with this selector.
fillGapSelector
- (String | String array
) a fill gap selector
Initial value: ['body', '[data-scroll-lock-fill-gap]']
import { addFillGapSelector } from 'scroll-lock';
addFillGapSelector('.my-fill-gap-selector');
removeFillGapSelector(fillGapSelector)
Returns the gap for elements with this selector.
fillGapSelector
- (String | String array
) a fill gap selector
import { removeFillGapSelector } from 'scroll-lock';
removeFillGapSelector('.my-fill-gap-selector');
addFillGapTarget(fillGapTarget)
Fills the gap at the element.
fillGapTarget
- (HTMLElement | NodeList | HTMLElement array
) a fill gap element
import { addFillGapTarget } from 'scroll-lock';
const $fillGapElement = document.querySelector('.my-fill-gap-element');
addScrollableTarget($fillGapElement);
removeFillGapTarget(fillGapTarget)
Returns the gap at the element.
fillGapTarget
- (HTMLElement | NodeList | HTMLElement array
) a fill gap element
import { removeFillGapTarget } from 'scroll-lock';
const $fillGapElement = document.querySelector('.my-fill-gap-element');
removeFillGapTarget($fillGapElement);
setFillGapMethod(fillGapMethod)
Changes the method of filling the gap.
fillGapMethod
- (String: 'padding', 'margin', 'width', 'max-width', 'none'
) gap-filling method
Default value: padding
import { setFillGapMethod } from 'scroll-lock';
setFillGapMethod('margin');
refillGaps()
Recalculates filled gaps.
import { refillGaps } from 'scroll-lock';
refillGaps();
See also
🙌 🙌 I would like to thank “Armani” for the translation. 🙌 🙌