DEV Community

Markus Tiefenbacher for Blue Tomato Dev

Posted on

Dear appear.js, I have met someone new. Her name is IntersectionObserver.

appear.js IntersectionObserver Meme

Dear appear.js, I have met someone new. It was more or less a good time with you. But I want to break up and you have to leave your stack.

The new one? Her name's IntersectionObserver. She is nice to me. She is smart, pretty syntax and very fast in doing things. I think I will have a good time with her.

Enough with joking.
At blue-tomato.com, we used some jQuery based image lazy loading library and appear.js for lazyloading things and doing effect based on elements in the viewpoint.

Both libraries listen on the scroll event and looking if the actual scroll position is in the range of the given elements position.

This technic was the default for long time, but since IntersectionObserver comes up, it was clear to switch sometimes to this. The main problem with the old method was the listing on the scroll-event was very expensive to browser performance.

Example

Making a navigation bar sticky with appear.js

In this example, after the .main-content became visible, the .navigation bar will get the CSS class .navigation--sticky and will become sticky. When .main-content disappers (e.g. by scrolling back to the top of the page) the .navigation bar will become static by removing the .navigation--sticky class.

appear({
  elements: function elements() {
    return document.querySelectorAll('.main-content');
  },
  appear: function appear() {
    $(".navigation").addClass('.navigation--sticky');
  },
  disappear: function appear() {
    $(".navigation").removeClass('.navigation--sticky');
  }
});
Enter fullscreen mode Exit fullscreen mode

Making a navigation bar sticky with InteractionObserver

With InteractionObserver this would work in this way:

var element = document.querySelector('.main-content');
if(element) {
  let observer = new IntersectionObserver(entries => {
    entries.forEach(element => {
      if(element.intersectionRatio > 0) {
        $(".navigation").addClass('.navigation--sticky');
      } else {
        $(".navigation").removeClass('.navigation--sticky');
      }
    });
  }, { rootMargin: '0px 0px', threshold: 0.00 });

  observer.observe(element);
}
Enter fullscreen mode Exit fullscreen mode

Whats that rootMargin and thresold?

Appear.js has only some "bounds" option to let it fire some pixels before the element is really in the viewport. IntersectionObserver has a really powerful and flexible method to control this via the root/rootMargin and thresold options. Have an eye on this article from Smashing Magazine where Denys Mishonnuc explains this very detailed: https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/#intersectionobserver-initialization

Top comments (0)