Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: Scroll to anchor when calling URL, replace browsers behaviour

I already know the jQuery plugin ScrollTo, but I didn't find any way up to now to realize the following:

The users gets to my site (by typing, NOT by clicking a link on my page) domain.com/bla.php#foo

and the anchor "#foo" exists. Now I want that the browser of the user does NOT automatically scroll to "#foo", instead I want to smoothly scroll so that the element '#foo' is about in the middle of the view and NOT on the absolute top position of the users view.

thanks so far!

like image 304
bj. Avatar asked Dec 14 '09 21:12

bj.


4 Answers

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);
    }
});
like image 153
Jan Jongboom Avatar answered Nov 14 '22 11:11

Jan Jongboom


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.

like image 37
Viktor Stískala Avatar answered Nov 14 '22 11:11

Viktor Stískala


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!

like image 1
ReLeaf Avatar answered Nov 14 '22 11:11

ReLeaf


/* 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() {});

like image 1
Emilion Avatar answered Nov 14 '22 13:11

Emilion