From 728620b527dd4d8e308c9344e319e5e11bdad859 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 31 Jan 2020 14:17:22 +0100 Subject: [PATCH] Mark active item in table of contents (#733) --- blog/static/css/main.css | 11 +++++++++-- blog/static/js/main.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/blog/static/css/main.css b/blog/static/css/main.css index b0f18a5c..7f940cbb 100644 --- a/blog/static/css/main.css +++ b/blog/static/css/main.css @@ -193,14 +193,21 @@ aside#all-posts-link { margin-left: -15rem; font-size: 90%; line-height: 1.2; + } + + #toc-aside li:not(.active) > a, #toc-aside h2 { opacity: .5; transition: opacity .5s; } - #toc-aside:hover { + #toc-aside:hover li:not(.active) > a, #toc-aside:hover h2 { opacity: 1; } + #toc-aside li.active > a { + font-weight: bold; + } + #toc-aside h2 { font-size: 110%; margin-bottom: .2rem; @@ -212,7 +219,7 @@ aside#all-posts-link { list-style:none; } - #toc-aside ol li:before { + #toc-aside ol li a:before { content: ""; border-color: transparent #008eef; border-style: solid; diff --git a/blog/static/js/main.js b/blog/static/js/main.js index 96ed6181..ce6b080b 100644 --- a/blog/static/js/main.js +++ b/blog/static/js/main.js @@ -3,6 +3,8 @@ window.onload = function() { if (container != null) { resize_toc(container); + toc_scroll_position(container); + window.onscroll = function() { toc_scroll_position(container) }; } } @@ -24,3 +26,38 @@ function resize_toc(container) { resizeId = setTimeout(resize, 300); }; } + +function toc_scroll_position(container) { + if (container.offsetParent === null) { + // skip computation if ToC is not visible + return; + } + var items = container.querySelectorAll("li") + + // remove active class for all items + for (item of container.querySelectorAll("li")) { + item.classList.remove("active"); + } + + // look for active item + var site_offset = document.documentElement.scrollTop; + var current_toc_item = null; + for (item of container.querySelectorAll("li")) { + if (item.offsetParent === null) { + // skip items that are not visible + continue; + } + var anchor = item.firstElementChild.getAttribute("href"); + var heading = document.querySelector(anchor); + if (heading.offsetTop <= (site_offset + document.documentElement.clientHeight / 3)) { + current_toc_item = item; + } else { + break; + } + } + + // set active call for current ToC item + if (current_toc_item != null) { + current_toc_item.classList.add("active"); + } +}