skip to Main Content

I have been experimenting with different combinations of HTML, CSS, and JavaScript that would give me an animated number counter on scroll with a symbol next to each number (+, %, etc.). I finally found the right combination; however, it is not perfect yet. I would like to add a comma to numbers 1,000 and above, but when I add commas in the HTML, it produces a NaN output. I am very new to JavaScript and I have no clue what to add or fix in my current code to show commas.

Would someone be able to rewrite my current code to show commas or guide me in how to do this? I would greatly appreciate any assistance!

<script>
function inVisible(element) {
  //Checking if the element is
  //visible in the viewport
  var WindowTop = $(window).scrollTop();
  var WindowBottom = WindowTop + $(window).height();
  var ElementTop = element.offset().top;
  var ElementBottom = ElementTop + element.height();
  //animating the element if it is
  //visible in the viewport
  if ((ElementBottom <= WindowBottom) && ElementTop >= WindowTop)
    animate(element);
}

function animate(element) {
  //Animating the element if not animated before
  if (!element.hasClass('ms-animated')) {
    var maxval = element.data('max');
    var html = element.html();
    element.addClass("ms-animated");
    $({
      countNum: element.html()
    }).animate({
      countNum: maxval
    }, {
      //duration 2 seconds
      duration: 2000,
      easing: 'linear',
      step: function() {
        element.html(Math.floor(this.countNum) + html);
      },
      complete: function() {
        element.html(this.countNum + html);
      }
    });
  }
}
//When the document is ready
$(function() {
  //This is triggered when the
  //user scrolls the page
  $(window).scroll(function() {
    //Checking if each items to animate are
    //visible in the viewport
    $("h2[data-max]").each(function() {
      inVisible($(this));
    });
  })
});
</script>

2

Answers


  1. Remove the commas when reading the HTML, add them back when displaying.

    function animate(element) {
      //Animating the element if not animated before
      if (!element.hasClass('ms-animated')) {
        var maxval = element.data('max');
        var html = element.html();
        element.addClass("ms-animated");
        $({
          countNum: parseInt(element.html().replace(/,/g, '')) // remove commas
        }).animate({
          countNum: maxval
        }, {
          //duration 2 seconds
          duration: 2000,
          easing: 'linear',
          step: function() {
            element.html((Math.floor(this.countNum) + html).toLocaleString());
          },
          complete: function() {
            element.html((Math.floor(this.countNum) + html).toLocaleString());
          }
        });
      }
    }
    
    Login or Signup to reply.
  2. You can format a locale-aware number via toLocaleString:

    function formatHeading(headingText, duration) {
      return `${Math.floor(duration).toLocaleString('en-US')} ${headingText}`;
    };
    

    Full example

    // When the document is ready
    $(function() {
      // This is triggered when the user scrolls the page
      $(window).scroll(function() {
        // Checking if each items to animate are visible in the viewport
        $("h2[data-max]").each(function() {
          animateIfVisible($(this));
        });
      })
    });
    
    function animateIfVisible($element) {
      // Checking if the element is visible in the viewport
      var windowTop = $(window).scrollTop();
      var windowBottom = windowTop + $(window).height();
      var elementTop = $element.offset().top;
      var elementBottom = elementTop + $element.height();
      // Animating the element if it is visible in the viewport
      if ((elementBottom <= windowBottom) && elementTop >= windowTop) {
        animate($element);
      }
    }
    
    function formatHeading(headingText, duration) {
      return `${Math.floor(duration).toLocaleString('en-US')} ${headingText}`;
    };
    
    function animate($element) {
      // Animating the element if not animated before
      if (!$element.hasClass('ms-animated')) {
        var maxValue = $element.data('max');
        var headingText = $element.text();
        $element.addClass("ms-animated");
        $({
          elapsedTime: 0
        }).animate({
          elapsedTime: maxValue
        }, {
          // Duration 2 seconds
          duration: 2000,
          easing: 'linear',
          step: function() {
            $element.text(formatHeading(headingText, this.elapsedTime));
          },
          complete: function() {
            $element.text(formatHeading(headingText, this.elapsedTime));
          }
        });
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    <h2 data-max="2000">Foo</h2>
    <h2 data-max="1000">Foo</h2>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search