Using the Intersection Observer along with an Animated Number Counter

One issue with the code snippet provided is that the Counters do not stop at the same time. Is there a way to adjust the duration of the Counters? I've heard that the animate function in JQuery can be used to adjust the duration, but I'm curious about integrating that with Intersection Observer to ensure that animated numbers run only when they become visible.

const counterElements = document.querySelectorAll(".count");

// Counters
function counter(target, start, stop) {
  target.innerText = 0.1;
  const counterInterval = setInterval(() => {
    start += 0.1;
    const valueConverted = (Math.round(start * 100) / 100).toFixed(1);
    target.innerText = valueConverted;
    if (valueConverted == stop) {
      clearInterval(counterInterval);
    }
  }, 30);
}

function obCallBack(entries) {
  entries.forEach((entry) => {
    const { target } = entry;
    const stopValue = target.innerText;
    const startValue = 0;
    if (!entry.isIntersecting) return;
    counter(target, startValue, stopValue);
    counterObserver.unobserve(target);
  });
}

const counterObserver = new IntersectionObserver(obCallBack, { threshold: 1 });
counterElements.forEach((counterElem) => counterObserver.observe(counterElem));
.emptyspace{
  height:400px;
  }
<div class="emptyspace"></div>
<p class="count">5.2</p>
<p class="count">50.9</p>
</div>

Answer №1

Instead of using a fixed number, it is recommended to use a ratio.

const speed = 100;
const inc = Number(stop / speed);

const counterElements = document.querySelectorAll(".count");
const speed = 100; // adjust for desired speed

// Counter function
function counter(target, start, stop) {
  target.innerText = 0.1;
  const counterInterval = setInterval(() => {
    const inc = Number(stop / speed);
    start += inc;
    const valueConverted = (Math.round(start * 100) / 100).toFixed(1);
    target.innerText = valueConverted;
    if (valueConverted == stop) {
      clearInterval(counterInterval);
    }
  }, 30);
}

function obCallBack(entries) {
  entries.forEach((entry) => {
    const { target } = entry;
    const stopValue = target.innerText;
    const startValue = 0;
    if (!entry.isIntersecting) return;
    counter(target, startValue, stopValue);
    counterObserver.unobserve(target);
  });
}

const counterObserver = new IntersectionObserver(obCallBack, { threshold: 1 });
counterElements.forEach((counterElem) => counterObserver.observe(counterElem));
.emptyspace{
  height:400px;
  }
<div class="emptyspace"></div>
<p class="count">5.2</p>
<p class="count">50.9</p>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Revamp the HTML page by automatically refreshing labels upon every Get request

My HTML webpage requires real-time updates for one or more labels. To achieve this, I have incorporated CSS and JS animations into the design. Currently, I am utilizing Flask to handle all the calls. I face a challenge where I need to consistently update ...

Utilizing .html() to convert JSON data into HTML content

I have thoroughly commented the code below in my attempt to retrieve JSON data and pass it to the 'results' div in my HTML view. However, this process seems to return nothing, making it challenging to debug since no output can be displayed on the ...

Error Found: Syntax Error - 'if' statement not recognized

