Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scrollspy Using Full URL

I am trying to get scrollspy to work when using an absolute url rather than an # anchor link.

For example, I can easily run scrollspy by using only <a href="#section1"></a>

I would like to be able to run scrollspy by using <a href="http://myurl.com/#section1"></a>

The reason for doing this, is the main navigation on the homepage is scorllspy, but the blog is not part of the homepage. When visiting the blog and then clicking a link to somthing on the homepage, you get routed to http://myurl.com/blog/#section1 rather than the homepage ID.

I found this solution ( use url and hash with bootstrap scrollspy ) , but could not get it to fully function. After some tweaking and a slew of regex combinations I could get it to add the active class to the first menu item, but it would not refresh.

Any thoughts on getting this to work? Is there an alternative js library I should use?

Solution thanks to Troy

jQuery(function($){
  // local url of page (minus any hash, but including any potential query string)
  var url = location.href.replace(/#.*/,'');

  // Find all anchors
  $('.nav-main').find('a[href]').each(function(i,a){
    var $a = $(a);
    var href = $a.attr('href');

    // check is anchor href starts with page's URI
    if (href.indexOf(url+'#') == 0) {
      // remove URI from href
      href = href.replace(url,'');
      // update anchors HREF with new one
      $a.attr('href',href);
    }

    // Now refresh scrollspy
    $('[data-spy="scroll"]').each(function (i,spy) {
      var $spy = $(this).scrollspy('refresh')
    })
  });

  $('body').scrollspy({ target: '.nav-main', offset: 155 })

});

I added $('body').scrollspy({ target: '.nav-main', offset: 155 }) in order to get the data offset to re-apply after refreshing scrollspy. After some trial and error, this is the only solution I was able to find.

like image 442
SmashBrando Avatar asked Jan 14 '14 06:01

SmashBrando


2 Answers

Or you can add data-target attribute to your link element: data-target="#link"

<a href="http://www.site.ru/#link1" data-target="#link1">Link1</a>
<a href="http://www.site.ru/#link2" data-target="#link2">Link2</a>
like image 173
kerstvo Avatar answered Oct 23 '22 17:10

kerstvo


The way scrollspy is coded, it looks at anchors that have href's that start with a #.

There is one way you could do this. Not pretty but may work.

Once the page loads, in your jQuery ready function, search the document for all anchors (inside of your target container, or body), and check to see if the href starts with your hostname, followed by a/#, and if it matches change the anchor's href to just be the portion after the #

Here is some rough code (not tested) that you could try (say your scrollspy target is a div with id of #navbar:

jQuery(function($){
  // local url of page (minus any hash, but including any potential query string)
  var url = location.href.replace(/#.*/,'');

  // Find all anchors
  $('#navbar').find('a[href]').each(function(i,a){
    var $a = $(a);
    var href = $a.attr('href');

    // check is anchor href starts with page's URI
    if (href.indexOf(url+'#') == 0) {
      // remove URI from href
      href = href.replace(url,'');
      // update anchors HREF with new one
      $a.attr('href',href);
    }

    // Now refresh scrollspy
    $('[data-spy="scroll"]').each(function (i,spy) {
       $(spy).scrollspy('refresh');
    });
  });

});

Now make sure you run this after you load the bootstrap.min.js file.

If you are initializing your ScrollSpy via javascript, rather than via data-* attributes, then replace the three lines of code where scrollspy is refreshed wit the code to initialise your scrollspy target & settings.

like image 34
Troy Morehouse Avatar answered Oct 23 '22 18:10

Troy Morehouse