type HTMLElementExpanded = HTMLElement & { polyfillScrollIntoView?: boolean }
/**
* Extension for scrollIntoView of HTMLElement
* set the flag "programmaticScroll" to true on the window object when is called that last 500 ms with this value ,
* so when we listen to scroll event we can know that comes from this method
*
* The reason of this polyfill is that there is no way to know if the scroll event comes from the scrollIntoView method.
* This polyfill is a workaround to solve this problem and shouldn't affect the normal behavior of the scrollIntoView method
*
*/
export default function scrollIntoViewPolyfill() {
// Check if the extension can be applied or if it is already applied to not apply it twice
const windowRef = window as Window & { polyfillScrollIntoView?: boolean }
if (!windowRef || (windowRef && windowRef?.polyfillScrollIntoView)) {
return
}
windowRef.polyfillScrollIntoView = true
const nativeScrollIntoView = window.HTMLElement.prototype.scrollIntoView
window.HTMLElement.prototype.scrollIntoView = function (
options?: ScrollIntoViewOptions | undefined
) {
const element = this as HTMLElementExpanded
const window = element.ownerDocument.defaultView as Window & {
programmaticScroll?: boolean
}
window.programmaticScroll = true
nativeScrollIntoView.apply(element, [options])
setTimeout(() => {
window.programmaticScroll = false
}, 500)
}
}
scrollIntoViewPolyfill()