I want to throttle listening to my window scroll event every 100 milliseconds instead of on every scroll to improve performance. I attempted this using setTimeout, but my implementation just waits 100 milliseconds before listening to window scroll instead of throttling the scroll event.
I don't want to use lodash and would like to use as much vanilla JS as possible.
import { useRef, useEffect } from "react";
import "./styles.css";
const cardData = [
{
title: "Title One",
description: "Description One"
},
{
title: "Title Two",
description: "Description Two"
},
{
title: "Title Three",
description: "Description Three"
},
{
title: "Title Four",
description: "Description Four"
},
{
title: "Title Five",
description: "Description Five"
},
{
title: "Title Six",
description: "Description Six"
},
{
title: "Title Seven",
description: "Description Seven"
},
{
title: "Title Eight",
description: "Description Eight"
},
{
title: "Title Nine",
description: "Description Nine"
},
{
title: "Title Ten",
description: "Description Ten"
},
{
title: "Title Eleven",
description: "Description Eleven"
},
{
title: "Title Twelve",
description: "Description Twelve"
},
{
title: "Title Thirteen",
description: "Description Thirteen"
}
];
const Card = ({ card }) => (
<div className="item">
<h1>{card.title}</h1>
<p>{card.description}</p>
</div>
);
export default function App() {
const slider = useRef(null);
const itemWrap = useRef(null);
const pan = useRef(null);
const countRef = useRef(0);
const handleOnRender = () => {
const wh = window.innerHeight;
pan.current.style.height = itemWrap.current.scrollWidth + wh / 1.25 + "px";
};
const handleScroll = () => {
console.log("scrolling");
if (window.scrollY <= pan.current.offsetTop) {
slider.current.style.position = "relative";
}
if (window.scrollY >= slider.current.offsetTop) {
slider.current.style.position = "fixed";
countRef.current = window.scrollY - pan.current.offsetTop;
itemWrap.current.style.transform = `translate3d(-${countRef.current}px, 0, 0)`;
}
};
useEffect(() => {
handleOnRender();
const timer = setInterval(() => {
window.addEventListener("scroll", handleScroll);
}, 100);
return () => {
clearInterval(timer);
window.removeEventListener("scroll", handleScroll);
};
}, []);
return (
<div className="App">
<div className="box bg-tomato">Box - #1</div>
<div className="box bg-thistle">Box - #2</div>
<div ref={slider} className="slider">
<h2>Box - #3 (Slider)</h2>
<div ref={itemWrap} className="item-wrap">
{cardData.map((card) => (
<Card card={card} key={card.title} />
))}
</div>
</div>
<div ref={pan} className="pan"></div>
<div className="box bg-teal">Box - #4</div>
<div className="box bg-violet">Box - #5</div>
</div>
);
}
How do I edit my setTimeout function to throttle the scroll event every 100 milliseconds instead of delaying 100 milliseconds?