skip to Main Content

I have implemented a code in my website that will hide the navbar when scrolling down and show it when scrolling up.

the problem is I want when the user scroll up and stops scrolling to read something on the website after like 5 sec the navbar will hide again until the user starts scrolling again.

how can I do this?

this is the script I used for show/hide nav bar:

<script>
const nav = document.querySelector("nav");
const navHeight = 70;
// the point the scroll starts from (in px)
let lastScrollY = 0;
// how far to scroll (in px) before triggering
const delta = 10;

// function to run on scrolling
function scrolled() {
  let sy = window.scrollY;
  // only trigger if scrolled more than delta
  if (Math.abs(lastScrollY - sy) > delta) {
    // scroll down -> hide nav bar
    if (sy > lastScrollY && sy > navHeight) {
      nav.classList.add("nav-up");
    } 
    // scroll up -> show nav bar
    else if (sy < lastScrollY) {
      nav.classList.remove("nav-up");
    }
   // update current scroll point
   lastScrollY = sy 
  }
}

// Add event listener & debounce so not constantly checking for scroll
let didScroll = false;
window.addEventListener("scroll", function(e){
  didScroll = true;
});

setInterval(function() {
  if (didScroll) {
    scrolled();
    didScroll = false;
   }
}, 250)

</script>

what can I add to it so the navbar will automatically hide when the user scrolls up and then stops scrolling?

5

Answers


  1. <script>
    const nav = document.querySelector("nav");
    const navHeight = 70;
    // the point the scroll starts from (in px)
    let lastScrollY = 0;
    // how far to scroll (in px) before triggering
    const delta = 10;
    // the duration of inactivity after which the navbar will be hidden (in ms)
    const hideDelay = 5000; // 5 seconds
    
    let hideTimeout;
    
    // function to hide the navbar
    function hideNavbar() {
      nav.classList.add("nav-up");
    }
    
    // function to show the navbar
    function showNavbar() {
      nav.classList.remove("nav-up");
    }
    
    // function to run on scrolling
    function scrolled() {
      let sy = window.scrollY;
      // only trigger if scrolled more than delta
      if (Math.abs(lastScrollY - sy) > delta) {
        // scroll down -> hide nav bar
        if (sy > lastScrollY && sy > navHeight) {
          hideNavbar();
        } 
        // scroll up -> show nav bar
        else if (sy < lastScrollY) {
          showNavbar();
        }
        // update current scroll point
        lastScrollY = sy;
    
        // Clear the previous timeout if exists
        clearTimeout(hideTimeout);
        // Set a new timeout to hide the navbar after the specified duration of inactivity
        hideTimeout = setTimeout(hideNavbar, hideDelay);
      }
    }
    
    // Add event listener & debounce so not constantly checking for scroll
    let didScroll = false;
    window.addEventListener("scroll", function(e) {
      didScroll = true;
    });
    
    setInterval(function() {
      if (didScroll) {
        scrolled();
        didScroll = false;
      }
    }, 250);
    
    </script>
    
    Login or Signup to reply.
  2. You can try adding a timer that waits for some time after the user stops scrolling before hiding the navbar again:

    
    <script>
    const nav = document.querySelector("nav");
    const navHeight = 70;
    let lastScrollY = 0;
    const delta = 10;
    let didScroll = false;
    let hideTimeout;
    
    function scrolled() {
      let sy = window.scrollY;
    
      if (Math.abs(lastScrollY - sy) > delta) {
        if (sy > lastScrollY && sy > navHeight) {
          nav.classList.add("nav-up");
        } else if (sy < lastScrollY) {
          nav.classList.remove("nav-up");
        }
    
        lastScrollY = sy;
        resetHideTimeout(); // Reset the timer every time there's a scroll event
      }
    }
    
    function resetHideTimeout() {
      clearTimeout(hideTimeout);
      hideTimeout = setTimeout(() => {
        nav.classList.add("nav-up");
      }, 5000); // Every 5 seconds
    }
    
    window.addEventListener("scroll", function(e) {
      didScroll = true;
    });
    
    setInterval(function() {
      if (didScroll) {
        scrolled();
        didScroll = false;
      }
    }, 250);
    
    // Initial timer setup on page load
    resetHideTimeout();
    
    </script>
    
    
    Login or Signup to reply.
  3. Simply use a setTimeout function with a 5000ms timer to hide the navbar. Then use an addEventListener to reset the timer if a scroll event within the window occurred:

    const NAV = document.querySelector('nav');
    
    let timer = null;
    
    window.addEventListener('scroll', function() {
      if (timer !== null) {
        clearTimeout(timer);
        NAV.classList.add('d-block');
      }
      timer = setTimeout(function() {
        NAV.classList.remove('d-block');
      }, 5000);
    }, false);
    nav {
      position: sticky;
      top: 0;
      display: none;
    }
    
    .d-block {
      display: block;
    }
    
    
    /* for demonstrationpurpose only */
    
    body {
      min-height: 100000vh;
    }
    <nav>THIS is the Navbar</nav>
    Login or Signup to reply.
  4. The following snippet should do the trick.

        let element = document.querySelector("#yourElement");
    
        const onScrollStop = callback => {
        let isScrolling;
            window.addEventListener(
                'scroll',
                e => {
                    element.style.display="unset"
                clearTimeout(isScrolling);
                isScrolling = setTimeout(() => {
                    callback();
                }, 5000);
                },
                false
            );
        };
            onScrollStop(() => {
                element.style.display="none"
        });
    

    Explanation: You want to add an eventlistener for scrolling the window, that sets a timeout of five seconds, before executing the onScrollStop function. Every time the user scrolls, we reset the timeout, because we want to wait five seconds, after the user STOPS scrolling, not when he stops for a just one or two seconds. If the condition (no scrolling for 5s) is met, we execute the onScrollStop function, which sets the display property of our header to none, making it disappear. Everytime the user scrolls, we set the header’s display property to unset, to make it appear. again.

    Hope this helps

    Happy coding!

    Login or Signup to reply.
  5. The logic is pretty simple:

    • const isHide = isOffTop && !isScrollUp
      Meaning: Hide the NAV when both the window.scrollY is greater than elNav.offsetHeight AND the scroll direction is "down"
    • If the scroll direction is "up", add a timeout that will hide the NAV after 5000ms
    • Clear that timeout on every scroll tick
    const elNav = document.querySelector("#nav");
    let lastScrollY = 0;
    let scrollTimeout;
    
    const toggleNav = () => {
    
      const isScrollUp = (lastScrollY - scrollY) > 0; // true when direction is up
      const isOffTop = scrollY > elNav.offsetHeight;  // scrolled >~70px from top
      const isHide = isOffTop && !isScrollUp;
      
      elNav.classList.toggle("nav-up", isHide);
      clearTimeout(scrollTimeout);
      
      if (isScrollUp) {
        scrollTimeout = setTimeout(() => {
          elNav.classList.add("nav-up");
        }, 5000);
      }
      
      lastScrollY = scrollY;
    };
    
    toggleNav(); // Do on init
    addEventListener("scroll", toggleNav); // and on scroll
    * { margin: 0; }
    body { min-height: 300vh; } /* Demo. To force scrollbars */
    
    #nav {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      padding: 2rem;
      background: gold;
      transition: translate 0.5s;
    }
    
    #nav.nav-up {
      translate: 0 -100%;
    }
    <nav id="nav">NAVIGATION</nav>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search