Reputation: 459
I'm using jQuery's animate() function in conjunction with easing from the jQuery UI plugin to animate scrolling down my page with links in a sidebar. I'm also using it to operate a "back to top" button. You can see it live here: http://www.element17.com/
The back to top button is working perfectly, but the behaviour of the links is erratic. Sometimes it works great, and other times it either refuses to scroll, waits a second or two and then scrolls, or doesn't animate at all and just jumps down the page as if they weren't scripted in the first place.
Here's the code for the back to top button:
$('#go_up').click(function(){
$('#main').animate({scrollTop:0}, 2000, 'easeOutExpo');
});
And here's the code for the links:
$('.scroll').click(function(){
$('#main').animate({scrollTop:$(this.hash).offset().top}, 3000, 'easeOutExpo');
});
I've tested this in Chrome in OSX and Windows, and the behaviour is erratic in both. Can anyone suggest why this might be the case?
Upvotes: 0
Views: 121
Reputation: 33408
At the first you need to prevent the default behavior from hash links (return false
) and further you need to check if there's an element with the given id.
$('a[href*=#]').on('click', function() {
var hash = $(this.hash).offset();
if (hash) {
$('#main').stop().animate({
scrollTop: hash.top
}, 3000, 'easeOutExpo');
return false;
}
});
UPDATE Change your links and ID's to valid ones:
By the way
To hide your scroll to top link if not needed (e.g. at the top of your page) use this:
$(window).scroll(function () {
if ($(this).scrollTop() !== 0) {
$('#go_up').fadeOut();
} else {
$('#go_up').fadeIn();
}
});
Hide it with css:
#go_up {display:none}
Upvotes: 2
Reputation: 9706
Your $(this.hash).offset().top
does not always provide the value you expect, i.e. from the top of the #main
div. If you scrolled to the bottom of the page and hit a link at the bottom, its offset().top
will be relative on the screen, not absolute. Could be a negative value, for example. However, animate's scrollTop requires absolute scroll position.
One solution could be to do
$('#main').animate({scrollTop:
$(this.hash).offset().top - $('#CONSTRUCTS').offset().top},
3000, 'easeOutExpo');
where #CONSTRUCTS
will work as the topmost element.
Depending on how dynamic your data is, you might want to replace it with anything at the top left corner of your #main.
There are many other ways to solve it.
Upvotes: 1