23

The IntersectionObserver is triggered when an element is visible in the viewport for a certain amount (0-100%). This means, when the element is already 100% in the viewport it does not trigger anymore, as there is no change on the threshold.

I have a element that has a height of 200vh and I want the IntersectionObserver to trigger, when I scroll over this element. So the element is always 100% inside the viewport.

Is there a way to trigger the observer while scrolling over the element?

I cannot use the scroll event, as I am using a CSS scroll-snap, which causes the event to be swallowed by the browser, before JS can detect it.

s1gr1d
  • 385
  • 3
  • 11
  • I have a similar problem with an infinite table scroll. I have observers before and after the table for prev and next page. The problem is once the observer is visible the callback no longer triggers. The clunky solution I came up with is to scroll 1px up or down - as the case may be, thus forciing the observer callback to fire again on scroll. – Matanya Apr 15 '20 at 08:16

1 Answers1

0

Hopefully I was able to grasp your challenge here, so I'll attempt to propose a solution that should work for your use case, even though there's no code to use as a reference.

From my understanding you're using scroll-snap to snap sections as the user interacts by doing scroll and your intention is to have the Intersection Observer to trigger as the users move from section to section.

In the following example you'll see how sections are being snapped but the debugger shows which section is being shown to the user.

const debuggerSpan = document.querySelector('#current-section');
const sections = [...document.querySelectorAll('.scroll-snap-item')];
const div = document.querySelector('.scroll-snap-container');

/*
 * This method will get called any time a section touches the top
 * of the viewport.
 */
const intersectionDetected = (entries, observer) => {
  entries.forEach((entry) => {
    const {
      innerText
    } = entry.target;

    if (!entry.isIntersecting) return;

    // Making it obvious that the current section is correct.
    debuggerSpan.innerText = innerText;

  });
};

const observer = new IntersectionObserver(intersectionDetected, {

  /*
   * Root should be div and not the default (doc).
   */
  root: div,

  /*
   * Negative margin from the bottom creates an invisible line
   * to detect intersections.
   * 
   * The reason why the recommendation is to use -1% and -99% is to
   * avoid the race condition between two intersections happening
   * (AKA the section about to be out of the viewport and the section
   * about to enter the viewport).
   */
  rootMargin: '-1% 0% -99% 0%',

  /*
   * Default value but making it explicit as this is the 
   * only configuration that works.
   */
  threshold: 0 
});


sections.forEach(section => observer.observe(section));
.scroll-snap-item {
  height: 100vh;
  display: grid;
  place-items: center;
  font-size: 4rem;
  scroll-snap-align: start;
}

.scroll-snap-container {
  scroll-snap-type: y mandatory;
  overflow-y: scroll;
  height: 100vh;
}


/* Decorative stuff below*/

.scroll-snap-item:nth-child(odd) {
  background-color: gray;
}

aside {
  position: fixed;
  font-size: 1.6rem;
  bottom: 16px;
  right: 16px;
  background-color: #333;
  color: white;
  padding: 16px;
  border-radius: 32px;
}
<div class="scroll-snap-container">
  <section class="scroll-snap-item">1</section>
  <section class="scroll-snap-item">2</section>
  <section class="scroll-snap-item">3</section>
  <section class="scroll-snap-item">4</section>
  <section class="scroll-snap-item">5</section>
  <section class="scroll-snap-item">6</section>
</div>

<aside>Current section: <span id="current-section"></span></aside>

I wrote a couple of practical posts that cover what's behind all this and what was the thought process to address this situation. Please feel free to give it a read and leave a comment if things are not clear enough:

Both are quick reads and should provide everything you need to tackle this and even more complex problems with the Intersection Observer. Also, feel free to play around with this tool I wrote called The Intersection Observer Playground where you can try out different configurations and see how they affect the intersection triggers.

Hope this is helpful!

wilsotobianco
  • 1,360
  • 14
  • 19