2017-11-17 2 views
2

Ich habe es geschafft, einen einfachen stat Zähler von Null bis zu einem bestimmten Wert zu bekommen, wo es nur auf Seite Scroll aktiviert ist, aber es ist nicht genau, wie ich es anstrebte.Schleife durch jQuery-Elemente getrennt und animiere auf Seite Scroll

Das Problem ist, dass alle ".counter" -Elemente gleichzeitig abfeuern, sobald das erste Element in Sicht kommt, anstatt zu warten, bis jedes einzelne Element tatsächlich auf dem Bildschirm sichtbar ist. Sobald also das Fenster auf das enthaltene div trifft, gehen alle sofort los.

Ich möchte jeden einzelnen .counter warten, bis es vollständig sichtbar ist, bevor es abfeuert.

Hier ist, was ich bisher habe:

HTML:

<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<p>&nbsp;</p> 
<div id="stats"> 
    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="400"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 

    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="350"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 

    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="12"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 

    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="97"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 

    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="899"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 

    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="4"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 

    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="0"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 

    <div class="single-stat"> 
    <h6 class="top-line">title</h6> 
    <div class="stat-container"> 
     <h6 class="stat"><span class="counter" count="6"></span></h6> 
    </div> 
    <h6 class="bottom-line">bottom line</h6> 
    </div> 
</div> 

Und die jQuery ...

(function($) { 

    $(function() { 

    var $counters = $('.counter'); //contains all elements of counter class 

    var $window = $(window); 

    $window.on('scroll', function(e) { 
     $counters.each(function(i, elem) { //loop through each element 
     if ($(this).hasClass('counted')) // check if already animated 
      return; 
     animateCounter($(this)); 
     }); 
    }); 
    }); 

    function animateCounter(elem) { 
    var winTop = $(window).scrollTop(); // calculate distance from top of window 
    var winBottom = winTop + $(window).height(); 
    var elemTop = $(elem).offset().top; // element distance from top of page 
    var elemBottom = elemTop + $(elem).height(); 

    if ((elemBottom <= winBottom) && (elemTop >= winTop)) { 
     $('.counter').each(function() { 
     var $this = $(this); 
     jQuery({ 
      Counter: 0 
     }).animate({ 
      Counter: $this.attr('count') 
     }, { 
      duration: 3000, 
      step: function() { 
      $this.text(Math.ceil(this.Counter)); 
      } 
     }); 
     $this.removeClass('counter').addClass('counted'); 
     }); 
    } 
    } 
})(jQuery); 

Fiddle hier: https://jsfiddle.net/ahfL4jxr/11/

Danke voraus.

+0

Ausgabe zu $(elem)

ändern (glaube ich) '$ (this)' sind alle die '.counter' Elemente und da es sich um eine Klassenauswahl ist, es wird für alle laufen. Ich werde ein wenig herumstöbern und sehen, ob ich es beheben kann. – Gezzasa

+0

buchstäblich eine Änderung :). In meiner Antwort behoben – Gezzasa

Antwort

1

Ah, Sie waren so nah.

Sie zielen auf alle Elemente anstatt auf das Element in dem Argument, das Sie durchgedrückt haben.

In Ihrer animateCounter() Funktion $('.counter') sollte, ist https://jsfiddle.net/7xsv33hf/

0

Es gab einen Fehler in Ihrem Javascript in animateCounter() -Funktion, Sie haben eine unnötige foreach, weil in der Funktion, die Sie bereits das Element übergeben, müssen Sie animieren, wenn Sie es aufrufen.

