Javascript animation trigger only when reaching a certain part of webpage

Viewed 400

I want a counter animation which is triggered only when webpage reaches that certain part. For example, the js file would be this. I want the count to start only when the page reaches that certain section.

    const counters = document.querySelectorAll('.counter');
    const speed = 200; // The lower the slower

    counters.forEach(counter => {
    const updateCount = () => {
        const target = +counter.getAttribute('data-target');
        const count = +counter.innerText;

        // Lower inc to slow and higher to slow
        const inc = target / speed;

        // console.log(inc);
        // console.log(count);

        // Check if target is reached
        if (count < target) {
            // Add inc to count and output in counter
            counter.innerText = count + inc;
            // Call function every ms
            setTimeout(updateCount, 1);
        } else {
            counter.innerText = target;
        }
    };

    updateCount();
});
3 Answers

Yo can easily do it using Jquery

$(document).ready(function() {
  $(window).scroll(function() {
    if ($(document).scrollTop() > 50) {
      $("div").css("background-color", "#111111");
    } else {
      $("div").css("background-color", "transparent");
    }
  });
});
div {
  height: 120vh;
  transition-duration: 0.5s;
}
<div>
  Scroll to Change Background
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>

You can use Intersection Observer to do that

const $observeSection = document.querySelector('#second');
const options = {
  root: null,
  rootMargin: '0px',
  threshold: 0.5
};

const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.intersectionRatio > options.threshold) {
      $observeSection.classList.add('yellow');
    } else {
      $observeSection.classList.remove('yellow');
    }
  });
}, options);

observer.observe($observeSection);
main {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
}
main section {
  width: 100vw;
  height: 100vh;
}
#first {
  background: red;
}
#second {
  background: blue;
}
#third {
  background: green;
}
.yellow {
  background: yellow!important;
}
<main>
  <section id="first"></section>
  <section id="second"></section>
  <section id="third"></section>
</main>

In this example, I observe the second section, and when the scroll come to the middle of the section (threshold: 0.5), I add a class to change the color of this section.

Be careful if you need to handle legacies browsers as you can see here :

https://caniuse.com/#feat=intersectionobserver

You don't need jquery to achieve this. Here is a VanillaJS solution:

window.onscroll = (e) => {
    e.stopPropagation();
    window.pageYOffset > 50 && console.log("do smh");
}
Related