3

I want to extend the code provided in this answer. The code there fades in an element when scrolling down and fades out an image when scrolling up but doesn't fade out when scrolling down. I want to implement all elements: fade in when scrolling down, fade out as element leaves the viewport, fade in when scrolling up and fade out as element leaves the viewport.

Mr.Rlover
  • 2,523
  • 3
  • 14
  • 32

1 Answers1

11

Instead of using jQuery and scroll event listener, you can use the Intersection Observer API to achieve the desired result.

You can adjust the threshold option of the IntersectionObserver according to your needs. This option is used to indicate at what percentage of the target's visibility the observer's callback should be executed. I have set it to 70%.

const observerOptions = {
  root: null,
  rootMargin: "0px",
  threshold: 0.7
};

function observerCallback(entries, observer) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // fade in observed elements that are in view
      entry.target.classList.replace('fadeOut', 'fadeIn');
    } else {
      // fade out observed elements that are not in view
      entry.target.classList.replace('fadeIn', 'fadeOut');
    }
  });
}

const observer = new IntersectionObserver(observerCallback, observerOptions);

const fadeElms = document.querySelectorAll('.fade');
fadeElms.forEach(el => observer.observe(el));
.fade {
  margin: 50px;
  padding: 50px;
  background-color: lightgreen;
  transition: opacity 0.7s ease-in;
}

.fadeOut { opacity: 0; }
.fadeIn { opacity: 1; }
<div class="container">
  <div class="fade fadeOut">Element 1</div>
  <div class="fade fadeOut">Element 2</div>
  <div class="fade fadeOut">Element 3</div>
  <div class="fade fadeOut">Element 4</div>
  <div class="fade fadeOut">Element 5</div>
  <div class="fade fadeOut">Element 6</div>
  <div class="fade fadeOut">Element 7</div>
  <div class="fade fadeOut">Element 8</div>
  <div class="fade fadeOut">Element 9</div>
  <div class="fade fadeOut">Element 10</div>
</div>
Yousaf
  • 27,861
  • 6
  • 44
  • 69