Skip to content

Instantly share code, notes, and snippets.

@lakesare
Created May 30, 2019 02:48
Show Gist options
  • Save lakesare/b33cab4d7fcfeadbae7f532e46f47a50 to your computer and use it in GitHub Desktop.
Save lakesare/b33cab4d7fcfeadbae7f532e46f47a50 to your computer and use it in GitHub Desktop.
preventScroll polyfilll
// focus - focusOptions - preventScroll polyfill
const isPreventScrollDefined = () => {
let supportsPreventScrollOption = false
// 1. Create element
const el = document.createElement('div')
// 2. Make sure it won't do anything on focus
el.addEventListener('focus', (event) => {
event.preventDefault()
event.stopPropagation()
}, true)
// 3. And attempt to .focus() on our element, observing whether browser tries to access .preventScroll option
const patchedOptions = Object.defineProperty({}, 'preventScroll', {
get: () => {
supportsPreventScrollOption = true
}
})
el.focus(patchedOptions)
return supportsPreventScrollOption
}
console.log(isPreventScrollDefined());
if (HTMLElement.prototype.nativeFocus === undefined && !isPreventScrollDefined()) {
HTMLElement.prototype.nativeFocus = HTMLElement.prototype.focus
var patchedFocus = function (args) {
var actualPosition = window.scrollY
this.nativeFocus()
if (args && args.preventScroll) {
// Hijacking the event loop order, since the focus() will trigger
// internally an scroll that goes to the event loop
setTimeout(function () {
window.scroll(window.scrollX, actualPosition)
}, 0)
}
}
HTMLElement.prototype.focus = patchedFocus
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment