Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery scroll to anchor (minus set amount of pixels)

I am using the following code to scroll to anchor points with jQuery:

$(document).ready(function() {
  function filterPath(string) {
  return string
    .replace(/^\//,'')
    .replace(/(index|default).[a-zA-Z]{3,4}$/,'')
    .replace(/\/$/,'');
  }
  var locationPath = filterPath(location.pathname);
  var scrollElem = scrollableElement('html', 'body');

  $('a[href*=#]').each(function() {
    var thisPath = filterPath(this.pathname) || locationPath;
    if (  locationPath == thisPath
    && (location.hostname == this.hostname || !this.hostname)
    && this.hash.replace(/#/,'') ) {
      var $target = $(this.hash), target = this.hash;
      if (target) {
        var targetOffset = $target.offset().top;
        $(this).click(function(event) {
          event.preventDefault();
          $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
            location.hash = target;
          });
        });
      }
    }
  });

  // use the first element that is "scrollable"
  function scrollableElement(els) {
    for (var i = 0, argLength = arguments.length; i <argLength; i++) {
      var el = arguments[i],
          $scrollElement = $(el);
      if ($scrollElement.scrollTop()> 0) {
        return el;
      } else {
        $scrollElement.scrollTop(1);
        var isScrollable = $scrollElement.scrollTop()> 0;
        $scrollElement.scrollTop(0);
        if (isScrollable) {
          return el;
        }
      }
    }
    return [];
  }

});

Is there anyway to make it scroll to that anchor but minus a set amount of pixels? (in my case i want it to go -92px)

Thanks for any help.

like image 767
John Avatar asked Jul 06 '12 15:07

John


3 Answers

I just had to solve this problem myself. You need to adjust your offset by the amount of pixels you want to scrollTo. In my case, I needed it to be 50 pixels higher on the page. So, I subtracted 50 from targetOffset.

Now, the part of the code that's throwing a wobbly for you is location.hash - this is telling the browser to set its location to a specific point. In all cases, this is a string containing the ID you just scrolled to. So, it'd be something like '#foo'. You need to maintain this, so we'll leave it.

However, to prevent the browser from 'jumping' when location.hash is set (a default browser action), you simply need to prevent the default action. So, pass your event 'e' through the completion function in the animate function. Then simply call e.preventDefault(). You'll have to make sure that the browser is actually calling an event, otherwise it will error out. So, an if-test fixes that.

Done. Here's the revised code chunk:

if (target) {
    var targetOffset = $target.offset().top - 50;
    $(this).click(function(event) {
      if(event != 'undefined') {
          event.preventDefault();}
      $(scrollElem).animate({scrollTop: targetOffset}, 400, function(e) {
          e.preventDefault();
          location.hash = target;
      });
    });
  }
like image 54
Jonathan Savage Avatar answered Nov 12 '22 10:11

Jonathan Savage


This is what I use:

function scrollToDiv(element){
    element = element.replace("link", "");
    $('html,body').unbind().animate({scrollTop: $(element).offset().top-50},'slow');
};

...where 50 is the number of pixels to add/subtract.

like image 22
kaleazy Avatar answered Nov 12 '22 10:11

kaleazy


This code work for me in any link anchor in my site respect "150px" height for fix menu on top.

<!-- SMOOTH SCROLL -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top-150
        }, 1000);
        return false;
      }
    }
  });
});
</script>
<!-- End of SMOOTH SCROLL -->
like image 16
Max Avatar answered Nov 12 '22 10:11

Max