Issue
Using Vue, I have the following setup in a component:
<template>
<article>
<!-- This content spans several viewport heights: you *have* to scroll to get to the bottom -->
{{ content }}
</article>
<span ref="readMarker" />
</template>
// Composition API with <script setup>
const emit = defineEmit<{
(e: "read", value: number): void
}>()
const readMarker = ref<HTMLSpanElement>()
let observer: IntersectionObserver;
onMounted(() => {
if (!readMarker.value)
return
observer = new IntersectionObserver(
() => {
emit("read", 1)
},
{
root: readMarker.value,
},
)
observer.observe(readMarker.value)
})
onDeactivated(() => observer.disconnect())
The idea is that when the user scrolls to the bottom of the content (rootMarker
enters the view), the read
event is emitted. When the parent receives the event, it loads another component like this and so on (@read.once="loadMore"
).
However, as soon as I load the page, the event fires immediately, without me having any time to scroll at all. The same event for subsequent instances also fire as soon as the each instance loads.
I also tried using null as the root and creating the observer outside onMounted (with onMounted only containing the observer.observe()
call), but that changed nothing.
I have clearly misunderstood something about IntersectionObserver, but I'm really confused about this behaviour.
Solution
It turns out that if you want to observe scrolling on the viewport itself, the root
of the IntersectionObserver has to be the document
itself, whereas in my question I am trying to set readMarker.value
as root, so the observer would only look in it and, of course, see it as "visible" right away.
Answered By - theberzi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.