bfintal / Counter-Up2

Counter-Up is a lightweight module that counts up to a targeted number when the number becomes visible.
MIT License
193 stars 65 forks source link

Only counts the first element with the class "counter" #13

Open paulhoppewhk opened 2 years ago

paulhoppewhk commented 2 years ago

I have three numbers next to each other I want to count up, but only the first one is counting. I tested this with adding an fourth one on top and only that one was counted. How can I archive that all numbers with the "counter" class get counted up?

I was using the previevs version "counterUp" and all numbers where counted but, but I had an issue that the final numbers change after scrolling, that is why I switched to "counterUp 2.

RobertHowdle commented 2 years ago

I've also found this issue.

Using this with Wordpress ACF Repeater Fields and I have 4 columns in a loop. Only the first is using the counter, the rest do not.

valeriaedw commented 2 years ago

Same

tripleten commented 2 years ago

Had the same issue, used the following code to make it work-

const counters = document.querySelectorAll( '.counter' );
for(const el of counters) {
    counterUp( el, {
        duration: 1000,
        delay: 16,
    })
}
tripleten commented 2 years ago

Same

Please check my last message.

joelveloso commented 2 years ago

From the example in the readme file with Intersection Obersver:

const callback = entries => {
    entries.forEach( entry => {
        const el = entry.target
        if ( entry.isIntersecting ) ) {
            counterUp( el, {
                duration: 2000,
                delay: 16,
            } )
        }
    } )
}

const IO = new IntersectionObserver( callback, { threshold: 1 } )

const el = document.querySelector( '.counter' )
IO.observe( el )

This only targets one element.

If you want to add to multiple elements you need to add a loop inside the if statement.

Say you have the following in HTML:

<div class="counters">
  <span class="counter">10</span>
  <span class="counter">20</span>
  <span class="counter">30</span>
</div>

Then your javascript goes as follows:

  1. Include dependency

<script src="https://unpkg.com/counterup2@2.0.2/dist/index.js"></script>

  1. Add script to your js file or inline
<script type="text/javascript">

const counterUp = window.counterUp.default

const callback = entries => {
    entries.forEach( entry => {
        const el = entry.target
        if ( entry.isIntersecting && ! el.classList.contains( 'is-visible' ) ) {
                    for(const counter of counters) {
                      counterUp( counter, {
                          duration: 1000,
                          delay: 16,
                      })
                    el.classList.add( 'is-visible' )
                  }
        }
    } )
}

// observer
const IO = new IntersectionObserver( callback, { threshold: 1 } )

// First element to target
const el = document.querySelector( '.counter' )

// all numbers
const counters = document.querySelectorAll( '.counter' )
IO.observe( el )

</script>

This should work for you.

siavashvj commented 2 years ago

@joelveloso Thanks, that makes all elements with .counter count, however they count all simultaneously and not when each an one of the elements come into viewport. Any hints how to accomplish that?

maxms commented 2 years ago

To use on multiple elements throughout a page, give each a new class name (e.g. 'counter2, counter3, etc.) and amend the bottom of the initialization script like this:

const el = document.querySelector( '.counter' ); IO.observe( el ); const el2 = document.querySelector('.counter2'); IO.observe(el2); const el3 = document.querySelector('.counter3'); IO.observe(el3);

Ben-Atherton commented 2 years ago

@joelveloso Thanks, that makes all elements with .counter count, however they count all simultaneously and not when each an one of the elements come into viewport. Any hints how to accomplish that?

I'd also be keen on this, could anyone provide an example please?

peterjrees commented 1 year ago

The solution by @joelveloso works for me however on pages that do not have the counter I get the following error:

Uncaught TypeError: Failed to execute 'observe' on 'IntersectionObserver': parameter 1 is not of type 'Element'.

Any ideas on how to address this?