2

I have a fixed header, of which has a handful of links. Now, this code is almost where I need it to be to work, the main issue being that there's a delay when executing the second function. It does it's intended purpose of scrolling to the top of the page when the bound element is clicked, but it does so slowly at first, before continuing at the specified speed. I'm sure there's also a way to DRY this up and turn it into a single function instead of two separate ones. Any help would be greatly appreciated.

$(function() {
  $("[href^='#']").on("click", function( e ) {  
    $("body, html").animate({ 
      scrollTop: $( $(this).attr('href') ).offset().top-$('.header').height()-$('.header').outerHeight()
    }, 800); 
    e.preventDefault();
  });    
});


$(function(){
    $("#home").on("click", function( e ){
        $("body, html").animate({
            scrollTop: 0
        }, 800);
        e.preventDefault();
    });
});

JSFiddle - http://jsfiddle.net/9by4n5cu/1/

PMills
  • 161
  • 1
  • 1
  • 9

2 Answers2

2

You can merge two function like bellow,

  $(function() {
    $("[href^='#']").on("click", function( e ) {  

      var target = $(this).attr('href');

      var scrollTop = $( target ).offset().top-$('.header').height()-$('.header').outerHeight();

      if ( target =='#home'){
         scrollTop = 0;
      }

      $("body, html").animate({
              scrollTop: scrollTop
          }, 800);

      e.preventDefault();


    });

  });

Demo : http://jsfiddle.net/ibrahim12/9by4n5cu/3/

Ibrahim
  • 584
  • 6
  • 15
0

it's delayed because you trigger the animate twice, so like what you say, you need to merge the function as one like this

$(function () {
    $("[href^='#']").on("click", function (e)  {
        var link = $(this);
        var $header = $('.header')
        var top = link.attr("id") == "home" ? 0 : $(link.attr('href')).offset().top - $header.height() - $header.outerHeight()

        //$("html").animate({

        $("body, html").animate({    // Use $("body, html") to work on all browser as noted by Ibrahim
            scrollTop: top
        }, 800);
        e.preventDefault();
    });
});

I use the first click function, then check whether the id of the link that's clicked is home, if yes, set the top to 0, else do the calculation as you do before.

here's the updated Fiddle Fiddle

Kyojimaru
  • 2,694
  • 1
  • 14
  • 22
  • I really want this to work, because it's so effing dry and beautiful, but even the jfiddle is unresponsive. Something's off mate. – PMills Nov 20 '14 at 07:57
  • @PMills, what didn't work and unresponsive? It's working fine in my browser. – Kyojimaru Nov 20 '14 at 08:42
  • 1
    `$("html").animate({` -> change this line to `$("body, html").animate({` to work on all browsers. – Ibrahim Nov 20 '14 at 13:56
  • @Ibrahim, thanks for the info :), I just know now that the `overflow` places is different for each browser from [this answers](http://stackoverflow.com/a/8149216) after what you said, thanks a lot :) – Kyojimaru Nov 21 '14 at 02:12