Implementing Twitter Bootstrap 3's Scrollspy plug-in took a bit of trial-and-error, below is my approach and findings for posterity sake (and perhaps someone else's benefit in the future):
My goal was to implement a menu listing on the left with content on the right for an FAQ page. Bootstrap 3's navbar was not the right fit, the list-group was closer, but not perfect (more on that later).
A few findings of note:
li
elements that are children of an element of class .nav
. See Scrollspy source.body
element. If you have a frame with scrollbars (a la the Bootstrap documentation sample), Scrollspy will work, but this is atypical.Let's get to the details. Bottom line is available as a JSFiddle.
The HTML used here is fairly simple, utilizing Bootstrap classes to style a left-hand navigation built with a list-group and content on the right.
<div class="row"> <div class="col-sm-4 col-xs-4" id="nav"> <ul class="nav list-group affix"> <li class="list-group-item"><a href="#g1">Item 1</a></li> <li class="list-group-item"><a href="#g2">Item 2</a></li> <li class="list-group-item"><a href="#g3">Item 3</a></li> <li class="list-group-item"><a href="#g4">Item 4</a></li> <li class="list-group-item"><a href="#g5">Item 5</a></li> </ul> </div> <div class="col-sm-8 col-xs-8"> <section id="g1">Content 1</section> <section id="g2">Content 2</section> <section id="g3">Content 3</section> <section id="g4">Content 4</section> <section id="g5">Content 5</section> </div> </div>
Although possible, I chose not to use Bootstrap's declarative interface to add Scrollspy here because as part of a larger application, another template defines the body
element.
As explained above, adding Scrollspy to the body element typically makes the most sense; however, some of the other articles / discussions on this topic seemed incorrect.
$(document).ready(function() { // plugin is applied to a scrollable element, targeting my navigation element $('body').scrollspy({ 'target': '#nav', 'offset': 10 }); // listen for scrollspy events on the navigation element itself $('#nav').on('activate.bs.scrollspy', function() { console.log('scroll spy!!') }); });
Finally, a bit of CSS to pretty things up and style the list-group to look as desired (very simple approach for demonstration):
section { height: 250px; background-color: #eee; padding: 10px; margin: 10px 0; } li.list-group-item:hover { background-color: #eee; cursor: pointer; } li.list-group-item.active > a, li.list-group-item.active > a:hover, li.list-group-item.active > a:focus { color: #fff; background-color: #428BCA; }
Depending on your content, you may need to change the offset.
That's it. Again, the JSFiddle has a working example.