Instantly share code, notes, and snippets.
Last active
March 5, 2018 13:15
-
Save gregogalante/7265398968b117a0127a2989842e1e62 to your computer and use it in GitHub Desktop.
A module to create a sidebar sections navigation based on content titles.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var SidebarSections = (function () { | |
var CONTENT_CONTAINER = 'YOUR CONTENT CONTAINER SELECTOR' | |
var SIDEBAR_CONTAINER = 'YOUR SIDEBAR CONTAINER SELECTOR' | |
var _titles = [] | |
var _titlesGroup = [] | |
// This function is used to initialize the module. | |
var init = function () { | |
_loadTitles() | |
_markTitles() | |
_groupTitles() | |
_createSidebar(null, _titlesGroup) | |
_animateScroll() | |
} | |
var _loadTitles = function () { | |
var container = jQuery(CONTENT_CONTAINER) | |
container.children('h2, h3, h4, h5, h6').each(function (_index, value) { | |
_titles.push(value) | |
}) | |
} | |
var _markTitles = function () { | |
for (var i = 0; i < _titles.length; i++) { | |
var jQueryElement = jQuery(_titles[i]) | |
jQueryElement.attr('id', _parametize(jQueryElement.text())) | |
} | |
} | |
var _groupTitles = function () { | |
var title, level, before | |
for (var i = 0; i < _titles.length; i++) { | |
title = _titles[i] | |
level = parseInt(title.tagName[title.tagName.length - 1]) | |
if (!before) { | |
_titlesGroup.push(_createNode(title, level, null)) | |
before = _titlesGroup[_titlesGroup.length - 1] | |
continue | |
} | |
if (level > before.level) { | |
before.children.push(_createNode(title, level, before)) | |
before = before.children[before.children.length - 1] | |
continue | |
} | |
if (level === before.level && before.parent) { | |
before.parent.children.push(_createNode(title, level, before.parent)) | |
before = before.parent.children[before.parent.children.length - 1] | |
continue | |
} | |
if (level === before.level && !before.parent) { | |
_titlesGroup.push(_createNode(title, level, null)) | |
before = _titlesGroup[_titlesGroup.length - 1] | |
continue | |
} | |
if(level < before.level) { | |
while (before !== null || (before && before.level !== level)) { | |
before = before.parent ? before.parent : null | |
} | |
if (!before) { | |
_titlesGroup.push(_createNode(title, level, null)) | |
before = _titlesGroup[_titlesGroup.length - 1] | |
} else { | |
before.parent.children.push(_createNode(title, level, before.parent)) | |
before = before.parent.children[before.parent.children.length - 1] | |
} | |
} | |
} | |
} | |
var _createSidebar = function (parent, children) { | |
if( !children || !children.length ) return | |
if (!parent) { | |
parent = jQuery(SIDEBAR_CONTAINER) | |
} | |
var i, l, list, li, a | |
list = jQuery("<ul></ul>").appendTo(parent) | |
for(i = 0, l = children.length; i < l; i++) { | |
li = jQuery("<li></li>") | |
jQuery("<a></a>") | |
.text(children[i].title.innerText) | |
.attr('href', '#' + children[i].title.id) | |
.appendTo(li) | |
_createSidebar(li, children[i].children) | |
list.append(li) | |
} | |
} | |
var _animateScroll = function () { | |
jQuery(SIDEBAR_CONTAINER + " a[href^='#']").click(function (e) { | |
e.preventDefault() | |
var position = jQuery(jQuery(this).attr("href")).offset().top - 40 | |
jQuery("body, html").animate({ | |
scrollTop: position | |
} /* speed */ ) | |
}) | |
} | |
// Helpers: | |
function _parametize (str) { | |
return str.trim().toLowerCase().replace(/[^a-zA-Z0-9 -]/, "").replace(/\s/g, "-"); | |
} | |
function _createNode(title, level, parent) { | |
var node = { | |
title: title, | |
level: level, | |
parent: parent, | |
children: [] | |
} | |
return node | |
} | |
return { | |
init | |
} | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment