I have a list of elements for animating through CSS3, for example:
.anim-slide-left { animation: anim-slide-left 0.8s ease forwards; -webkit-animation: anim-slide-left 0.8s ease forwards; } @-webkit-keyframes anim-slide-left { 0% { transform: translateX(-500px); -webkit-transform: translateX(-500px); opacity: 0; } 100% { transform: translateX(0); -webkit-transform: translateX(0); opacity: 1; } }
When the page loads, js should animate only visible elements with the special class 'animate':
$(function() { var $window = $(window); var $toAnimate = $('.animate'); animate(); // check if element is on the viewport function isElementVisible(elementToBeChecked) { var TopView = $(window).scrollTop(); var BotView = TopView + $(window).height(); var TopElement = elementToBeChecked.offset().top; return ((TopElement <= BotView) && (TopElement >= TopView)); } // add css animation class function animate() { $toAnimate.each(function(i, el) { var $el = $toAnimate.eq(i); if ($el.length && isElementVisible($el)) { // remove already visible elements $toAnimate.splice(i, 1); // setting up animation effect $el.addClass( $el.data('effect') ); $el.removeClass('animate'); } }); } });
Now here is the problem. Only every second element is checked as visible, for example:

But it should be like this:

The remaining elements are animated only when the page scrolls down:
$window.scroll( function() { animate(); });
How to iterate over each item in this scenario?
EDIT:
Considering @TJ Crowder comments, I modified the animation function with the filter function suggested by @charlietfl:
$('.animate').filter( function( idx ) { if( isElementVisible($(this)) ) { $(this).addClass( $(this).data('effect') ); $(this).removeClass('animate'); } });
It works just fine :) Thanks guys.
source share