if (fname == null || fname == "") { Receiving an error message "uncaught syntax error:unexpected token if in line 13". The error indicates "SyntaxError: missing variable name" when using Javascript lint function validateRegistration() { var emailReg ...

Looking for a drag-and-drop solution using Vanilla Javascript, no need for jQuery

Looking for assistance with creating a click-and-drag solution for a background image using Vanilla Javascript. I came across a jQuery solution on Codepen, but I need help translating it into Vanilla Javascript. Draggable.create(".box", { ...

Sorting complex strings in Typescript based on the dates contained within them

How can I sort a list of 2 strings with dates inside them so that the earlier one always comes first? The date is always after the second comma. For example, const example = ["AAA,5,2020-09-17T21:14:09.0545516Z", "AAA,0,2020-09-03T20:38:08. ...

What strategies would you use to put in place conditional imports in a way that is reminiscent of ReactNative

Is there a way to implement conditional imports in other projects similar to how React Native imports Android or iOS specific classes using *.android.js and *.ios.js? If I wanted to have different classes for development and production purposes, could I u ...

When using NodeJS and MongoDB together, a POST request may receive a 404 error code

Despite having all the routes set up correctly, I'm encountering a 404 error when trying to send a POST request. I've searched through numerous similar questions but haven't come across a solution that addresses my specific issue. Below is ...

Issue with passing boolean parameter in Javascript not functioning properly

I have a function that contains multiple if statements, designed to execute when a parameter is true. However, I've noticed that passing false as a parameter does not seem to have any effect. Can you help me figure out what I'm doing wrong? fu ...

Using this functionality on a ReactJS Functional Component

Hey everyone, I'm fairly new to using React and I'm currently trying to wrap my head around some concepts. After doing some research online, I stumbled upon a situation where I am unsure if I can achieve what I need. I have a functional componen ...

An issue has been identified with the functionality of an Ajax request within a partial view that is loaded through another Ajax request specifically in

Here is the current scenario within my ASP.NET MVC application: The parent page consists of 3 tabs, and the following javascript code has been implemented to handle the click events for each tab: Each function triggers a controller action (specified in t ...

The link containing special characters like % cannot access the api

I am facing an issue with retrieving a signUrl from S3. When I make the call with special characters like %, my code does not parse it correctly and I receive a 404 not found error. Here is the ajax request I am using: My API setup: app.get('/websi ...

Attempting to iterate over the array of objects in order to discover a match

I am currently working with an object structure that resembles the one shown in the image linked below. My goal is to compare the inner object properties (such as massing type id) with existing IDs. If there is a match, I want to retrieve the name of that ...

Iterating through JSON objects in JavaScript using 'Foreach'

After receiving a JSON Object from my PHP script, I am trying to extract specific data using JavaScript. { "Data":{ "Recipes":{ "Recipe_7":{ "ID":"7", "TITLE":"Wu ...

Having difficulties with the edit function in JavaScript To Do Application

After creating an edit button to modify a task, it functions properly for the initial task I create. However, when attempting to edit subsequent tasks, the edit function defaults back to modifying the input of the first task instead. With each new ta ...

Tips for effectively invoking a method in a Vue component

As a Vue2 beginner, I am currently working with the Vue CLI and following the structure generated from it. My goal is to submit form data, but I keep encountering a warning and error: [Vue warn]: Property or method "onSubmit" is not defined on the insta ...

Preventing the build-up of opacity animations in jQuery: Tips and tricks

-I have two division tags in my code. <div id="div1">Hover over me to show Div2</div> <div id="div2">Div2</div> -I used CSS to set the opacity of div2 to 0. -My goal is for div2's opacity to change from 0 to 1 when hovered o ...

Integrating Material-UI Dialog with Material-table in ReactJS: A Step-by-Step Guide

I have implemented the use of actions in my rows using Material-Table, but I am seeking a way for the action to open a dialog when clicked (Material-UI Dialogs). Is there a way to accomplish this within Material-Table? It seems like Material-UI just appen ...

Variability in Focus Behavior while Opening a URL in a New Tab with window.open()

Here is a code snippet I have been using to open a URL in a new tab: window.open(urlToOpen, '_blank', 'noopener noreferrer'); The issue I am experiencing is that when this code is executed for the first time, it opens the URL in a new ...

How to retrieve a JSON value without a key using jQuery

I am struggling to fetch JSON using jQuery. If anyone can help me figure out the mistake in my code that would be greatly appreciated. The data.json file contains { "value1", "value2", "value3", "value4" } Here is my jQuery code $.getJSON( "data.js ...

Encountering an error with Nested MaterialUI Tabs while attempting to open the second level of tabs

I am attempting to create nested horizontal tabs using MaterialUI. This means having a first level of tabs that, when clicked on, opens a second level of tabs. Here is a link to a working example of the code: https://codesandbox.io/s/sweet-pasteur-x4m8z?f ...