0

So the specific functionality I'm looking for is a link on one page (e.g. drupalsite/home) leading directly to a specific section of another page (e.g. a section on drupalsite/otherpage).

I believe that to implement this I need to use hash based navigation such that the content I want to link to is has it's css class name preceded by a hash (pound sign or number symbol) <div class="#mydiv"> and is linked to by including the hash referenced content in the href attribute of an anchor tag. Such that <div class="#mydiv"> on page drupalsite/mypage via <a href="/mypage#mydiv">.

Will this work without out of the box with just HTML changes? Or is additional JavaScript configuration necessary?

I know that more specific and fluid implementations will necessitate JavaScript and jQuery, but I want to know if the core HTML works without conflicting with Drupal's internals.

  • The target needs an id, not class <p id="my_target">Link me</p> and those links like <a href="/some-page#my_target">Click me</a> work without any problem in Drupal core. It is just HTML. – Hudri Jan 16 '19 at 14:42
  • My mistake, I was really wondering if there were any gotchas to this? I know the implementation can be improved upon. – nizz0k Jan 16 '19 at 14:49
  • Actually I've had quite a few gotchas, mainly due responsive images (those have no height set, so the viewport might change when the images is loaded slowly) and due fixed parts (if you have a fixed navbar, it might overlap the top of your linked section). For the first part I used ImagesLoaded, the 2nd part I'm doing hardcoded per project. – Hudri Jan 16 '19 at 15:04
  • That definitely seems relevant and important. Thanks. – nizz0k Jan 16 '19 at 15:05
  • The edit to my title is incorrect. I do not mean "one page" navigation as it is not a SPA. I mean "hash based" navigation. – nizz0k Jan 18 '19 at 14:08
0

This is the code I'm using on most of my projects

(function ($, Drupal) {
  var wt = window.wt || {}; //just my personal namespace

  wt.getFixedTop = function() { 
    /* return pixel height of fixed elements, e.g. Admin Toolbar or a fixed main nav */
  };

  wt.scrollTo = function(uri) {
    if ((uri.indexOf(location.pathname) === 0 || uri.indexOf('#scroll') === 0) && uri.indexOf('#scroll') !== -1) {
      var selector = decodeURIComponent(uri.substring(uri.indexOf('#scroll') + '#scroll'.length));
      var regex = /^=[#\.\[\]a-zA-Z0-9-_]+$/;
      if (selector.search(regex) != -1) {
        selector = selector.substring(1);
        $('html, body').animate({scrollTop: $(selector).offset().top - wt.getFixedTop() }, 1000);
      }
      return false;
    }
  }

  $('body').on('click', 'a[href*="#scroll"]', function () {
    wt.scrollTo($(this).attr('href'));
  });

  $('body').imagesLoaded( function() {
    window.setTimeout( wt.scrollTo(location.pathname + location.hash), 200 );
  });

}(jQuery, Drupal));

It requires ImagesLoaded and works within and across pages, and with responsive images. It also allows linking to IDs and classes by appending the proper CSS selector, e.g. /some-page#scroll=.my_class

It certainly is not a perfect solution, but our internal, HTML-trained editors can quickly create deep links to any section they want by adding #scroll=<CSS_ID_OR_CLASS_SELECTOR> to any link.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.