Mi Col
Mi Col

Reputation: 89

Script is working multiple times

https://codepen.io/Yarwaa/pen/QBKqxK

I just can't understand why my progress bar increases width and then reduces it back to 0, then make this action all over again.

Why my script is working multiple times and how to stop this action?

p.s If i stop my script with .off it won't increase width over and over again, but then the script will work only for the first element, and it actually will just ignore the second element.

I'll be glad for any help, i am actually lost in this

Code from Codepen:

<script>
  $(document).ready(function(){
    $(window).on('scroll', function(){

      $(".progress-bar").each(function () {
        var bottom_object = $(this).position().top + $(this).outerHeight();
        var bottom_window = $(window).scrollTop() + $(window).height();
      if( bottom_window > bottom_object ){
        $(this).animate( {width: $(this).attr('aria-valuenow') + '%' }, 2000 );
    }
      });
    });
  });
</script>
<body>
  <div class="block">
    SCROLL DOWN
  </div>
  <div class="progress" id="progress">
    <div class="progress-bar progress-bar-striped bg-success" id="progress-bar" role="progressbar" style="width: 0" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
  <div class="block">
    SCROLL DOWN
  </div>
  <div class="progress" id="progress">
    <div class="progress-bar progress-bar-striped bg-success" role="progressbar" style="width: 0" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
</body>

Upvotes: 2

Views: 168

Answers (1)

Rylee
Rylee

Reputation: 1656

Basically what's happening is that each time you scroll into the elements view, you're adding another animation event which seems to be causing the progress-bars to get stuck in a loop as they're trying to re-adjust to one another

One way to fix this would be to determine if the animation had occurred yet.

An example using the data method in jQuery

$(".progress-bar").each(function(){
    //Setup the data for each .progress-bar
    $(this).data('scrollInitialised',false);
});
$(window).on('scroll', function(){
    $(".progress-bar").each(function () {
        var $this= $(this);

        //Check if the progress bar animation has been initialised yet
        if($this.data('scrollInitialised') === false){

            var bottom_object = $this.position().top + $this.outerHeight(),
                bottom_window = $(window).scrollTop() + $(window).height();

            //If it has not been initialised, check if it is within view
            if( bottom_window > bottom_object ){
                //Progress bar is in view, now we can animate
                $this.animate( {width: $this.attr('aria-valuenow') + '%' }, 2000 );

                //Set scrollInitialised to true so that we do not attempt to re-animate the scrollbar again
                $this.data('scrollInitialised',true);

            }

        }

    });
});

By checking if the .progress-bar element has had the scrollInitialised set or not, you can prevent multiple animations being set on the element

Upvotes: 4

Related Questions