Skip to content

Commit

Permalink
Add table of contents
Browse files Browse the repository at this point in the history
  • Loading branch information
bushyn committed Feb 25, 2016
1 parent ebd0548 commit 9693f4d
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 0 deletions.
70 changes: 70 additions & 0 deletions css/table_of_contents.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.toc {
box-sizing: border-box;
display: none;
width: 290px;
height: 100%;
padding: .5em;
position: absolute;
overflow: auto;
}

.toc-header {
font-size: 1.3em;
margin: 0;
padding: 0;
}

.toc-link {
direction: ltr;
display: block;
text-decoration: none;
margin: 0 0 .2em;
padding: 0;
line-height: 1.1;
color: inherit;
}

.toc-link:hover, .toc-link:active, .toc-link.current {
color: #1EAEDB;
}

.toc-link.h1 {
font-size: 1em;
}

.toc-link.h2 {
margin-left: .5em;
font-size: .95em;
font-style: italic;
}

.toc-link.h2::before {
content: '•';
margin-right: .5em;
text-align: left;
}

.toc-link.h3 {
margin-left: 1em;
font-size: .9em;
}

.toc-link.h3::before {
content: '◦';
margin-right: .5em;
text-align: left;
}

@media(min-width: 1070px) {
.container {
width: 100%;
max-width: 1050px;
}
.toc {
display: block;
}
.toc + .nine.columns {
margin-left: 350px;
max-width: 700px;
}
}
2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<!-- JavaScripts! -->
<script src="js/anchor.min.js"></script>
<script src="js/table_of_contents.js"></script>

<!-- FONT -->
<link rel="stylesheet" type="text/css" href="https://cloud.typography.com/7584432/7495152/css/fonts.css" />
Expand All @@ -23,6 +24,7 @@
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/skeleton.css">
<link rel="stylesheet" href="css/prism.css">
<link rel="stylesheet" href="css/table_of_contents.css">

<style>

Expand Down
93 changes: 93 additions & 0 deletions js/table_of_contents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
window.addEventListener("DOMContentLoaded", function(event) {
// get headers from page
var content = document.querySelector('.nine.columns');
var headers = [];
var children = content.children;
for (var i = 0, child; i < children.length; i++) {
child = children[i];
if (~['H1', 'H2', 'H3'].indexOf(child.nodeName)) headers.push(child);
}

// create table of contents
var toc = document.createElement('nav');
toc.className = 'toc';
toc.innerHTML = '<h3 class=toc-header>Table of Contents</h3>';
var links = {};
for(var i = 0, header, a; i < headers.length; i++) {
header = headers[i];
a = document.createElement('a');
a.className = 'toc-link ' + header.nodeName.toLowerCase();
a.href ='#' + header.id;
a.textContent = header.textContent;
links[a.hash] = a;
toc.appendChild(a);
}
var top = content.offsetTop;
toc.style.top = top + 'px';
content.parentNode.insertBefore(toc, content);

// make toc sticky
var sticky = false;
var y = toc.getBoundingClientRect().top + pageYOffset;
function stickOnscroll() {
if (!sticky && pageYOffset > y) {
toc.style.position = 'fixed';
toc.style.top = 0;
sticky = true;
} else if (sticky && pageYOffset <= y) {
toc.style.position = 'absolute';
toc.style.top = top + 'px';
sticky = false;
}
}
stickOnscroll();
window.addEventListener('scroll', stickOnscroll);

// highlight current link
var previous = null, current = null;
function highlight(hash) {
current = links[hash];
if (previous == current) return;
previous && previous.classList.remove('current');
current && current.classList.add('current');
previous = current;
}
highlight(location.hash);
current && current.scrollIntoView();
window.addEventListener('hashchange', function() {
highlight(location.hash);
});

// determine sections by pixels because markup is not semantic
var positions = headers.map(function(h) {
return {hash: '#' + h.id, y: h.getBoundingClientRect().top + pageYOffset};
});
function highlightOnScroll() {
for (var i = positions.length - 1; i >= 0; i--)
if (positions[i].y <= pageYOffset + 30) {
highlight(positions[i].hash);
break;
}
}
window.addEventListener('scroll', highlightOnScroll);

var highlightOnResize = debounce(function() {
positions = headers.map(function(h) {
return {hash: '#' + h.id, y: h.getBoundingClientRect().top + pageYOffset};
});
highlightOnScroll();
current && current.scrollIntoView();
}, 300);
window.addEventListener('resize', highlightOnResize);
});

function debounce(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}

0 comments on commit 9693f4d

Please sign in to comment.