IntersectionObserver 在元素进入视图之前触发

IntersectionObserver triggers before element enters view

使用 Vue,我在组件中进行了以下设置:

<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())

想法是,当用户滚动到内容底部(rootMarker 进入视图)时,会发出 read 事件。当父级接收到事件时,它会加载另一个组件,依此类推 (@read.once="loadMore")。

但是,我一加载页面,事件就立即触发,我根本没有时间滚动。每个实例加载后,后续实例的相同事件也会触发。

我还尝试使用 null 作为根并在 onMounted 之外创建观察者(onMounted 仅包含 observer.observe() 调用),但这没有任何改变。

我显然误解了 IntersectionObserver 的某些内容,但我对这种行为真的很困惑。

事实证明,如果您想观察视口本身的滚动,IntersectionObserver 的 root 必须是 document 本身,而在我的问题中,我试图设置 readMarker.value 作为 root,因此观察者只会查看它,当然会立即将其视为“可见”。