DEV Community 👩‍💻👨‍💻

Hunter Chang
Hunter Chang

Posted on • Updated on

Show/Hide Element on Scroll w/ Vanilla JS

Here's a quick script in Vanilla JavaScript that will add/remove a class based on if you're scrolling up or down on a page. In the past, I've used a widget called Headroom.js but I wanted to see if I could replicate the basics from scratch.

Here is the result:
Custom Headroom Demo (view source)

Take a look at the index.html source code.

The main script that runs is this block here:

let scrollPos = 0;
const nav = document.querySelector('.site-nav');

function checkPosition() {
  let windowY = window.scrollY;
  if (windowY < scrollPos) {
    // Scrolling UP
    nav.classList.add('is-visible');
    nav.classList.remove('is-hidden');
  } else {
    // Scrolling DOWN
    nav.classList.add('is-hidden');
    nav.classList.remove('is-visible');
  }
  scrollPos = windowY;
}

window.addEventListener('scroll', checkPosition);
Enter fullscreen mode Exit fullscreen mode

We add a scroll event listener to the window and fire off the checkPosition function every time the user scrolls on the page.

Looking at function checkPosition(){} we first get the window.scrollY position, which is how far in pixels we are from the top of the page. We then compare it to the scrollPos variable which will get updated to the new window.scrollY position after each scroll.

If windowY is less than the previous scrollPos then we know that we are scrolling up and we can add a class to our nav element accordingly. In this case, we want our menu to show when scrolling up and hide when scrolling down.

That's basically it, but we'll want to add some sort of throttle so that we don't fire off events like crazy during long scroll sessions. For this we add a debounce function which will make sure it waits 10ms before firing.

We can replace our window event listener like this:

function debounce(func, wait = 10, immediate = true) {
  let timeout;
  return function() {
    let context = this, args = arguments;
    let later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    let callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

window.addEventListener('scroll', debounce(checkPosition));
Enter fullscreen mode Exit fullscreen mode

All the JavaScript needs to do is add or remove a class to our element, and our CSS will handle the rest.

I know this isn't as flexible as Headroom.js but it's a slimmed down version that might be a good intro into scroll events.

Check out https://codebushi.com/ for more of my web development tips and resources.

Top comments (1)

Collapse
marypieroszkiewicz profile image
Mary Pieroszkiewicz

Truly great stuff.

Could you add that when scrolling down and up the element is hidden. Thank You.

🌚 Life is too short to browse without dark mode