Skip to content

Instantly share code, notes, and snippets.

@souporserious
Last active September 28, 2018 20:57
Show Gist options
  • Save souporserious/7a87eb99c44147b190c016b9c84083cf to your computer and use it in GitHub Desktop.
Save souporserious/7a87eb99c44147b190c016b9c84083cf to your computer and use it in GitHub Desktop.
Locks scrollbars starting from an element
/**
* Locks scrollbars starting from an element
* @param {HTMLElement} node - the element to start locking scroll at
* @return {Function} unlockScroll - unlocks all scroll elements/parents
*/
function lockScroll(node, lockedNodes = []) {
const viewport = getClosestViewport(node)
if (viewport && !viewport.__locked) {
const { overflow, paddingRight } = getComputedStyle(viewport)
const previousStyles = {
overflow: viewport.style.overflow,
paddingRight: viewport.style.paddingRight,
}
lockedNodes.push([viewport, previousStyles])
if (overflow !== 'hidden') {
viewport.style.overflow = 'hidden'
viewport.style.paddingRight =
parseInt(paddingRight, 10) + getScrollbarWidth() + 'px'
}
if (viewport === document.body) {
return () => {
lockedNodes.forEach(([node, previousStyles]) => {
node.style.overflow = previousStyles.overflow
node.style.paddingRight = previousStyles.paddingRight
delete node.__locked
})
}
} else {
return lockScroll(viewport.parentNode, lockedNodes)
}
viewport.__locked = true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment