Skip to content

Instantly share code, notes, and snippets.

@Klaster1
Last active August 29, 2015 14:23
Show Gist options
  • Save Klaster1/b52311698c73e1d83b95 to your computer and use it in GitHub Desktop.
Save Klaster1/b52311698c73e1d83b95 to your computer and use it in GitHub Desktop.
ui-bootstrap $modal body shift fix
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