Same intersection observer for multiple HTML elements

Ollie Williams picture Ollie Williams · Feb 25, 2019 · Viewed 8.9k times · Source

I am trying to make it so that as some text items stop overlapping a dark background, they will individually change color one by one as the user scrolls. All of the text items are position: fixed

EDIT: The MDN docs say (emphasis mine):

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element

I think this means there is no way to solve my problem because the elements I want to monitor for overlap are not children of the root I am specifying in the options object.

Is there any way to detect overlap if the overlapping element is not a child of the other element?

if ('IntersectionObserver' in window) {

    const options = {
        root: document.getElementById('flow-landing'),
        rootMargin: '0px',
        threshold: 0
      }


    var callback = function(entries, observer) { 
            entries.forEach(entry => {

                if (entry.isIntersecting) {
                    entry.target.style.color = "white";
                }
                else {
                    entry.target.style.color = null;
                }
            });
          };

    const observer = new IntersectionObserver(callback, options);

    var targets = [Array.from(document.querySelectorAll('.social-item')), Array.from(document.querySelectorAll('.additional-item'))].flat();

    targets.forEach(target => 
        observer.observe(target));
}

There aren't any console errors but the code isn't doing anything.

Answer

Ruslan Korkin picture Ruslan Korkin · Sep 18, 2020

you can do something like that, at least it helps me:

document.querySelectorAll('.social-item').forEach((i) => {
    if (i) {
        const observer = new IntersectionObserver((entries) => {
            observerCallback(entries, observer, i)
        },
        {threshold: 1});    
        observer.observe(i);
    }
})

const observerCallback = (entries, observer, header) => {
    entries.forEach((entry, i) => {
         if (entry.isIntersecting) {
             entry.target.style.color = "white";
         }
         else {
             entry.target.style.color = null;
         }
    });
};