Last active
September 28, 2018 20:57
-
-
Save souporserious/7a87eb99c44147b190c016b9c84083cf to your computer and use it in GitHub Desktop.
Locks scrollbars starting from an element
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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