1

Does anyone know how to start the number counter animation when you scroll to a specific parent id like #counter-container?

$(window).scroll(startCounter);

function startCounter() {
  if ($(window).scrollTop() > 200) {
    $(window).off("scroll", startCounter);
    $('.count').each(function() {
      var $this = $(this);
      jQuery({
        Counter: 0
      }).animate({
        Counter: $this.text().replace(/,/g, '')
      }, {
        duration: 1000,
        easing: 'swing',
        step: function() {
          $this.text(commaSeparateNumber(Math.floor(this.Counter)));
        },
        complete: function() {
          $this.text(commaSeparateNumber(this.Counter));
          //alert('finished');
        }
      });
    });

    function commaSeparateNumber(val) {
      while (/(\d+)(\d{3})/.test(val.toString())) {
        val = val.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
      }
      return val;
    }
  }
}
#counter-container {
  margin-top: 1000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Scroll down...
<div id="counter-container">
  <span class="count">6,000</span>
  <span class="count">600</span>
  <span class="count">60</span>
</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
mgonz
  • 45
  • 1
  • 8

1 Answers1

1

To determine if scrolling has gone past a certain element you can compare the window scroll position + height, to the vertical offset of the target element. Try this:

$(window).scroll(startCounter);

function startCounter() {
  let scrollY = (window.pageYOffset || document.documentElement.scrollTop) + window.innerHeight;
  let divPos = document.querySelector('#counter-container').offsetTop;

  if (scrollY > divPos) {
    $(window).off("scroll", startCounter);

    $('.count').each(function() {
      var $this = $(this);
      jQuery({
        Counter: 0
      }).animate({
        Counter: $this.text().replace(/,/g, '')
      }, {
        duration: 1000,
        easing: 'swing',
        step: function() {
          $this.text(commaSeparateNumber(Math.floor(this.Counter)));
        },
        complete: function() {
          $this.text(commaSeparateNumber(this.Counter));
          //alert('finished');
        }
      });
    });

    function commaSeparateNumber(num) {
      return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
  }
}
#spacer {
  height: 1000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Scroll down...
<div id="spacer"></div>
<div id="counter-container">
  <span class="count">6,000</span>
  <span class="count">600</span>
  <span class="count">60</span>
</div>

Also note that I implemented a more robust version of your number grouping logic, taken from this answer.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • Thank you. this is only working on load where i am implementing it. Could the margin top be interfering with it? – mgonz Jun 10 '21 at 15:14
  • It works in Chrome, but possible that it's causing issues in other browsers. I updated the example to use a different method to force page content to scroll. – Rory McCrossan Jun 10 '21 at 15:16