user7281939
user7281939

Reputation:

Scroll to specific section, smooth at first but then jumps/shifts down the screen

I'm currently trying to get my navigation bar (fixed at the top of the screen) to work better. Currently, if you press on a link within the nav bar, it will go to a certain section with this code:

   $('a[href^="#"]').bind('click.smoothscroll',function (e) {
       e.preventDefault();

       var target = this.hash,
           $target = $(target);

       $('html, body').animate({
           'scrollTop': $target.offset().top - 45
       }, 400, 'swing', function () {
           window.location.hash = target;
       });
   });
  });

However, it will go to that section but then shift down on the screen and cover content. But if I press the same section again, it will go to the correct spot. I need it to go to the correct spot on the first click.

When I take out the "- 35" part within animate(), it doesn't shift down and goes smoothly, but I need the "- 35" part to offset the nav bar or else it will cover content every time. What is causing this jumping/shifting? Any advice or information that would be helpful? Thanks!

Note: I also have this code, but I'm not sure if it's part of the issue:

$(document).ready(function(){
   var offset = $(".navbar").offset().top;
   $(window).scroll(function() {
         if ($(window).scrollTop() >= offset) {
             $('.navbar').addClass('navbar-fixed');
         }
    });

UPDATE: I fixed my issue by reading more into the details of jQuery's animate. The parameter "complete" (a function to call once the animation is complete, called once per matched element) that I was using was not necessary, so I removed it from my code.

Upvotes: 3

Views: 486

Answers (1)

muecas
muecas

Reputation: 4335

You need to avoid setting the hash after the animation is completed. As you use an offset for the animation (the -45) the animation will run smoothly to the given coordinates, and then it will jump to the hash position when you set the location.hash (after the animation is completed). The solution is to remove the hash from the location (the preventDefault() does that), and don’t set it again after animation is completed.

$('a[href^="#"]').bind('click.smoothscroll',function (e) {
    e.preventDefault();
    var target = this.hash,
        $target = $(target);
    $('html, body').animate({
        'scrollTop': $target.offset().top - 45
    }, 400, 'swing');
});

Upvotes: 2

Related Questions