4

I have the following problem:

$('.gotoservices').click(function(){
    $('html,body').scrollTo($("#services"),1000);
    window.location.hash = "services";
    return false;
});

This code works but for some reason the page flashes before the scrollTo.

If I remove the window.location.hash line the return false; works and the page doesn't flash/flicker.

I have tried e.preventDefault - doesn't work

I'm struggling to find any work around.

Cheers

César
  • 9,939
  • 6
  • 53
  • 74
user1076082
  • 261
  • 2
  • 4
  • 6
  • I think you only need one of them. Setting `window.location.hash` will also scroll to the location. – Ry- Dec 01 '11 at 18:45
  • @minitech that's incorrect in Chrome's case – Pierre Sep 17 '12 at 21:25
  • @Pierre: Er... [no, it's not?](http://jsfiddle.net/minitech/TBAce/) – Ry- Sep 18 '12 at 00:22
  • @minitech: my bad for typing before thinking. The use case in which this doesn't work in chrome is when you set the `window.location.hash` and then `window.location.reload()` the page. When a page is reloaded, Chrome seems to prioritize the previous scroll position over what window.location.hash is pointing at (which is not the case in FireFox) – Pierre Sep 24 '12 at 16:57

2 Answers2

2

In a generic sense, you can update the URL with HTML5 history without the browser re-rendering anything:

history.pushState(null, null, '#myhash');

Of course, you will likely want to have fallbacks for older browsers, and you might want to do this only after your animation is done.

So, integrated with your code:

$('.gotoservices').click(function(e){
    //Prevent default so the browser doesn't try to do anything
    e.preventDefault();
    var $hash = "#services";
    $('html,body').scrollTo($($hash), 1000, function () {
        //If the browser supports HTML5 history,
        //use that to update the hash in the URL
        if (history.pushState) {
            history.pushState(null, null, $hash);
        }
        //Else use the old-fashioned method to do the same thing,
        //albeit with a flicker of content
        else {
            location.hash = $hash;
        }
    });
});
jporcenaluk
  • 966
  • 10
  • 25
0

Why don't you just make a function that specifically scrolls to #services? You're telling your web browser to go to #services and then to scroll to #services. Probably has a conflict with that. If you're trying to update the url to have the hash, then you probably need

$(window).bind('hashchange', function(e) {
    e.preventDefault();
});

So that it doesn't try to "go to the hash".

Manuel van Rijn
  • 10,170
  • 1
  • 29
  • 52
romo
  • 1,990
  • 11
  • 10