Last active
August 29, 2015 14:23
-
-
Save Klaster1/b52311698c73e1d83b95 to your computer and use it in GitHub Desktop.
ui-bootstrap $modal body shift fix
This file contains 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
function measureScrollbar(document) { | |
const overflowY = window.getComputedStyle(document.body).overflowY | |
let scrollDiv = document.createElement('div') | |
scrollDiv.className = 'modal-scrollbar-measure' | |
document.body.appendChild(scrollDiv) | |
const width = scrollDiv.offsetWidth - scrollDiv.clientWidth | |
document.body.removeChild(scrollDiv) | |
scrollDiv = null | |
return {width, overflowY} | |
} | |
function hasScrollbar(target, overflowY) { | |
return overflowY === 'scroll' || | |
target.offsetHeight > window.innerHeight | |
} | |
function setPadding(target, width) { | |
target.style.paddingRight = width | |
} | |
function setScrollbar(target, {width, overflowY}) { | |
const bodyPad = parseInt((target.style.paddingRight || 0), 10) | |
const alreadyApplied = bodyPad === width | |
if (hasScrollbar(target, overflowY) && !alreadyApplied) setPadding(target, bodyPad + width) | |
return alreadyApplied ? 0 : bodyPad | |
} | |
function isClassMutation(mutation) { | |
return mutation.type === 'attributes' && mutation.attributeName === 'class' | |
} | |
// NOTE: https://github.com/angular-ui/bootstrap/pull/2425 | |
export default function bodyShiftFix($window, $document, $timeout) { | |
if (!('MutationObserver' in $window)) return | |
$timeout(() => { | |
const body = $document[0].querySelector('body') | |
const measures = measureScrollbar($document[0]) | |
let originalPad = 0 | |
const observer = new MutationObserver(mutations => { | |
[...mutations] | |
.filter(isClassMutation) | |
.forEach(({target}) => { | |
if (target.classList.contains('modal-open')) { | |
originalPad = setScrollbar(target, measures) | |
} else { | |
setPadding(target, originalPad) | |
} | |
}) | |
}) | |
observer.observe(body, { | |
attributes: true | |
}) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment