Intersection Observer 不可信?

Intersection Observer is not trustable?

我正在更改完全可见的 table 单元格的背景颜色。为了完成这项任务,我使用了路口观察器。

所有代码都在代码沙箱上可用,并带有重现错误的演示:

我正在为路口观察器使用 useInView 挂钩:

export const useInView = options => {
  const ref = useRef();
  const [isVisible, setIsVisible] = useState(false);
  const [intersectionRatio, setIntersectionRatio] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      console.log("called");
      setIsVisible(entry.isIntersecting);
      setIntersectionRatio(entry.intersectionRatio);
    }, options);

    if (ref.current) observer.observe(ref.current);

    return () => {
      if (ref.current) observer.unobserve(ref.current);
    };
  }, [ref, options]);

  return [ref, isVisible, intersectionRatio];
};

这是我在其中呈现数据的 table:



 <div id="my-table" style={{ height: 200, width: 200, overflow: "auto" }}>
    <table>
      <tbody>
        {tableValues.map((row, rowIndex) => (
          <tr key={rowIndex}>
            {row.map((cell, cellIndex) => (
              <CellRendererContainer
                key={`${rowIndex}${cellIndex}`}
                rowIndex={rowIndex}
                cellIndex={cellIndex}
                tableCell={cell}
              />
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  </div>

交集观察器在CellRenderer中使用,分为两个文件:

CellRendererContainer.js

const CellRendererContainer = ({ rowIndex, cellIndex, tableCell }) => {
  const [ref, isVisible, intersectionRatio] = useInView({
    root: document.querySelector("#my-table"),
    rootMargin: "0px",
    threshold: 0.0
  });

  return (
    <CellRenderer
      ref={ref}
      isVisible={isVisible}
      intersectionRatio={intersectionRatio}
      rowIndex={rowIndex}
      cellIndex={cellIndex}
      tableCell={tableCell}
    />
  );
};

这里是单元格的实际渲染,CellRenderer.js

const CellRenderer = React.forwardRef(
  ({ isVisible, intersectionRatio, rowIndex, cellIndex, tableCell }, ref) => (
    <td
      ref={ref}
      style={{
        padding: 25,
        backgroundColor:
          rowIndex > 0 && cellIndex > 0 && isVisible && intersectionRatio > 0.9
            ? "red"
            : "white"
      }}
    >
      {tableCell}
    </td>
  )
);

当前实现中的问题是:未调用路口观察者对某些项目的回调。

预期结果:

任何可见的单元格在完全可见后应立即具有红色背景。否则,该单元格应为白色。

代码沙箱link:(这样你就不需要滚动到顶部)

IntersectionObserver constructor 签名是:

var observer = new IntersectionObserver(callback[, options]);

options 参数是可选的,如果提供,它应该是一个对象,其属性描述了您希望新创建的 IntersectionObserver 的行为方式。

hook.js 中,您有这一行:

const observer = new IntersectionObserver(([entry]) => {
  console.log("called");
  setIsVisible(entry.isIntersecting);
  setIntersectionRatio(entry.intersectionRatio);
}, options);

您的变量 options 未设置为在此上下文中有用的值。

相反,像这样的东西可以满足您的需求:

const observer = new IntersectionObserver(([entry]) => {
  console.log("called");
  setIsVisible(entry.isIntersecting);
  setIntersectionRatio(entry.intersectionRatio);
}, {
  threshold: 0.9
});

此更改后,当相关元素的可见度超过或低于 90% 时,将触发该事件。