fix: scroll both body and documentElement for cross-browser compatibility

This commit is contained in:
Julien Calixte
2026-02-19 19:19:49 +01:00
parent 4a06c11b0a
commit 8da5dcc50f

View File

@@ -1,7 +1,7 @@
import { useEventListener, useWindowSize } from '@vueuse/core'
import { computed, ref } from 'vue'
import { useEventListener, useWindowSize } from "@vueuse/core"
import { computed, ref } from "vue"
import { MOBILE_BREAKPOINT } from '@/constants/mobile'
import { MOBILE_BREAKPOINT } from "@/constants/mobile"
export const useOverlay = (listen = true) => {
const x = ref(0)
@@ -10,31 +10,32 @@ export const useOverlay = (listen = true) => {
const isMobile = computed(() => width.value <= MOBILE_BREAKPOINT)
if (listen) {
useEventListener(
window,
'scroll',
() => {
x.value = window.scrollX
y.value = window.scrollY
},
{
passive: true,
capture: false
}
)
// In Firefox/Chrome, body is the horizontal scroll container (body has
// computed overflow-x: auto from overflow-y: hidden). In Safari, the
// viewport (documentElement) is used instead. Listen on both.
const updateScroll = () => {
x.value = document.body.scrollLeft || window.scrollX
y.value = document.body.scrollTop || window.scrollY
}
useEventListener(window, "scroll", updateScroll, {
passive: true,
capture: false,
})
useEventListener(document.body, "scroll", updateScroll, {
passive: true,
capture: false,
})
}
const scrollToNote = (to: number) => {
const go = () => {
const scrollOptions = isMobile.value
? {
top: to
}
: {
left: to
}
window.scrollTo(scrollOptions)
if (isMobile.value) {
document.body.scrollTop = to
document.documentElement.scrollTop = to
} else {
document.body.scrollLeft = to
document.documentElement.scrollLeft = to
}
}
setTimeout(() => {
@@ -46,6 +47,6 @@ export const useOverlay = (listen = true) => {
x,
y,
isMobile,
scrollToNote
scrollToNote,
}
}