4

I have a nav menu bar based on twitter bootstrap that I want to apply scrollspy to for hightlighting. i include the menu into multiple pages using a normal php include. therefore I am linking to files using their filename plus bookmark (e.g. products.php#foo).

but the way that scrollspy wants urls to work is to use the format <a href="#id-of-target">my link</a>, so that when <div id="id-of-target"> scrolls into view, the href is matched based on the href attrib and gets the active class put on it.

which means that if I have a link like <a href="products.php#my-catalogue">my catalogue</a> then it won't match the id and the link won't highlight.

i couldn't work out how to modify scrollspy so that it only matches on the id after the # in the href value.

frumbert
  • 2,323
  • 5
  • 30
  • 61

2 Answers2

14

New Answer

(1) You can add a data-target to your link like so:

<a href="products.php#my-catalogue" data-target="#my-catalogue">my catalogue</a>

(2) Bootstrap uses either your href or data-target in your nav links to find the target regions on the page. If you have something like products.php#my-catalogue the regular expression checker in the code will fail. But if you do a trim beforehand it will work

In scroll spy bootstrap code you can change (in the "refresh" function in ScrollSpy):

.map(function () {
    var $el = $(this)
              , href = $el.data('target') || $el.attr('href')
              , $href = /^#\w/.test(href) && $(href)

to

.map(function () {
    var $el = $(this)
              , href = $el.data('target') || $el.attr('href')
              , trimmed = href.match(/#\w*/)[0]
              , $href = /^#\w/.test(trimmed) && $(trimmed)

and then having something like

<a href="products.php#my-catalogue">my catalogue</a>

should be no problem


Old Answer

Maybe you could try editing the scroll spy selector in the bootstrap js code?

There is a line (around 1442 for me):

selector = this.selector
      + '[data-target="' + target + '"],'
      + this.selector + '[href="' + target + '"]'

If changed to

 selector = this.selector
      + '[data-target="' + target + '"],'
      + this.selector + '[href="products.php' + target + '"]'

Could solve your problem

hajpoj
  • 13,299
  • 2
  • 46
  • 63
  • that gave me an idea, and I tried using an "endswith" selector inside it, so that it looked like `selector = this.selector + '[data-target="' + target + '"],' + this.selector + '[href$="' + target + '"]'` - but this didn't work. :( – frumbert Oct 05 '12 at 03:57
  • damn, it's this: `$href = /^#\w/.test(href)` - link must start with # - I think I need to combine it with the previous and state "any link ending with a #something"; tried, doesn't help :( – frumbert Oct 05 '12 at 04:16
  • Dang, yeah. There absolutely has to be a way to do this with some tinkering, but I'm not positive off the top of my head how to do it :( – hajpoj Oct 06 '12 at 01:33
  • 4
    Actually there is a simple solution: add a data-target property to your links like so: `my catalogue` – hajpoj Oct 06 '12 at 23:47
  • *slaps own head* when in doubt, re-read the documentation. How did I miss that? – frumbert Oct 07 '12 at 09:26
2

Adding data-target="#target" works perfectly. I use it in services sub-pages. Here's a working example:

http://calebserna.com/services/web-design/

Visitors can browse through a list of services that link to another page very smoothly.