Run a JS function while in viewport. - javascript

I've found on here how to do a counter, and I will be using it on a scrolling site.
I'm using the following code:
$(function() {
function count($this){
var current = parseInt($this.html(), 10);
$this.html(++current);
if(current !== $this.data('count')){
setTimeout(function(){count($this)}, 10);
}
}
$("span").each(function() {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
});
I've tried to include the following code, but I'm not sure I'm adding it correctly:
if ($('element').visible(true)) {
}
Heres a link to the Jfiddle that is currently working without the if statement. Any help would be appreciated.
http://jsfiddle.net/WpJxn/257/

This is what you should look at: Check if element is visible after scrolling
Here is an example for you that demonstrates this technique: http://jsfiddle.net/XYS2G/ - just try to scroll the Result window.
HTML:
<div class="indicators">
<span class="indicator" data-id="section1">section1</span>
<span class="indicator" data-id="section2">section2</span>
<span class="indicator" data-id="section3">section3</span>
<span class="indicator" data-id="section4">section4</span>
<span class="indicator" data-id="section5">section5</span>
<span class="indicator" data-id="section6">section6</span>
</div>
<div class="sections">
<div class="section" id="section1">section1</div>
<div class="section" id="section2">section2</div>
<div class="section" id="section3">section3</div>
<div class="section" id="section4">section4</div>
<div class="section" id="section5">section5</div>
<div class="section" id="section6">section6</div>
</div>
CSS:
.indicators { position: fixed; }
.section { height: 150px; }
JavaScript:
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
function refreshIndicators() {
$('.indicator').each(function () {
if (isScrolledIntoView($('#' + $(this).attr('data-id')))) {
$(this).css('color', 'red');
} else {
$(this).css('color', 'black');
}
});
}
refreshIndicators();
$(window).bind('scroll', refreshIndicators);

Related

Function scrollIntoView doesn't work

I have a little problem with my function scrollIntoView. Indeed, it doesn't work :(
This is my code:
HTML
<section class="page_mission">
<div class="page_mission_text">
<div class="scroll-animations">
<div class="animated fadeInLeft">
<h2>Design <i class="fab fa-css3-alt"></i><i class="fab fa-html5"></i></h2>
<p>Blablabla<br></p>
</div><hr style="width: 75%;">
<div class="animated">
<h2>Modernité <i class="fas fa-dna"></i></h2>
<p>Blablabla</p>
</div><hr style="width: 75%;">
<div class="animated">
<h2>Coûts <i class="far fa-credit-card"></i></h2>
<p>Blablabla</p>
</div>
</div>
</div>
</section>
JS
$(document).ready(function() {
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function() {
$('.scroll-animations .animated').each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass('fadeInLeft');
}
});
});
Does someone have an idea what's wrong?
Thanks a lot!
It appears to me the fadeInLeft class is being added on scroll as expected. You do, however, need an additional closing curly brace and closing parentheses to close your document ready event handler:
$(document).ready(function() {
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function() {
$('.scroll-animations .animated').each(function() {
if (isScrolledIntoView(this) === true) {
$(this).addClass('fadeInLeft');
}
});
});
}); // This was missing
JSFiddle
You also need to make sure to load jQuery before your JavaScript executes. The easiest way is to place something like this in the page's <head> element:
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

Determine whether a section with class is visible or not, jQuery

