How to make a javascript function that updates numbers without clearing the numbers styles when resetting the numbers to 0?
Tags: javascript, webdev, beginners, coding
Published: 2023-07-27 20:04:30

I use a funnel builder called systeme.io to make a page with an update numbers animation. This function I wrote is able to update numbers when you scroll down until you reach them and see them on the screen.

You can see this animation on [this page](https://lesfunnelsbuilders.systeme.io/codage)

=> You can scroll down until you reach the numbers. Then refresh the page to see the numbers' native styles. Then, scroll up and down again until you reach the numbers. As you can see the numbers become black when the function starts.

Indeed, in systeme.io funnel builder, there is a drag & drop no code system that allows us to put and style elements. Each element has an id. So, we can insert some code through this builder and target the element by its id in our code.

I wrote a JavaScript code to activate a `updateCount()` function on 4 elements that have the following ids: `headline-e6423da8`, `headline-77ad9299`, `headline-8255ec52` and `headline-5e08a0cb`.

Here is the complete code:

```
class Counter {
  constructor(id, target, speed, appendString) {
    this.id = id;
    this.target = target;
    this.speed = speed || 1000;
    this.counter = document.querySelector(`#${id}`);
    this.count = 0;
    this.appendString = appendString || '';
  }

  updateCount() {
    if (this.count < this.target) {
      this.counter.innerText = `${this.count} ${this.appendString}`;
      this.count++;
      setTimeout(() => this.updateCount(), this.speed);
    } else {
      this.counter.innerText = `${this.target} ${this.appendString}`;
    }
  }
}

const ids = [
  'headline-e6423da8',
  'headline-77ad9299',
  'headline-8255ec52',
  'headline-5e08a0cb'
];

const values = [];

for (const id of ids) {
  const value = document.querySelector(`#${id}`).innerText;
  values.push(value);
}

const counters = [
  new Counter('headline-e6423da8', values[0], 10, ''),
  new Counter('headline-77ad9299', values[1], 15, ''),
  new Counter('headline-8255ec52', values[2], 20, '%'),
  new Counter('headline-5e08a0cb', values[3], 25, '+')
];

window.addEventListener('scroll', () => {
  counters.forEach(counter => {
    if (
      pageYOffset >
        counter.counter.offsetTop - counter.counter.offsetHeight - 500 &&
      counter.activated === false
    ) {
      counter.counter.innerText = 0;
      counter.count = 0;
      counter.activated = true;
      counter.updateCount();
    } else if (
      pageYOffset <
        counter.counter.offsetTop - counter.counter.offsetHeight - 500 ||
      (pageYOffset === 0 && counter.activated === true)
    ) {
      counter.counter.innerText = 0;
      counter.activated = false;
    }
  });
});
```

I managed to set the maximum targeted numbers through the funnel's native builder. So, if I set 150, 227, 91 and 31 respectively in each element in this application's builder, the page will update the numbers and stop when they reach the numbers set in the builder.

Here is the part of the code that does this:

```
const ids = [
  'headline-e6423da8',
  'headline-77ad9299',
  'headline-8255ec52',
  'headline-5e08a0cb'
];

const values = [];

for (const id of ids) {
  const value = document.querySelector(`#${id}`).innerText;
  values.push(value);
}

const counters = [
  new Counter('headline-e6423da8', values[0], 10, ''),
  new Counter('headline-77ad9299', values[1], 15, ''),
  new Counter('headline-8255ec52', values[2], 20, '%'),
  new Counter('headline-5e08a0cb', values[3], 25, '+')
];
```

However, when the function starts, it resets the numbers to 0 and clears their styles. For example, let's say I set the color of yellow to these 4 elements on the builder. The problem is that, on the screen, the numbers will be reset to 0 and the color of black, then they will be updated from 0 to the maximum targeted numbers with the black color.

I would like the numbers to be updated without losing the native styles I set to them before via the builder. Besides that, the numbers should be able to inherit the style changes I would make through the builder and display the updated numbers with their new styles.

I try to get my inspiration from the logic I did when I fetched the values of these 4 elements by their ids:

```
const ids = [
  'headline-e6423da8',
  'headline-77ad9299',
  'headline-8255ec52',
  'headline-5e08a0cb'
];

const values = [];

for (const id of ids) {
  const value = document.querySelector(`#${id}`).innerText;
  values.push(value);
}

const counters = [
  new Counter('headline-e6423da8', values[0], 10, ''),
  new Counter('headline-77ad9299', values[1], 15, ''),
  new Counter('headline-8255ec52', values[2], 20, '%'),
  new Counter('headline-5e08a0cb', values[3], 25, '+')
];
```

And I tried to write a code that would fetch and extract the styles of these values, then display the numbers with these inherited styles:

```
const styles = [];

for (const id of ids) {
  const style = document.querySelector(`#${id}`).innerText;
  styles.push(style);
}

const counters = [
  new Counter('headline-e6423da8', values[0].styles[0], 10, ''),
  new Counter('headline-77ad9299', values[1].styles[1], 15, ''),
  new Counter('headline-8255ec52', values[2].styles[2], 20, '%'),
  new Counter('headline-5e08a0cb', values[3].styles[3], 25, '+')
];
```

Obviously, this method is not correct.

I tried to replace `innerText` by `textContent`, but I did not get what I expected.

I expected to extract the styles and append them to the values, so that the code displays the updated the numbers with their respective styles.