Anchor links scroll

Hey X theme,

On my site http://jagkin.com, if you look under “About” and “Services” you will see the anchor links I’ve created. To create them I gave each relevant section an ID then linked the menu items with the format /page-name/#ID.

If you visit them you will notice a few errors:

  1. The anchors correctly visit each section but doesn’t take into account the menu, resulting in the menu covering the uppermost part of the section. We would like if the bottom of the menu just touches the very top of the next section that we are linking to.

  2. Ideally we have smooth scroll to anchor sections like other sites have and not just a random jump. We’d like to have this implemented both within a single page and across two different pages. I seem to recall this being a function that X was capable of previously (and built in before) so hoping that it is an easy fix.

Please advise on what we should do. Let me know if there is something that doesn’t make sense. Thanks very much,

jagelman

Hi there,

Thanks for writing in.

It’s only applicable for one-page navigation and your pages aren’t. Please add this code to your global custom javascript instead

jQuery ( document ).ready ( function( $ ) {

var hash = window.location.hash;

if ( hash !== "") {

$('html, body').stop().animate ( { scrollTop : $(hash).offset().top - 47 } ); 

}

} );

Please note that this may conflict your existing javascript (if there is existing code with the same function as this) and this may not work in the future. This is provided as snippet and we don’t provide support for custom scripts but you’re free to enhance it :slight_smile:

Thanks.

Hey @iam,

Thanks so much for your prompt reply. I just tried it and everything seems to work except for the offset. Could you please help me have a look at this again?

Thanks

j

Edit: You can still visit the page here: http://www.jagkin.com/services/#compliance

Hi again,

You can replace the previous code with this:

jQuery(document).ready(function($) {

  var $body                = $('body');
  var bodyHeight           = $body.outerHeight();
  var adminbarHeight       = $('#wpadminbar').outerHeight();
  var navbarFixedTopHeight = $('.hm1.x-bar').outerHeight();
  var locHref              = location.href;
  var locHashIndex         = locHref.indexOf('#');
  var locHash              = locHref.substr(locHashIndex);
  var dragging             = false;
  
  $body.on('touchmove', function() {
      dragging = true;
  } );
  
  $body.on('touchstart', function() {
      dragging = false;
  } );


  //
  // Calculate the offset height for various elements and remove it from
  // the element's top offset so that fixed elements don't cover it up.
  //

  function animateOffset( element, ms, easing ) {
    $('html, body').animate({
      scrollTop: $(element).offset().top - adminbarHeight - navbarFixedTopHeight + 1
    }, ms, easing);
  }


  //
  // Page load offset (if necessary).
  //

  $(window).load(function() {
    if ( locHashIndex !== -1 && $(locHash).length ) {
      animateOffset(locHash, 1, 'linear');
    }
  });


  //
  // Scroll trigger.
  //

  $('a[href*="#"]').unbind('touchend click').on('touchend click', function(e) {
      console.log($('.hm1.x-bar-fixed').outerHeight());
    href        = $(this).attr('href');
    notComments = href.indexOf('#comments') === -1;
    if ( href !== '#' && notComments ) {
      var theId = href.split('#').pop();
      var $el   = $('#' + theId);
      if ( $el.length > 0 ) {
        e.preventDefault();
        
        if (dragging) {
            return;
        }
        
        animateOffset($el, 850, 'easeInOutExpo');
      }
    }
  });
});

Since you’re using header shrinking feature, this may cause offset issues in the above code, to make it work flawless I’d suggest you to turn off the shrinking feature.

Hope this helps!

Thanks so much! This worked perfectly with the suggestions you made.

I have the same issue with another website now (just with the aligning of the menu). For some reason on this site the smooth scroll anchors work automatically, it is just the menu alignment that isn’t functional. I think it may be the stack I am using (Ethos) maybe has the smooth scroll anchors built in?

Anyway please advise on what I should do. I don’t want to just use this code straight up because i’m not sure if that would conflict with the scroll code already there. However if that is what is best then let me know.

P.S. the new site is http://fudge.jagelman.asia/mandates/, anchors are in the menu. :slight_smile:

Thanks so much for your time and help with this (if only my jquery skills were up to scratch I could maybe figure this out myself :-P)

jagelman

Hi again,

For your other site above code will work without an issue that is:

jQuery(document).ready(function($) {

  var $body                = $('body');
  var bodyHeight           = $body.outerHeight();
  var adminbarHeight       = $('#wpadminbar').outerHeight();
  var navbarFixedTopHeight = $('.hm1.x-bar').outerHeight();
  var locHref              = location.href;
  var locHashIndex         = locHref.indexOf('#');
  var locHash              = locHref.substr(locHashIndex);
  var dragging             = false;
  
  $body.on('touchmove', function() {
      dragging = true;
  } );
  
  $body.on('touchstart', function() {
      dragging = false;
  } );


  //
  // Calculate the offset height for various elements and remove it from
  // the element's top offset so that fixed elements don't cover it up.
  //

  function animateOffset( element, ms, easing ) {
    $('html, body').animate({
      scrollTop: $(element).offset().top - adminbarHeight - navbarFixedTopHeight + 1
    }, ms, easing);
  }


  //
  // Page load offset (if necessary).
  //

  $(window).load(function() {
    if ( locHashIndex !== -1 && $(locHash).length ) {
      animateOffset(locHash, 1, 'linear');
    }
  });


  //
  // Scroll trigger.
  //

  $('a[href*="#"]').unbind('touchend click').on('touchend click', function(e) {
      console.log($('.hm1.x-bar-fixed').outerHeight());
    href        = $(this).attr('href');
    notComments = href.indexOf('#comments') === -1;
    if ( href !== '#' && notComments ) {
      var theId = href.split('#').pop();
      var $el   = $('#' + theId);
      if ( $el.length > 0 ) {
        e.preventDefault();
        
        if (dragging) {
            return;
        }
        
        animateOffset($el, 850, 'easeInOutExpo');
      }
    }
  });
});

Just add it in your Customizer and make sure to clear the cache after adding the code.

Cheers!