Skip to content

Instantly share code, notes, and snippets.

@vxhviet
Last active July 25, 2023 12:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vxhviet/6e3ebef1f823ed6c8f224f86f8868224 to your computer and use it in GitHub Desktop.
Save vxhviet/6e3ebef1f823ed6c8f224f86f8868224 to your computer and use it in GitHub Desktop.

[JavaScript] - Sticky Navigation - Intersection Observer API

SOURCE

<header class="header">
    <nav class="nav">
//   ....
    </nav>
</header>

// A section in the page
<section class="section" id="section--1">
//    ...
</section>
// Old way
/* const section1 = document.querySelector('#section--1');

const initialCoords = section1.getBoundingClientRect();
console.log(initialCoords);

// this works but it creates a lot of function
window.addEventListener('scroll', function () {
  console.log(window.scrollY);

  if (window.scrollY > initialCoords.top) nav.classList.add('sticky');
  else nav.classList.remove('sticky');
}); */

// New way with Intersection Observer API
const header = document.querySelector('.header');
const navHeight = nav.getBoundingClientRect().height;

const stickyNav = function (entries) {
  const [entry] = entries; // equivalent to `const entry = entries[0]`
  // console.log(entry);

  if (!entry.isIntersecting) nav.classList.add('sticky');
  else nav.classList.remove('sticky');
};

const headerObserver = new IntersectionObserver(stickyNav, {
  root: null,
  threshold: 0, // percentage of intersection that the observer callback (`stickyNav`) will be called
  rootMargin: `-${navHeight}px`, // stick the nav bar before it entering the content so that content doesn't get covered
});

headerObserver.observe(header);

// More explanation for the `threshold`.
// Is the threshold is 0.1 (10%), then everytime the `header` is overlapped (intersected) with
// the viewport 10%, the callback (`stickyNav`) will be called.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment