Skip to content

Commit b6bc012

Browse files
committed
refactor: Implementing useIntersectionObserver composable
1 parent d6de956 commit b6bc012

File tree

1 file changed

+36
-44
lines changed

1 file changed

+36
-44
lines changed

app/pages/package/[[org]]/[name].vue

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const router = useRouter()
2929
const header = useTemplateRef('header')
3030
const isHeaderPinned = shallowRef(false)
3131
const navExtraOffset = shallowRef(0)
32+
const isMobile = useMediaQuery('(max-width: 639.9px)')
3233
3334
function checkHeaderPosition() {
3435
const el = header.value
@@ -41,57 +42,48 @@ function checkHeaderPosition() {
4142
isHeaderPinned.value = Math.abs(rect.top - top) < 1
4243
}
4344
44-
let footerEl: HTMLElement | null = null
45-
let footerObserver: IntersectionObserver | null = null
46-
let footerMediaQuery: MediaQueryList | null = null
47-
const footerMediaHandler = (event: MediaQueryListEvent) => {
48-
if (event.matches) {
49-
setupFooterObserver()
50-
} else {
51-
teardownFooterObserver()
52-
}
53-
}
45+
useEventListener('scroll', checkHeaderPosition, { passive: true })
46+
useEventListener('resize', checkHeaderPosition)
47+
48+
const footerTarget = ref<HTMLElement | null>(null)
49+
const footerThresholds = Array.from({ length: 11 }, (_, i) => i / 10)
50+
51+
const { pause: pauseFooterObserver, resume: resumeFooterObserver } = useIntersectionObserver(
52+
footerTarget,
53+
([entry]) => {
54+
if (!entry) return
55+
56+
navExtraOffset.value = entry.isIntersecting ? entry.intersectionRect.height : 0
57+
},
58+
{
59+
threshold: footerThresholds,
60+
immediate: false,
61+
},
62+
)
63+
64+
function initFooterObserver() {
65+
footerTarget.value = document.querySelector('footer')
66+
if (!footerTarget.value) return
5467
55-
function setupFooterObserver() {
56-
if (!footerEl) return
57-
const thresholdValues = Array.from({ length: 101 }, (_, index) => index / 100)
58-
footerObserver = new IntersectionObserver(
59-
entries => {
60-
const entry = entries[0]
61-
if (!entry) return
62-
navExtraOffset.value = entry.isIntersecting ? entry.intersectionRect.height : 0
68+
pauseFooterObserver()
69+
70+
watch(
71+
isMobile,
72+
value => {
73+
if (value) {
74+
resumeFooterObserver()
75+
} else {
76+
pauseFooterObserver()
77+
navExtraOffset.value = 0
78+
}
6379
},
64-
{ threshold: thresholdValues },
80+
{ immediate: true },
6581
)
66-
footerObserver.observe(footerEl)
67-
}
68-
69-
function teardownFooterObserver() {
70-
footerObserver?.disconnect()
71-
footerObserver = null
72-
navExtraOffset.value = 0
7382
}
7483
75-
useEventListener('scroll', checkHeaderPosition, { passive: true })
76-
useEventListener('resize', checkHeaderPosition)
77-
7884
onMounted(() => {
7985
checkHeaderPosition()
80-
footerEl = document.querySelector('footer')
81-
if (!footerEl) return
82-
footerMediaQuery = window.matchMedia('(max-width: 639.9px)')
83-
if (footerMediaQuery.matches) {
84-
setupFooterObserver()
85-
} else {
86-
teardownFooterObserver()
87-
}
88-
footerMediaQuery.addEventListener('change', footerMediaHandler)
89-
})
90-
91-
onBeforeUnmount(() => {
92-
teardownFooterObserver()
93-
footerMediaQuery?.removeEventListener('change', footerMediaHandler)
94-
footerMediaQuery = null
86+
initFooterObserver()
9587
})
9688
9789
const navExtraOffsetStyle = computed(() => ({

0 commit comments

Comments
 (0)