Showing & Hiding Navbar Bug on Momentum-Based Touch Devices

I used the code below to add a simple navbar hiding and showing when a user scrolls up and down on a webpage.


const Navbar = () => {
  const [show, setShow] = useState(true);
  const [lastScrollY, setLastScrollY] = useState(0);

  const controlNavbar = () => {
    if (typeof window !== 'undefined') { 
      if (window.scrollY > lastScrollY) { // if scroll down hide the navbar
        setShow(false); 
      } else { // if scroll up show the navbar
        setShow(true);  
      }

      // remember current page location to use in the next move
      setLastScrollY(window.scrollY); 
    }
  };

  useEffect(() => {
    if (typeof window !== 'undefined') {
      window.addEventListener('scroll', controlNavbar);

      // cleanup function
      return () => {
        window.removeEventListener('scroll', controlNavbar);
      };
    }
  }, [lastScrollY]);

  return (
        <nav className={`active ${show && 'hidden'}`}>
        ....
        </nav>
  );
};

export default Navbar;

It works perfectly well on a desktop browser, but had a bug when testing it on my iphone (on both chrome and safari). On touch devices, when scrolling back to the top, there’s a little bounce animation where the scroll goes past the top of the page and then rubberbands back to the actual top of the page. This behaviour causes my event listener to register that the user scrolled down, and hides the navbar. Similarly, when the user scrolls to the bottom of the page, the rubberband effect causes my navbar event listener to register that the user scrolled up (when it bounces back) and shows the navbar. I hope I’m explaining this clearly (lol).

I’m trying to think of a solution, and the best one I came up with is to set the hiding and showing behaviour to work after a scroll of a certain number of pixels, so something like this.

if (window.scrollY > lastScrollY + 20){
   follow abovementioned logic...
}

But since the bounce amplitude is based on the user’s scroll speed, if the user scrolls really aggressively to the top of the window it definitely is going to bounce more than 20 pixels and therefore the same bug occurs.

I can’t seem to even find others facing this problem online, so any help would be appreciated!