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.
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With