This is a variation of others topics, the idea is to assign a .js-visible to any element in the DOM, and only when it is visible assign to it a .visible class.
The tricky part is that as all of the elements are using the same class name .js-visible I need to assign the class .visible to only the visible element and ignore all the other DOM elements with the same class name. If it was visible and is not anymore then remove the class name .visible
<style>
.visible {
background: green;
}
</style>
<div class="js-visible" style="height:800px">I am 1st</div>
<div class="js-visible" style="height:800px">I am 2nd</div>
<div class="js-visible" style="height:800px">I am 3rd</div>
<div class="js-visible" style="height:800px">I am 4th</div>
This is not working as desired
$(window).scroll(function() {
var hT = $('.js-visible').offset().top,
hH = $('.js-visible').outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
$('.js-visible').addClass('visible')
} else {
$('.js-visible').removeClass('visible')
}
});
Any suggestions?
Based on your code, this function seems to work.
You need to check each element individually.
$(window).scroll(function() {
var wH = $(this).height(),
wS = $(this).scrollTop();
$('.js-visible').each(function() {
var hT = $(this).offset().top,
hH = $(this).outerHeight();
if (wS >= (hT+hH-wH) && (hT >= wS) && (wS+wH >= hT+hH)){
$(this).addClass('visible')
} else {
$(this).removeClass('visible')
}
});
});
.visible {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
.visible {
background: green;
}
</style>
<div class="js-visible" style="height:200px">I am 1st</div>
<div class="js-visible" style="height:200px">I am 2nd</div>
<div class="js-visible" style="height:200px">I am 3rd</div>
<div class="js-visible" style="height:200px">I am 4th</div>
I would like to post a demo of the solution for who needs the same solution, you can adapt to your project
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$(window).on('resize scroll', function() {
$('.js-visible').each(function() {
var activeColor = $(this).attr('id');
if ($(this).isInViewport()) {
$(this).addClass('visible');
} else {
$(this).removeClass('visible');
}
});
});
.visible {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="js-visible" style="height:800px">I am 1st</div>
<div class="js-visible" style="height:800px">I am 2nd</div>
<div class="" style="height:800px">I am something else</div>
<div class="" style="height:800px">I am something else</div>
<div class="js-visible" style="height:800px">I am 3rd</div>
<div class="js-visible" style="height:800px">I am 4th</div>

Start counting after scroll on specific element

I create a website and add a counter to my codes.
$(function() {
function count($this){
var current = parseInt($this.html(), 10);
$this.html(++current);
if(current !== $this.data('count')){
setTimeout(function(){count($this)}, 50);
}
}
$(".c-section4").each(function() {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<div class="section4">
<div class="section4-bg"></div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
</div>
Now i have a problem, i want to counter start when i scroll to this element
Demo
Sorry for my bad english
You can handle the window scroll event and use the function given here by Scott Dowding to determine if the element has been scrolled into view. An isCounting flag can be set on each element to prevent counting several times simultaneously.
In the following code snippet, the counting is performed only while the element is visible.
$(function () {
function isScrolledIntoView($elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $elem.offset().top;
var elemBottom = elemTop + $elem.height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
function count($this) {
var current = parseInt($this.html(), 10);
if (isScrolledIntoView($this) && !$this.data("isCounting") && current < $this.data('count')) {
$this.html(++current);
$this.data("isCounting", true);
setTimeout(function () {
$this.data("isCounting", false);
count($this);
}, 50);
}
}
$(".c-section4").each(function () {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
$(this).data("isCounting", false);
});
function startCount() {
$(".c-section4").each(function () {
count($(this));
});
};
$(window).scroll(function () {
startCount();
});
startCount();
});
.tallDiv
{
height: 800px;
background-color: silver;
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<div class="section4">
<div class="section4-bg"></div>
<div class="tallDiv">Scroll down to test</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="counter-section">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
<div class="tallDiv"></div>
</div>
You need to give the target element and id, then get its postition from top var pos = document.getElementById('targetId').scrollHeight - element.clientHeight; and compare it to the scrolled height window.pageYOffset.
If widow offset is greater than the pos, you can start the counter. You should hook the comparison to the window.onscroll event.
Also you should memorize in a variable if you started the counter for an element already to avoid starting it twice.
Get the scroll Height and compare with the height of the start div(count start div) put a condition
$(function() {
var pos = document.getElementById('targetId').scrollHeight;
console.log(pos);
if(pos>="75"){
function count($this){
var current = parseInt($this.html(), 10);
$this.html(++current);
if(current !== $this.data('count')){
setTimeout(function(){count($this)}, 50);
}
}
$(".c-section4").each(function() {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="counter-section" id="targetId">
<span class="c-section4">152 </span>
<h3> کارکنان ما </h3>
</div>
Live Link
You can use this Plugin for it. Source LINK
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0'
data-max='82' data-delay='19' data-increment="2">0</span>
NB: data-max='**'give your max-number and data-delay='**' select a time for countdown running and select increment data-increment="**" .
/**
* jQuery scroroller Plugin 1.0
*
* http://www.tinywall.net/
*
* Developers: Arun David, Boobalan
* Copyright (c) 2014
*/
(function($){
$(window).on("load",function(){
$(document).scrollzipInit();
$(document).rollerInit();
});
$(window).on("load scroll resize", function(){
$('.numscroller').scrollzip({
showFunction : function() {
numberRoller($(this).attr('data-slno'));
},
wholeVisible : false,
});
});
$.fn.scrollzipInit=function(){
$('body').prepend("<div style='position:fixed;top:0px;left:0px;width:0;height:0;' id='scrollzipPoint'></div>" );
};
$.fn.rollerInit=function(){
var i=0;
$('.numscroller').each(function() {
i++;
$(this).attr('data-slno',i);
$(this).addClass("roller-title-number-"+i);
});
};
$.fn.scrollzip = function(options){
var settings = $.extend({
showFunction : null,
hideFunction : null,
showShift : 0,
wholeVisible : false,
hideShift : 0,
}, options);
return this.each(function(i,obj){
$(this).addClass('scrollzip');
if ( $.isFunction( settings.showFunction ) ){
if(
!$(this).hasClass('isShown')&&
($(window).outerHeight()+$('#scrollzipPoint').offset().top-settings.showShift)>($(this).offset().top+((settings.wholeVisible)?$(this).outerHeight():0))&&
($('#scrollzipPoint').offset().top+((settings.wholeVisible)?$(this).outerHeight():0))<($(this).outerHeight()+$(this).offset().top-settings.showShift)
){
$(this).addClass('isShown');
settings.showFunction.call( this );
}
}
if ( $.isFunction( settings.hideFunction ) ){
if(
$(this).hasClass('isShown')&&
(($(window).outerHeight()+$('#scrollzipPoint').offset().top-settings.hideShift)<($(this).offset().top+((settings.wholeVisible)?$(this).outerHeight():0))||
($('#scrollzipPoint').offset().top+((settings.wholeVisible)?$(this).outerHeight():0))>($(this).outerHeight()+$(this).offset().top-settings.hideShift))
){
$(this).removeClass('isShown');
settings.hideFunction.call( this );
}
}
return this;
});
};
function numberRoller(slno){
var min=$('.roller-title-number-'+slno).attr('data-min');
var max=$('.roller-title-number-'+slno).attr('data-max');
var timediff=$('.roller-title-number-'+slno).attr('data-delay');
var increment=$('.roller-title-number-'+slno).attr('data-increment');
var numdiff=max-min;
var timeout=(timediff*1000)/numdiff;
//if(numinc<10){
//increment=Math.floor((timediff*1000)/10);
//}//alert(increment);
numberRoll(slno,min,max,increment,timeout);
}
function numberRoll(slno,min,max,increment,timeout){//alert(slno+"="+min+"="+max+"="+increment+"="+timeout);
if(min<=max){
$('.roller-title-number-'+slno).html(min);
min=parseInt(min)+parseInt(increment);
setTimeout(function(){numberRoll(eval(slno),eval(min),eval(max),eval(increment),eval(timeout))},timeout);
}else{
$('.roller-title-number-'+slno).html(max);
}
}
})(jQuery);
.nm {
height: 400px;
background: #f5f5f5;
display: block;
}
.nm_1 {
background-color: #632525;
}
.nm_2 {
background-color: grad;
}
.nm_3 {
background-color: gray;
}
.nm_4 {
background-color: green;
}
.nm_5 {
background-color: georgian;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="nm nm_1">
</section>
<section class="nm nm_2">
</section>
<section class="nm nm_3">
</section>
<section class="nm nm_4">
<div>
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0' data-max='192' data-delay='19' data-increment="2">0</span>
<h3> کارکنان ما </h3>
</div>
<div>
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0' data-max='282' data-delay='19' data-increment="2">0</span>
<h3> کارکنان ما </h3>
</div>
<div>
<span class='numscroller numscroller-big-bottom' data-slno='1' data-min='0' data-max='82' data-delay='19' data-increment="2">0</span>
<h3> کارکنان ما </h3>
</div>
</section>
<section class="nm nm_4">
</section>
<section class="nm nm_5">
</section>
Here's my solution which supports floats and a configurable animation duration. It will only animate the count one time - as soon the element appears in the viewport of the specified container.
const initAnimatedCounts = () => {
const ease = (n) => {
// https://github.com/component/ease/blob/master/index.js
return --n * n * n + 1;
};
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// Once this element is in view and starts animating, remove the observer,
// because it should only animate once per page load.
observer.unobserve(entry.target);
const countToString = entry.target.getAttribute('data-countTo');
const countTo = parseFloat(countToString);
const duration = parseFloat(entry.target.getAttribute('data-animateDuration'));
const countToParts = countToString.split('.');
const precision = countToParts.length === 2 ? countToParts[1].length : 0;
const startTime = performance.now();
const step = (currentTime) => {
const progress = Math.min(ease((currentTime - startTime) / duration), 1);
entry.target.textContent = (progress * countTo).toFixed(precision);
if (progress < 1) {
animationFrame = window.requestAnimationFrame(step);
} else {
window.cancelAnimationFrame(animationFrame);
}
};
let animationFrame = window.requestAnimationFrame(step);
}
});
});
document.querySelectorAll('[data-animateDuration]').forEach((target) => {
target.setAttribute('data-countTo', target.textContent);
target.textContent = '0';
observer.observe(target);
});
};
initAnimatedCounts();
div {
font-size: 30px;
text-align: center;
padding: 30px 0;
}
div > span {
color: #003d82;
}
div.scrollpad {
height: 100vh;
background-color: #eee;
}
<div>
<span>$<span data-animateDuration="1000">987.45</span></span> was spent on
about <span><span data-animateDuration="1000">5.8</span>M</span> things.
</div>
<div class="scrollpad">keep scrolling</div>
<div>
There are <span><span data-animateDuration="1000">878</span>K</span> people involved.
<br/>
And <span><span data-animateDuration="1000">54</span></span> cakes.
</div>
<div class="scrollpad">keep scrolling</div>
<div>
Additionally, <span>$<span data-animateDuration="3000">300</span>B</span> went to waste.
<br/>
Because <span>$<span data-animateDuration="2000">54</span></span> was spent on each cake.
</div>
<div class="scrollpad">keep scrolling</div>
<div>
Lastly, <span><span data-animateDuration="4000">3.5334583</span>T</span> ants said hello.
<br/>
But <span><span data-animateDuration="2000">4</span></span> of them said goodbye.
</div>

JQuery "fade out" effect on scroll up

I have this code, if scroll down Fade in and show the object
css:
.fadeInBlock {
opacity:0;
}
js:
$(function() {
$(window).scroll( function(){
$('.fadeInBlock').each( function(i){
var bottom_of_object = $(this).position().top + $(this).outerHeight();
var bottom_of_window = $(window).scrollTop() + $(window).height();
/* Adjust the "200" to either have a delay or that the content starts fading a bit before you reach it */
bottom_of_window = bottom_of_window + 200;
if( bottom_of_window > bottom_of_object ){
$(this).animate({'opacity':'1'},500);
}
});
});
});
and need solution to fade out the object after scroll up.
Please advise, thank you
Maybe something like this will help
function isVisible(elem){
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function() {
console.log('scroll')
$('.fadeInBlock').each(function(i) {
if (isVisible(this)) {
$(this).animate({
'opacity': '1'
}, 1000);
} else {
$(this).css({
'opacity': '0'
});
}
});
});
https://jsfiddle.net/32feyrhy/4/
$(window).on("load",function() {
$(window).scroll(function() {
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
/* If the element is completely within bounds of the window, fade it in */
if (objectBottom < windowBottom) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}); $(window).scroll(); //invoke scroll-handler on page-load
});
.fade {
margin: 50px;
padding: 50px;
background-color: lightgreen;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div>
<div class="fade">Fade In 01</div>
<div class="fade">Fade In 02</div>
<div class="fade">Fade In 03</div>
<div class="fade">Fade In 04</div>
<div class="fade">Fade In 05</div>
<div class="fade">Fade In 06</div>
<div class="fade">Fade In 07</div>
<div class="fade">Fade In 08</div>
<div class="fade">Fade In 09</div>
<div class="fade">Fade In 10</div>
</div>
Please check this link:-Fade In on Scroll Down, Fade Out on Scroll Up - based on element position in window

jQuery queue does not work

What I'm trying to accomplish:
Let multiple cards in the queue slide in after each other on document ready and for the elements that arent visible on page load I want the same for them on scroll.
The problem:
All elements slide in at the same time. (Even though I'm using an each loop)
Example:
$( document ).ready(function(){
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
function readyAnimation (animationClass) {
var resetAnimationClass = "reset-animations";
$("." + animationClass).each(function() {
var elem = $(this);
if(elem.hasClass(animationClass)) {
if (isScrolledIntoView(elem) == true ) {
elem.delay(500).queue(function(){
elem.addClass(resetAnimationClass).dequeue();
})
}
}
});
}
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
.card {
float: left;
width: 25%;
background: $brand;
height: 300px;
border: 1px solid white;
background: #333;
}
.slide-in-cards {
transform: translate3d(0, 50px, 0);
opacity: 0;
transition: transform 600ms cubic-bezier(0.52, 1.61, 0.56, 1), opacity 600ms cubic-bezier(0.22, 0.61, 0.36, 1);
will-change: transform;
}
.reset-animations {
transform: translate3d(0, 0, 0);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...
What I did so far:
My markup looks like this:
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...
And I want them so slide in after each other by using something like this:
function readyAnimation (animationClass) {
var resetAnimationClass = "reset-animations";
$("." + animationClass).each(function() {
var elem = $(this);
if(elem.hasClass(animationClass)) {
if (isScrolledIntoView(elem) == true ) {
elem.delay(500).queue(function(){
elem.addClass(resetAnimationClass).dequeue();
})
}
}
});
}
I add a class that resets their css to normal, the elements have the transition property
This function is called like this
$( document ).ready(function(){
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
The isScrolledIntoView function is from stackoverflow and looks like this
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
Some thoughts:
Remember that animations on separate elements run in parallel; each element has its own animation queues.
You've said that you had an issue when more elements come into view. That's because you weren't eliminating them from the selection of elements to animate.
Your if (elem.hasClass(animationClass)) check is unnecessary, as you've selected only elements that have that class.
So (see *** commented lines):
function readyAnimation(animationClass) {
var resetAnimationClass = "reset-animations";
var counter = 0; // ***
$("." + animationClass).not("." + resetAnimationClass).each(function() { // ***
var elem = $(this);
// *** No `if (elem.hasClass(animationClass))` here, we know it does
if (isScrolledIntoView(elem) == true) {
++counter; // ***
elem.delay(500 * counter).queue(function() { // ***
elem.addClass(resetAnimationClass).dequeue();
})
}
});
}
$(document).ready(function() {
//readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
$(window).scroll(function() {
//readyAnimation("slide-in-left");
readyAnimation("slide-in-cards");
});
function readyAnimation(animationClass) {
var resetAnimationClass = "reset-animations";
var counter = 0;
$("." + animationClass).not("." + resetAnimationClass).each(function() {
var elem = $(this);
if (isScrolledIntoView(elem) == true) {
++counter;
elem.delay(500 * counter).queue(function() {
elem.addClass(resetAnimationClass).dequeue();
})
}
});
}
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
.card {
float: left;
width: 25%;
background: $brand;
height: 300px;
border: 1px solid white;
background: #333;
}
.slide-in-cards {
transform: translate3d(0, 50px, 0);
opacity: 0;
transition: transform 600ms cubic-bezier(0.52, 1.61, 0.56, 1), opacity 600ms cubic-bezier(0.22, 0.61, 0.36, 1);
will-change: transform;
}
.reset-animations {
transform: translate3d(0, 0, 0);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
<div class="card slide-in-cards">
<img />
</div>
...

Categories