Reputation: 1582
I have a scroll function set up so when the window scrolls beyond 50px, the .header-wrap
div animates from a height of 140px
to 70px
, ideally what should happen then is when you scroll back less than 50px from the top, the .header-wrap
div should animate back from 70px
to 140px
but this function doesn't seem to be working as it should:
jsFiddle: http://jsfiddle.net/ub8Rb/
HTML:
<div class="header-wrap">hello</div>
<div class="scroll"></div>
CSS:
.header-wrap {
position: fixed;
width: 100%;
height: 140px;
top: 0;
left: 0;
text-align: center;
background-color: #999;
z-index: 9999;
}
.scroll {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4000px;
}
jQuery:
$(document).scroll(function () {
if (window.scrollY > 50) {
$(".header-wrap").animate({
height: "70px"
}, 500);
} else {
$(".header-wrap").animate({
height: "140px"
}, 500);
}
});
This function doesn't seem to be working as I've described above, and not animating the height of the div dependant on how far the window has scrolled. Any suggestions are greatly appreciated!
Upvotes: 0
Views: 11056
Reputation: 7059
What happens is your scroll function will fire rapidly, trying to execute the animate()
function, which will add them queued into your browser's memory. If you wait long enough, the queue will reach the end and your animation works as expected.
Easy solution, add stop(true, false)
in front of animate()
API: http://api.jquery.com/stop/
You could use a wrapper function to capture duplicated events if you want to control the delay.
var headerwrap = $(".header-wrap"),
delayedEvent = (function () {
var timers = {};
return function (callback, delay, id) {
delay = delay || 500;
id = id || "duplicated event";
if (timers[id]) {
clearTimeout(timers[id]);
}
timers[id] = setTimeout(callback, delay);
};
})();
$(document).scroll(function (ev) {
delayedEvent(function () {
var h = (window.scrollY > 50) ? 70 : 140;
headerwrap.stop(true, false).animate({ height: h }, 500);
}, 500, "scroll event");
});
FIDDLE: http://jsfiddle.net/tive/QskJm/
Upvotes: 1
Reputation: 2165
This one is smooth...
var go = true;
$(window).scroll(function() {
if ($(this).scrollTop() > 50 && go) {
$(".header-wrap").stop().animate({height:'70px'}, 500);
go = false;
} else if ($(this).scrollTop() < 50 && !go) {
$(".header-wrap").stop().animate({height:'140px'}, 200);
go = true;
}
});
made a fiddle: http://jsfiddle.net/filever10/z5D4E/
Upvotes: 3
Reputation: 833
Add a stop()
to your code, $(".header-wrap").stop().animate
, this stops any currently executing animations. Here is a JSFiddle with the modified code: >>>CLICK HERE<<<
Upvotes: 1
Reputation: 224
This may be a problem of conflicting animations, because if you scroll slowly your example works. Setting a trigger to determine when/if to play the height animation should correct the conflict. Here is an example of this working:
var sizeTrigger = 'tall';
$(document).scroll(function () {
console.log(window.scrollY);
if (window.scrollY > 50 && sizeTrigger == 'tall') {
$(".header-wrap").animate({
height: "70px"
}, 500, function() {
sizeTrigger = 'small';
console.log(sizeTrigger);
});
} else if (window.scrollY < 50 && sizeTrigger == 'small') {
$(".header-wrap").animate({
height: "140px"
}, 500, function() {
sizeTrigger = 'tall';
console.log(sizeTrigger);
});
}
});
Upvotes: 1