diff --git a/src/hooks/useOverlay.hook.ts b/src/hooks/useOverlay.hook.ts index ba5461a..9e35412 100644 --- a/src/hooks/useOverlay.hook.ts +++ b/src/hooks/useOverlay.hook.ts @@ -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, } }