Skip to content

Instantly share code, notes, and snippets.

@k1sul1
Created April 18, 2016 15:39
Show Gist options
  • Save k1sul1/e45f3ee71c58681ebd16a23dbe730fbb to your computer and use it in GitHub Desktop.
Save k1sul1/e45f3ee71c58681ebd16a23dbe730fbb to your computer and use it in GitHub Desktop.
Dynamic post navigation that sticks around. jQuery-free.
window.$ = function (selector){
return Array.prototype.slice.call(document.querySelectorAll(selector));
};
window.getOffset = function(el) {
el = el.getBoundingClientRect();
return {
left: el.left + window.scrollX,
top: el.top + window.scrollY
};
};
var sidebar = document.getElementById("service-sidebar");
var headers = $("article .entry-content > h2");
var sidebarHeight = sidebar.offsetHeight;
var startPos = getOffset($("main#main > .text-container")[0]).top - 80;
var endPos = getOffset($(".entry-footer")[0]).top - sidebarHeight;
var scroller = function(){
if(window.scrollY < startPos){
sidebar.classList.remove("fixed");
sidebar.classList.remove("absolute");
sidebar.style.top = null;
}
if(window.scrollY >= startPos && window.scrollY < endPos){
sidebar.classList.add("fixed");
sidebar.classList.remove("absolute");
sidebar.style.top = null;
}
if(window.scrollY >= endPos){
sidebar.classList.remove("fixed");
sidebar.classList.add("absolute");
sidebar.style.top = endPos + "px";
}
};
window.addEventListener("scroll", scroller);
var resetActive = function(){
var links = $("aside#service-sidebar a");
links.forEach(function(link){
link.classList.remove("active");
});
};
headers.forEach(function(header){
header.id = header.textContent; // assign id for h2
var el = document.createElement("a");
el.textContent = header.textContent;
el.href = "#" + header.textContent;
el.addEventListener("click", function(e){
var _this = e.target;
resetActive();
_this.classList.add("active");
});
sidebar.appendChild(el);
});
var setActiveByScroll = function(){
var windowPos = window.scrollY;
for(var i = 0; i < headers.length; i++){
var header = headers[i];
var headerPos = getOffset(header).top;
var nextHeader;
var nextHeaderPos;
if(typeof headers[i+1] !== "undefined"){
nextHeader = headers[i+1];
nextHeaderPos = getOffset(nextHeader).top - 30; // 30px offset w/ css
// check if we're already past the header after the current one.
}
else{
nextHeader = null;
nextHeaderPos = 99999999;
}
var links = $("aside#service-sidebar a");
if(windowPos > headerPos && windowPos < nextHeaderPos){
resetActive();
setActive(links);
}
}
function setActive(links){
links.filter(function(link){
return link.hash === "#" + header.id;
}).forEach(function(link){
link.classList.add("active");
});
}
};
window.addEventListener("scroll", setActiveByScroll);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment