Daniel Martin
Daniel Martin

Reputation: 11

jQuery Smooth Scroll cross-browser problem

I have a small snippet of code to produce a smooth scroll to anchor tags and back again. My site design has a fixed header of height 170px. So to compensate for this the java has been modified as below.

var jump=function(e)
{
   e.preventDefault();
   var target = $(this).attr("href");
   $('html,body').animate(
   {
      scrollTop: $(target).offset().top-170 // modification
   },1000,function()
   {
      location.hash = target;
   });
}
$(document).ready(function()
{
   $('a[href*=#]').bind("click", jump);
   return false;
});

This code works perfectly in Chrome and Safari, but in IE & Firefox it scrolls to the intended location and jumps 170px further down the page.

Any ideas?

Thanks, Dan

Upvotes: 1

Views: 4259

Answers (2)

DarthJDG
DarthJDG

Reputation: 16591

The problem is that when your animation finishes, you set location.hash which makes the browser jump to the anchor. As a simple workaround, don't prevent the hash change on the click, save the current scroll position instead. That way your browser would jump to the hash straight away.

To animate the whole thing, you can catch the hashchange event, and immediately jump back where you've left off and animate the transition to your heart's content.

Older browsers might experience some flicker, see if it's accaptable for you, worth a try.

var scrollFrom = 0;

$('a[href*=#]').click(function(e){
    scrollFrom = $(window).scrollTop();
});

$(window).bind('hashchange',function(){
    $(window).scrollTop(scrollFrom);
    var target = '#' + location.hash.replace(/#/,'');
    $('html,body').animate({
        scrollTop: $(target).offset().top-170 // modification
    },1000);
});

Alternatively you can do it your way, just prefix the actual IDs of your anchors in the markup to prevent the browser automatically jumping there, then add the prefix to the clicked hash to locate the element with a selector.

Also see @fudgey's answer for cleaning up your 'html,body' selector.

Upvotes: 2

Mottie
Mottie

Reputation: 86483

There are two problems I see:

  1. When you set the hash in the callback function, it makes the page jump to the anchor. So, the best solution, I think, would be to have a margin-bottom under your anchor. That way you don't need to subtract out the 170 pixels, and the hash change in the callback won't make the page jump.
  2. The second problem is using $('html,body') for scrolling. Opera seems to treat both as separate elements, so you will see the page scroll twice. Here is a nice cross-browser fix.

Upvotes: 0

Related Questions