(function($) { 
 

 
    $(function() { 
 

 
    var $counters = $('.counter'); //contains all elements of counter class 
 

 
    var $window = $(window); 
 

 
    $window.on('scroll', function(e) { 
 
     $counters.each(function(i, elem) { //loop through each element 
 
     if ($(this).hasClass('counted')) // check if already animated 
 
      return; 
 
     animateCounter($(this)); 
 
     }); 
 
    }); 
 
    }); 
 

 
    function animateCounter(elem) { 
 
    var winTop = $(window).scrollTop(); // calculate distance from top of window 
 
    var winBottom = winTop + $(window).height(); 
 
    var elemTop = $(elem).offset().top; // element distance from top of page 
 
    var elemBottom = elemTop + $(elem).height(); 
 

 
    if ((elemBottom <= winBottom) && (elemTop >= winTop)) { 
 
     var $this = $(elem); 
 
     jQuery({ 
 
     Counter: 0 
 
     }).animate({ 
 
     Counter: $this.attr('count') 
 
     }, { 
 
     duration: 3000, 
 
     step: function() { 
 
      $this.text(Math.ceil(this.Counter)); 
 
     } 
 
     }); 
 
     $this.removeClass('counter').addClass('counted'); 
 
    } 
 
    } 
 
})(jQuery);
#stats { 
 
    font-size: 0; 
 
} 
 

 
#stats * { 
 
    color: #000; 
 
} 
 

 
.single-stat { 
 
    width: 45%; 
 
    margin: 2.5%; 
 
    display: inline-block; 
 
    vertical-align: top; 
 
    text-align: center; 
 
} 
 

 
.stat-container { 
 
    position: relative; 
 
} 
 

 
.top-line { 
 
    font-size: 30px; 
 
    color: red; 
 
} 
 

 
.stat { 
 
    font-size: 48px; 
 
    margin: 0; 
 
} 
 

 
.bottom-line { 
 
    font-size: 16px; 
 
} 
 

 
.animateBlock { 
 
    display: inline-block; 
 
    position: relative; 
 
} 
 

 
.animateBlock { 
 
    opacity: 0; 
 
} 
 

 
.left.animated { 
 
    transform: translateX(-40px); 
 
} 
 

 
.right.animated { 
 
    transform: translateX(40px); 
 
} 
 

 
.top.animated { 
 
    transform: translateY(-40px); 
 
} 
 

 
.bottom.animated { 
 
    transform: translateY(40px); 
 
} 
 

 
.animated { 
 
    animation: come-in 0.5s ease forwards; 
 
} 
 

 
@keyframes come-in { 
 
    from { 
 
    opacity: 0; 
 
    } 
 
    to { 
 
    opacity: 1; 
 
    transform: translateY(0); 
 
    transform: translateX(0); 
 
    } 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<div id="stats"> 
 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="400"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="350"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="12"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="97"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="899"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="4"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="0"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="6"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 
</div>

1

Das Problem mit Ihrem Code war, dass man richtig die Scroll-Abstand, wurden überprüft, aber die Animation, um alle Ihre Zähler anwenden.

\t (function($) { 
 
    
 
\t $(function() { 
 
    
 
\t  var $counters = $('.counter'); //contains all elements of counter class 
 
     
 
\t  var $window = $(window); 
 
     
 
\t  $window.on('scroll', function(e) { 
 
\t  $counters.each(function(i, elem) { //loop through each element 
 
\t   if ($(this).hasClass('counted')) // check if already animated 
 
\t   return; 
 
\t   animateCounter($(this)); 
 
\t  }); 
 
\t  }); 
 
\t }); 
 
    
 
\t function animateCounter(elem) { 
 
\t  var winTop = $(window).scrollTop(); // calculate distance from top of window 
 
\t  var winBottom = winTop + $(window).height(); 
 
\t  var elemTop = $(elem).offset().top; // element distance from top of page 
 
\t  var elemBottom = elemTop + $(elem).height(); 
 
     
 
\t  if ((elemBottom <= winBottom) && (elemTop >= winTop)) { 
 
\t   var $this = elem; 
 
\t   jQuery({ 
 
\t   Counter: 0 
 
\t   }).animate({ 
 
\t   Counter: $this.attr('count') 
 
\t   }, { 
 
\t   duration: 3000, 
 
\t   step: function() { 
 
\t    $this.text(Math.ceil(this.Counter)); 
 
\t   } 
 
\t   }); 
 
\t   $this.removeClass('counter').addClass('counted'); 
 
\t  
 
\t  } 
 
\t } 
 
\t })(jQuery);
#stats { 
 
    font-size: 0; 
 
} 
 

 
#stats * { 
 
    color: #000; 
 
} 
 

 
.single-stat { 
 
    width: 45%; 
 
    margin: 2.5%; 
 
    display: inline-block; 
 
    vertical-align: top; 
 
    text-align: center; 
 
} 
 

 
.stat-container { 
 
    position: relative; 
 
} 
 

 
.top-line { 
 
    font-size: 30px; 
 
    color: red; 
 
} 
 

 
.stat { 
 
    font-size: 48px; 
 
    margin: 0; 
 
} 
 

 
.bottom-line { 
 
    font-size: 16px; 
 
} 
 

 
.animateBlock { 
 
    display: inline-block; 
 
    position: relative; 
 
} 
 

 
.animateBlock { 
 
    opacity: 0; 
 
} 
 

 
.left.animated { 
 
    transform: translateX(-40px); 
 
} 
 

 
.right.animated { 
 
    transform: translateX(40px); 
 
} 
 

 
.top.animated { 
 
    transform: translateY(-40px); 
 
} 
 

 
.bottom.animated { 
 
    transform: translateY(40px); 
 
} 
 

 
.animated { 
 
    animation: come-in 0.5s ease forwards; 
 
} 
 

 
@keyframes come-in { 
 
    from { 
 
    opacity: 0; 
 
    } 
 
    to { 
 
    opacity: 1; 
 
    transform: translateY(0); 
 
    transform: translateX(0); 
 
    } 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<p>&nbsp;</p> 
 
<div id="stats"> 
 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="400"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="350"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="12"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="97"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="899"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="4"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="0"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 

 
    <div class="single-stat"> 
 
    <h6 class="top-line">title</h6> 
 
    <div class="stat-container"> 
 
     <h6 class="stat"><span class="counter" count="6"></span></h6> 
 
    </div> 
 
    <h6 class="bottom-line">bottom line</h6> 
 
    </div> 
 
</div>

https://jsfiddle.net/cndbqeck/

Verwandte Themen