Reputation: 65
I have a div I'd like to animate once after a certain distance has been reached between a trigger div and the top of the window, but when within a .scroll() function the animation is continually triggered as you scroll.
This below code works fine:
$(window).scroll(function(){
var a = $('.intro-text').offset().top;
console.log(a);
if ( a > 100 ) {
$('.hide-me').fadeOut();
} else if ( a < 100 ) {
$('.hide-me').fadeIn();
}
});
But if I change it to .animate(), it's continually queued up and takes forever to run:
$(window).scroll(function(){
var a = $('.intro-text').offset().top;
console.log(a);
if ( a > 100 ) {
$('.hide-me').animate({
left: -200
}, 1000);
} else if ( a < 100 ) {
$('.hide-me').animate({
left: 0
}, 1000);
}
});
My coding skills aren't the best, but I'd like it to learn if there's a function within jQuery / pure javascript before going into any external libraries or plugins. Any help would be much appreciated, thanks.
Upvotes: 0
Views: 1177
Reputation: 4150
Create a scroll
object and save two flags fadeIn
and fadeOut
var scroll = {
fadeIn: false,
fadeOut: false
};
Explanation
Inside your scroll event there are two conditions a>100
and a<100
So, once one of the condition is true it goes inside and check if the flag is set before triggering the animation and then sets flag of the animation done to true and clears the other flag.
For Example:
if (a > 100) {
if (!scroll.fadeOut) {
$('.hide-me').fadeOut();
scroll.fadeOut = true;
scroll.fadeIn = false;
}
}
In the above code
It checks if scroll.fadeOut
is not set then
It does the animation
$('.hide-me').fadeOut();
and sets the flags
scroll.fadeOut = true;
scroll.fadeIn = false;
This will not allow this animation to be executed again until the second one is triggered and its clears the flag.
Full JS
var scroll = {
fadeIn: false,
fadeOut: false
};
$(window).scroll(function() {
var a = $('.intro-text').offset().top;
console.log(a);
if (a > 100) {
if (!scroll.fadeOut) {
$('.hide-me').fadeOut();
scroll.fadeOut = true;
scroll.fadeIn = false;
}
} else if (a < 100) {
if (!scroll.fadeIn) {
$('.hide-me').fadeIn();
scroll.fadeIn = true;
scroll.fadeOut = false;
}
}
});
UPDATE
var scroll = {
fadeIn: false,
fadeOut: false
};
$(window).scroll(function() {
var a = $('.intro-text').offset().top;
console.log(a);
if (a > 100) {
if (!scroll.fadeOut) {
$('.hide-me').animate({
left: -200
}, 1000);
scroll.fadeOut = true;
scroll.fadeIn = false;
}
} else if (a < 100) {
if (!scroll.fadeIn) {
$('.hide-me').animate({
left: 0
}, 1000);
scroll.fadeIn = true;
scroll.fadeOut = false;
}
}
});
Upvotes: 1
Reputation: 73906
In these scenarios you can use jquery .stop([clearQueue],[jumpToEnd])
method like:
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
$(window).scroll(function() {
debounce(function() {
var a = $('.intro-text').offset().top;
console.log(a);
if (a > 100) {
$('.hide-me').stop(true, true).animate({
left: -200
}, 1000);
} else if (a < 100) {
$('.hide-me').stop(true, true).animate({
left: 0
}, 1000);
}
}, 50);
});
If more than one animation method is called on the same element, the later animations are placed in the effects queue for the element. These animations will not begin until the first one completes. When .stop()
is called, the next animation in the queue begins immediately. If the clearQueue
parameter is provided with a value of true
, then the rest of the animations in the queue are removed and never run.
Upvotes: 1