Ok, I'm facing an issue when trying to animate several elements of the DOM, using a condition on a scroll event.
First of all, I'm using Drupal 7 so the jQuery library I'm using is of version 1.4.4.
Now, I want to shrink the size of my header when the page srolls down by changing css properties of elements inside of it.
So first, on the scroll event, I check the scrollTop position of the window. If the position is different than 0 (meaning that the page is scrolled down), I trigger the animation on the elements inside the header.
If the position is equal to zero, I want the css properties to fall back to their original state so the header retrieve its full size.
The first part of the animation works fine. When I scroll down the page, the header shrinks as expected. But when I scroll the page back up to the top, the second animation doesn't work.. the animations are all buggy and occur after several second and go wild, changing back and forth the css properties affected by the animate()
function.
Does anyone have a clue on how to clear this out ??
Here is the simplified portion of the code I'm using:
$(window).scroll(function(){
if($(window).scrollTop() != 0){
$('#myFirstElement').animate({marginTop: '20px'}, 300);
$('#mySecondElement').animate({top: '20px'}, 300);
}
else {
$('#myFirstElement').animate({marginTop: '32px'}, 300);
$('#mySecondElement').animate({top: '32px'}, 300);
}
});
you can use something like
http://jsfiddle.net/HjFH4/
$elem1 = $('#myFirstElement');
$elem2 = $('#mySecondElement');
var scrollState = 'top';
$(window).scroll(function(){
var scrollPos = $(window).scrollTop();
if( ( scrollPos != 0 ) && ( scrollState === 'top' ) ) {
$elem1.stop().animate({marginTop: '0px'}, 300);
$elem2.stop().animate({height: '10px'}, 300);
scrollState = 'scrolled';
}
else if( ( scrollPos === 0 ) && ( scrollState === 'scrolled' ) ) {
$elem1.stop().animate({marginTop: '32px'}, 300);
$elem2.stop().animate({height: '80px'}, 300);
scrollState = 'top';
}
});
The problem is that the scroll
event occurred many many times durring user scrolling action.
And every times, you ask JQuery to start an animation.
You should only do the animation if needed :
var smallMenu = false;
$(window).scroll(function(){
if($(window).scrollTop() !== 0)
{
if(smallMenu === false)
{
smallMenu = true;
$('#myFirstElement').stop().animate({marginTop: '20px'}, 300);
$('#mySecondElement').stop().animate({top: '20px'}, 300);
}
}
else
{
if(smallMenu === true)
{
smallMenu = false;
$('#myFirstElement').stop().animate({marginTop: '32px'}, 300);
$('#mySecondElement').stop().animate({top: '32px'}, 300);
}
}
});
Try using .data
or something to save the state of the animation, and only animate it when the state is the opposite of what you want.
$(window).scroll
triggers repeatedly while you're scrolling. See the live example at the bottom of http://api.jquery.com/scroll/
So it seems to me that while scrolling, and the top is not zero, it's actually queueing up a ton of animation events, which then cause conflict when you scroll back up.