Estoy haciendo un componente de desplazamiento infinito en reaccionar. Verifico ( offsetHeight + scrollTop == scrollHeight ) para darme cuenta de que me desplacé hasta el final. Sin embargo, cuando se desplaza hasta el final, a veces offsetHeight + scrollTop no es igual a scrollHeight .
const handleScroll = async (e) => { const { offsetHeight, scrollTop, scrollHeight } = e.target; console.log(offsetHeight + scrollTop + " == " + scrollHeight); if (offsetHeight + scrollTop == scrollHeight) { console.log("ok"); setStep((prev) => prev + step); fetchData(nowStep + step); } }; return ( <div onScroll={handleScroll} style={{ height: height, overflowY: "scroll", overflowX: "hidden", width: "100%", padding: 0, margin: 0, textAlign: "center", }} > {children} </div>Esto es lo que pienso:
Editar: me di cuenta de que el zoom del navegador podría ser la causa. En algunos niveles de zoom, por ejemplo: 125 %, 100 %, 75 %, 67 %, el código funciona bien, pero en 110 %, 90 %, 80 %, los resultados de la comprobación no son los esperados. Consola al desplazarse hasta el final:
690.9090881347656 == 696 694.5454406738281 == 696 695.757568359375 == 696 694.6666564941406 == 696 695.3333435058594 == 696 696 == 696 ok 694.0740966796875 == 696 694.8148498535156 == 696 695.5555725097656 == 696No compliques demasiado las cosas. Puede lograr un desplazamiento sin fin mucho más fácil con Intersection Observer (IO)
Con IO puede observar un elemento y reaccionar cada vez que se cruza con la ventana gráfica o con otro elemento. Para su caso, desea que active una función cada vez que esté a la vista (se cruza con la ventana gráfica)
Creas un div ficticio en la parte inferior de tu página y creas un IO. Luego, solo espere a que aparezca y haga su lógica para agregar más elementos:
let observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { addAnotherRow(); } }) }); const target = document.querySelector('#dummy'); observer.observe(target); addAnotherRow = () => { const template = document.querySelector('#moreItem'); const clone = template.content.cloneNode(true); document.querySelector('ul').appendChild(clone); } ul { min-height: 110vh; } li { min-height: 47vh; } <ul> <li> Test </li> <li> Item </li> <li> More Content </li> </ul> <div id="dummy"> </div> <template id="moreItem"> <li> Lazy Loaded items </li> </template>