He visto tutoriales que demuestran cómo hacer esto, pero todo lo que he visto usa "ventana" o ejemplos donde el elemento se ve desde la parte inferior de una página. Tengo un modal con una altura fija que se desplaza:
const ItemMarkup = forwardRef(({user}, ref) => <li ref={ref}>...</li>) // This opens up in a modal: https://headlessui.dev/react/dialog <div className="content"> {/** Tailwind's fixed height 'h-96' */} <ul ref={scrollRef} className="h-96 overflow-scroll"> {users.map((user, index) => <ItemMarkup {/** I'm looking for the last item/element to come in this view (ul) */} ref={users.length === index + 1 ? ref : null} key={user.id} user={user} /> )} </ul> </div>He visto esta demostración pero, de nuevo, es para toda la página/ventana. Entonces he intentado usar esta función:
// element would be the ref.current // target would be scrollRef // But this always return false function isInViewport(element, target) { const rect = element.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= target.innerHeight && rect.right <= target.innerWidth ); }Así es como probé el intento:
const ref = useRef() const scrollRef = useRef() // From the demo link above const onScreen = useOnScreen(ref) // No idea if I need this const [scrolling, setScrolling] = useState(false) useEffect(() => { const onScroll = e => { setScrolling(true) console.log(isInViewport(ref.current, scrollRef)) }; scrollRef?.current.addEventListener("scroll", onScroll); //console.log(ref, onScreen) return () => scrollRef?.current.removeEventListener("scroll", onScroll); }, [ref, onScreen, scrolling])Esto parece todo mal. ¿Hay algún enlace de reacción que pueda determinar cuándo un elemento específico aparece en una vista modal o cualquier vista desplazable que especifique y no en la vista del documento? Simplemente no puedo encontrar ninguna documentación / tutoriales sobre esto.
Estoy creando un pergamino infinito. Cuando aparecen los últimos elementos del modal, activé una función para obtener más datos.
Supongo que tengo cosas más complicadas:
useEffect(() => { const onScroll = e => { console.log(isInViewport(e.target)) }; scrollRef?.current.addEventListener("scroll", onScroll); return () => scrollRef?.current.removeEventListener("scroll", onScroll); }, []) function isInViewport(element) { return element.scrollHeight - element.scrollTop === element.clientHeight } Ahora, cuando me desplazo hasta la parte inferior, veo un registro de consola de true .