Sackadelic
Sackadelic

Reputation: 1019

Why is Intersection Observer adding class to all observed elements upon intersection of first element?

Pardon my ignorance, as I'm learning. I'm working on getting divs with the class of .entry to animate upon intersection with the Intersection Observer by adding the class of .entry-animation to them.

I've never worked with selecting all elements and animating before. Upon the first intersection, all elements simultaneously animate. What am I doing wrong?

Here's the demo:

JSFiddle

Here's the HTML:

  <div id="content-container">
    <div class="content">

      <div class="entry">
        <h2>
          Title of Post 1
        </h2>
        <p>
          Some content here on each entry
        </p>
      </div>
      <div class="entry">
        <h2>
          Title of Post 2
        </h2>
        <p>
          Some content here on each entry
        </p>
      </div>
      <div class="entry">
        <h2>
          Title of Post 3
        </h2>
        <p>
          Some content here on each entry
        </p>
      </div>
      <div class="entry">
        <h2>
          Title of Post 4
        </h2>
        <p>
          Some content here on each entry
        </p>
      </div>
      <div class="entry">
        <h2>
          Title of Post 5
        </h2>
        <p>
          Some content here on each entry
        </p>
      </div>
      <div class="entry"></div>
    </div>
  </div>

Here's the CSS:

body {
  background: #FFF;

}

.entry {
  background: #f6f6f6;
  text-align: center;
  padding: 5%;
  margin: 5%;
  border: 1px solid #ccc;
  border-radius: 15px;
  box-shadow: 0 4px 5px #cecece;
}


.entry-animation {
    animation: 2s fadeIn-1;
    animation-fill-mode: both;
}

@keyframes fadeIn-1 {
    0% {
        transform: translateY(20%);
        opacity: 0;
}
    100%{
        transform: translateY(0);
        opacity:1;
    }
}

Here's the JS:

const options = {
  threshold: 0.4,
};

const blogs = document.querySelectorAll('.entry');

const observer = new IntersectionObserver(function(entries, observer) {

  entries.forEach((entry) => {

    if (!entry.isIntersecting) {
      return;
    }
    blogs.forEach(blog => blog.classList.add('entry-animation'));


  },options);
});

blogs.forEach(blog => observer.observe(blog));

Upvotes: 1

Views: 785

Answers (1)

palaѕн
palaѕн

Reputation: 73906

You can easily fix this issue by replacing:

blogs.forEach(blog => blog.classList.add('entry-animation'));

with

entry.target.classList.add('entry-animation')

inside entries.forEach() loop. The issue here is basically we just need to add the animation class to only the elements which are in view using entry.target, instead of adding them to all at once.

Working Demo

Upvotes: 2

Related Questions