Search code examples
javascriptjquery-selectorsintersection-observer

Call Back IntersectionObserver function for different different id with a single function


I want to create a entrance effects for element when it's on view port for different ids. I have 3 different ids #fadeAppear #slideAppear #zoomAppear with different css property. I want to call a single function for all those three individual ids. The code works fine for single ID. Instead of writing three separate functions for the three IDs, I'm going to do the job with one function. I have tried various way but failed. It just applied for first ID. my code is given bellow:

document.addEventListener('DOMContentLoaded', function() {
  const appear = document.querySelector('#fadeAppear, #slideAppear, #zoomAppear');
  const cb = function(entries) {
    entries.forEach(entry => {
     if (entry.isIntersecting) {
      entry.target.classList.add('inview');
        } else {
          entry.target.classList.remove('inview');
        }
     });
   }
     const io = new IntersectionObserver(cb);
     io.observe(appear);
});
#wrap{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
#fadeAppear {
    background: red;
    -webkit-transition: all 0.8s;
    transition: all 0.8s;
    opacity: 0;
    -webkit-transform: translateY(40px);
    transform: translateY(40px);
}

#slideAppear {
    background: green;
    -webkit-transition: all 0.8s;
    transition: all 0.8s;
    opacity: 0;
    -webkit-transform: translateX(100%);
    transform: translateX(100%);
}

#zoomAppear {
     background: orange;
    -webkit-transition: all 0.8s;
    transition: all 0.8s;
    opacity: 0;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
}

#fadeAppear.inview,
#slideAppear.inview,
#zoomAppear.inview {
    opacity: 1;
    -webkit-transform: none;
    transform: none;
    -webkit-transition-delay: 0.3s;
    transition-delay: 0.3s;
}
<div id="wrap">
  <div id="fadeAppear">Fade Appear</div>
  <div id="slideAppear">Slide Appear</div>
  <div id="zoomAppear">Zoom Appear</div>
 </div>

I also tried by individual id. but nothing happened.

function handleIntersection(entries, observer) {
entries.forEach(entry => {
    if (entry.isIntersecting) {
        entry.target.classList.add("inview");
    } else {
        entry.target.classList.remove("inview");
    }
});
}

const observer = new IntersectionObserver(handleIntersection);

const element1 = document.getElementById("#fadeAppear");
const element2 = document.getElementById("#slideAppear");
const element3 = document.getElementById("#zoomAppear");

observer.observe(element1);
observer.observe(element2);
observer.observe(element3);

Solution

  • The reason is that, querySelector() returns the first Element within the document that matches the specified selector.

    You need querySelectorAll() which returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors. Use forEach() to iterate each element and observe individually.

    Try the following way:

    document.addEventListener('DOMContentLoaded', function() {
      //select all elements with the specified IDs
      const elements = document.querySelectorAll('#fadeAppear, #slideAppear, #zoomAppear');
    
      const cb = function(entries) {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            entry.target.classList.add('inview');
          } else {
            entry.target.classList.remove('inview');
          }
        });
      }
    
      const io = new IntersectionObserver(cb);
      //observe each element individually
      elements.forEach(element => {
        io.observe(element);
      });
    });