Chris
Chris

Reputation: 27384

Scroll to anchor whilst keeping the hash

I have a page with navigation to various sections. Each one provides an anchor tag for that page so someone can revisit the section easily. What I want is for the normal mechanism to work correctly but instead of jumping to the section (as per normal browser behavior) I want it to scroll there.

I have implemented the scrolling which works well I just dont know how to keep the hash URL as e.preventDefault() stops this from occuring. If I remove this line then the page flashes before scrolling.

$(".navigation a").click(function(e){
    $(".navigation a").removeClass("active");
    $(this).addClass("active");

    if ($(this).attr("href").substring(0,1) == "#"){
        e.preventDefault();

         $('html, body').animate({
             scrollTop: $($(this).attr("href")).offset().top
         }, 1000);
    }
});

Upvotes: 2

Views: 1382

Answers (1)

Martijn
Martijn

Reputation: 16103

I dont know how well you have to support old browsers, but otherwise you can use pushState functionallity That url gives documentation about how to use it :)

Supported by all browsers and IE10 (so no 9 or less)


A no-pushstate solution would be to scroll to the proper height, and then change the url. If properly done, the page wont hop :)

// you should change class navigation to id navigation, since there probally is only one
$(".navigation".find("a").click(function(e){ // with id this will speed up a bit
    //$(".navigation a").removeClass("active");
    $(".navigation a.active").removeClass("active"); // with A its faster
    $(this).addClass("active");
    var anchorDestination = this.href; // save for later, select as little times as possible

    //if ($(this).attr("href").substring(0,1) == "#"){
    if ( this.href.substring(0,1) == "#"){ // use native JS where possible
        e.preventDefault();
        var anchorDestination = this.href; // save for later
        var $aElem = $(this); // select it once, save it for later

        $('html, body').animate({
             //scrollTop: $($(this).attr("href")).offset().top
             scrollTop: $aElem.offset().top
        }, 1000, function(){
             window.location = anchorDestination;
        });
    }
});

Upvotes: 2

Related Questions