jQuery: Scroll to anchor when calling URL, replace browsers behaviour
Machineghost's answer was very helpful. The code I patched together takes a URL param and turns it into a hash tag that the browser then scrolls to as soon as the DOM is ready.
The URL would look like this:
www.mysite.com/hello/world.htm?page=contact
Contact is the name of the ID you want to scroll to
<h1 id="contact">Contact Us</h1>
Here's the code:
// Get any params from the URL
$.extend({
getUrlVars: function(){
var vars = [], hash;
var url = decodeURIComponent(window.location.href);
var hashes = url.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
},
getUrlVar: function(name){
return $.getUrlVars()[name];
}
});
$(document).ready(function() {
// Unhide the main content area
$('section.centered').fadeIn('slow');
// Create a var out of the URL param that we can scroll to
var page = $.getUrlVar('page');
var scrollElement = '#' + page;
// Scroll down to the newly specified anchor point
var destination = $(scrollElement).offset().top;
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination-75}, 800 );
return false;
});
I checked this in Chrome and FF and it worked very well. Try adjusting "destination-75" if the scroll target isn't going to the exact place you want it to.
I couldn't have done it with out the posts above, so thanks!
I made some enhancement to script from Jan Jongboom so it now looks like this:
$(document).ready(function () {
// replace # with #_ in all links containing #
$('a[href*=#]').each(function () {
$(this).attr('href', $(this).attr('href').replace('#', '#_'));
});
// scrollTo if #_ found
hashname = window.location.hash.replace('#_', '');
// find element to scroll to (<a name=""> or anything with particular id)
elem = $('a[name="' + hashname + '"],#' + hashname);
if(elem) {
$(document).scrollTo(elem, 800);
}
});
It changes all anchors in links so for users without javascript the behaviour will remain untouched.
/* scrolling to element */
var headerHeight = $('#header').height() + $('#header-bottom-cap').height() + 10; //When the header position is fixed
$('a').click(function(){
var hashEle = $(this).attr('href').split('#');
if (hashEle.length > 1) {
if (hashEle[1] == 'top') {
$('body, html').animate({
scrollTop: 0
},500);
} else {
jQuery('body, html').animate({
scrollTop: $('#'+ hashEle[1]).offset().top - headerHeight
},500);
}
};
})
// find element from url
hashname = window.location.hash.replace('#', '');
elem = $('#' + hashname);
if(hashname.length > 1) {
if(hashname == 'top') {
$('body, html').animate({
scrollTop: 0
},200);
} else {
$('body, html').animate({
scrollTop: $(elem).offset().top - headerHeight
},500);
}
};
/* END scrolling to element */
this script should be into $(document).ready(function() {});
If you don't create the actual anchor foo
, but rather create your anchor with an id like _foo
(something like <a id="_foo">
). You can handle the $(document).ready
to achieve this.
Something like (pseudo code)
$(document).ready(function() {
var elem = $('#_' + window.location.hash.replace('#', ''));
if(elem) {
$.scrollTo(elem.left, elem.top);
}
});