‘Autospy’ for scrollspy.js

Written by:
Posted in: ,
Published: November 24, 2013

On a recent Bootstrap-based WordPress project, we wanted to make use of the scrollspy.js plugin, but there was no way to automatically populate the sidebar based on headings found in the content. Since most of the pages on the site had different layouts, we needed a way to dynamically populate the sidebar navigation based on what content was available on any given page. This is a pretty simple script, but we offer it up to the world in the hopes it might help someone out.

Just specify the heading type you’d like to use for your top-level menu, and heading type to use for sub-level menus. For example, using [code]h3[/code] and [code]h4[/code], the script will first locate all of the [code]h3[/code]’s on the page, then it will look for any [code]h4[/code] tags in the same parent container (or lower) than the [code]h3[/code], and put them into a [code]<ul class=”nav”>[/code] inside the parent [code]li[/code]. See a demo here.

[code javascript]
jQuery(document).ready(function($) {
var topLevel = $(‘h3’);
var subLevel = $(‘h4’);

topLevel.each(function () {

var $menuItem = $(&quot;&lt;li&gt;&lt;a href=’#&quot; + $(this).attr(&quot;id&quot;) + &quot;’&gt;&quot; + $(this).text() + &quot;&lt;/a&gt;&lt;/li&gt;&quot;);
$(‘#sidebar-affix .nav’).append($menuItem);

if($(this).parent().find(subLevel).length) {

var $subMenu = $(&quot;&lt;ul class=’sub-nav’&gt;&lt;/ul&gt;&quot;);
$menuItem.append($subMenu);

$(this).parent().find(subLevel).each(function (){

var $submenuItem = $(&quot;&lt;li&gt;&lt;a href=’#&quot; + $(this).attr(&quot;id&quot;) + &quot;’&gt;&quot; + $(this).attr(‘title’) + &quot;&lt;/a&gt;&lt;/li&gt;&quot;);
$subMenu.append($submenuItem);

});
}
});
});
[/code]