在 Intersection Observer 的选项参数中设置 root 属性 会导致奇怪的行为

Setting root property in options argument of Intersection Observer causes weird behavior

我一直在测试 Intersection Observer API,特别是在 React 中。我 运行 遇到一个问题,当我设置选项参数的根 属性 时,观察者无法正确识别元​​素何时可见。如果不是很清楚,请看下面我的代码:

import * as React from "react"
import {} from "styled-components/macro"

const Component = () => {
  
  const containerRef = React.useRef()

  React.useEffect(() => {
     const container = containerRef.current
     
     if(container){
       
       const observer = new IntersectionObserver((entries) => {
         entries.forEach((entry) => {
           console.log(entries.intersectionRatio)
         })
       }, {
       root: container,
       threshold: [0, 0.2, 0.4, 0.6, 0.8, 1]
       })
   
       container.childNodes.forEach((child) => {
         observer.observe(child)
       })

       return () => observer.disconnect()
     }
  }, [])
  
  
 return <div
      
      ref={containerRef}
      css={`
        background-color: green;
        padding: 15px;

        > * {
          margin-bottom: 20px;
        }
      `}
    >
      <h1 name="section1">
        Section One
      </h1>
      <p name="para1">
        sit amet tincidunt eu, consectetur non purus. Ut ex lorem, pellentesque
        quis augue quis, semper fringilla ante. Nunc suscipit interdum nisl, id
        fermentum turpis consequat pellentesque. Praesent nec ex egestas tellus
        gravida vulputate nec sed tortor. Maecenas vulputate mattis tincidunt.
      </p>

      <h2 name="section2">Section Two</h2>
      <p name="para2">
        Ut commodo ac turpis eu cursus. Aliquam vel faucibus leo. Etiam ac
        tortor ullamcorper, ornare nisl in, blandit nisl. Quisque congue dictum
        eros at pellentesque. Morbi vulputate massa ac sapien molestie, vitae
        dictum elit varius. Quisque efficitur pulvinar turpis, ac condimentum

      </p>

      <h3 name="section3">Section 3</h3>
      <p name="para3">
        Ut commodo ac turpis eu cursus. Aliquam vel faucibus leo. Etiam ac
        tortor ullamcorper, ornare nisl in, blandit nisl. Quisque congue dictum
        eros at pellentesque. Morbi vulputate massa ac sapien molestie, vitae
 
      </p>
    </div>
}

这是我正在尝试做的一个非常基本的例子。这里的问题是它显示所有元素的比率为“1.0”,这没有意义,因为一些元素不在视口中。另一个问题是阈值不会触发回调,除非是在最初的观察中。如果我将 root 设置为 null BUT 则此代码有效,原因我不会深入,这并不理想。将 root 设置为 null 会将视口默认为整个文档正文。

我似乎无法弄清楚到底是什么问题,如果您能帮助我解决这个问题,我将不胜感激。

尝试对您的组件进行一些更改,它工作正常。

您的代码console.log(entries.intersectionRatio)似乎console.log(entries.intersectionRatio)不正确

const Component = () => {
  
  const containerRef = React.useRef()

  React.useEffect(() => {
     const container = containerRef.current
     
     if(container){
       
       const observer = new IntersectionObserver((entries) => {
         entries.forEach((entry) => {
           const {isIntersecting, target, intersectionRatio } = entry;
           console.log( {isIntersecting, name: target.attributes["name"].value, intersectionRatio });
         })
       }, {
       root: container,
       threshold: [0, 0.2, 0.4, 0.6, 0.8, 1]
       })
   
       container.childNodes.forEach((child) => {
         observer.observe(child)
       })

       return () => observer.disconnect()
     }
  }, [])
  
  
 return <div
      
      ref={containerRef}
      style={{
        padding: '15px',
        height: '200px',
        overflow: 'scroll',
      }}
    >
      <h1 name="section1">
        Section One
      </h1>
      <p name="para1">
        sit amet tincidunt eu, consectetur non purus. Ut ex lorem, pellentesque
        quis augue quis, semper fringilla ante. Nunc suscipit interdum nisl, id
        fermentum turpis consequat pellentesque. Praesent nec ex egestas tellus
        gravida vulputate nec sed tortor. Maecenas vulputate mattis tincidunt.
      </p>

      <h2 name="section2">Section Two</h2>
      <p name="para2">
        Ut commodo ac turpis eu cursus. Aliquam vel faucibus leo. Etiam ac
        tortor ullamcorper, ornare nisl in, blandit nisl. Quisque congue dictum
        eros at pellentesque. Morbi vulputate massa ac sapien molestie, vitae
        dictum elit varius. Quisque efficitur pulvinar turpis, ac condimentum

      </p>

      <h3 name="section3">Section 3</h3>
      <p name="para3">
        Ut commodo ac turpis eu cursus. Aliquam vel faucibus leo. Etiam ac
        tortor ullamcorper, ornare nisl in, blandit nisl. Quisque congue dictum
        eros at pellentesque. Morbi vulputate massa ac sapien molestie, vitae
 
      </p>
    </div>
}

我能够观察到不可见元素的结果 isIntersecting: false, intersectionRation: 0