简体   繁体   English

Reactjs 中的交叉点观察器

[英]Intersection Observer in Reactjs

Can someone help me how can I do this in Reactjs?有人可以帮助我如何在 Reactjs 中做到这一点吗?

Can I iterate one IntersectionObserver for multiple child in reactjs我可以在 reactjs 中为多个孩子迭代一个 IntersectionObserver

 const faders = document.querySelectorAll('.fade-in'); const appearOptions = { threshold: 1 }; const appearOnScroll = new IntersectionObserver( function(entries, appearOnScroll){ entries.forEach(entry => { if(!entry.isIntersecting){ return; }else{ entry.target.classList.add('appear') appearOnScroll.unobserve(entry.target) } }) }, appearOptions); faders.forEach(fader =>{ appearOnScroll.observe(fader) })

useIntersectionObserver.js使用IntersectionObserver.js

Use this custom hook.使用这个自定义钩子。 It creates an IntersectionObserver instance and saves it in a useRef hook.它创建一个IntersectionObserver实例并将其保存在useRef挂钩中。 It tracks the elements that are being observed in a state.它跟踪在某个状态下观察到的元素。 Whenever the state changes, it unobserves all elements and then reobserves the elements that remain in the state.每当状态发生变化时,它不会观察所有元素,然后重新观察保持在状态中的元素。

The advantages of creating a custom hook is that you can reuse the hook and implement it on multiple occasions.创建自定义钩子的优点是您可以重复使用该钩子并在多个场合实现它。

import { useRef, useState, useEffect } from 'react';

const useIntersectionObserver = ({ root = null, rootMargin = '0px', threshold = 0 }) => {
  const [entries, setEntries] = useState([]);
  const [observedNodes, setObservedNodes] = useState([]);
  const observer = useRef(null);

  useEffect(() => {
    if (observer.current) {
      observer.current.disconnect();
    }

    observer.current = new IntersectionObserver(entries => setEntries(entries), {
      root,
      rootMargin,
      threshold
    });

    const { current: currentObserver } = observer;

    for (const node of observedNodes) {
      currentObserver.observe(node);
    }

    return () => currentObserver.disconnect();
  }, [observedNodes, root, rootMargin, threshold]);


  return [entries, setObservedNodes];
};

export default useIntersectionObserver;

app.js应用程序.js

Use the hook where you need to observe your elements.在需要观察元素的地方使用钩子。 Create references to the elements that you need to observe and pass them to the hook after the first render.创建对您需要观察的元素的引用,并在第一次渲染后将它们传递给钩子。

The entries state will contain an array of IntersectionObserverEntry objects. entries状态将包含一个IntersectionObserverEntry对象数组。 Loop over it whenever the entries state changes and assert your logic, like adding a class.每当entries状态更改并断言您的逻辑时,循环它,例如添加一个类。

import { useRef, useEffect } from 'react';
import useIntersectionObserver from './useIntersectionObserver';

function App() {
  const targets = useRef(new Set());

  const [entries, setObservedNodes] = useIntersectionObserver({
    threshold: 1
  });

  useEffect(() => {
    setObservedNodes(() => ([...targets.current]));
  }, [setObservedNodes]);

  useEffect(() => {
    for (const entry of entries) {
      if (entry.isIntersecting) {
        entry.target.classList.add('appear');

        setObservedNodes(observedNodes => 
          observedNodes.filter(node => node !== entry.target)
        );
      }
    }
  }, [entries, setObservedNodes]);

  return (
    <>
      <div className="fade-in" ref={element => targets.current.add(element)}></div>
      <div className="fade-in" ref={element => targets.current.add(element)}></div>
    </>
  )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM