Scrollspy-style updating of hash and TOC highlighting

This commit is contained in:
Erik Demaine 2019-01-04 12:29:13 -05:00
parent d361c00f8a
commit f2f580101e
4 changed files with 49 additions and 2 deletions

View file

@ -507,6 +507,11 @@
border-top-left-radius: $border-radius;
border-top-right-radius: $border-radius;
}
// Scrollspy marks toc items as .active when they are in focus
.active {
background: $active-color;
}
}
.toc__menu {

View file

@ -61,6 +61,7 @@ $muted-text-color: mix(#fff, $text-color, 35%) !default;
$border-color: $lighter-gray !default;
$form-background-color: $lighter-gray !default;
$footer-background-color: $lighter-gray !default;
$active-color: mix($light-gray, $lighter-gray, 50%) !default;
$primary-color: #6f777d !default;
$success-color: #3fa63f !default;

View file

@ -64,10 +64,13 @@ $(document).ready(function() {
// Smooth scrolling
// Bind popstate event listener to support back/forward buttons.
var smoothScrolling = false;
$(window).bind("popstate", function (event) {
$.smoothScroll({
scrollTarget: location.hash,
offset: -20
offset: -20,
beforeScroll: function() { smoothScrolling = true; },
afterScroll: function() { smoothScrolling = false; }
});
});
// Override clicking on links to smooth scroll
@ -83,6 +86,44 @@ $(document).ready(function() {
$(window).trigger("popstate");
}
// Scrollspy equivalent: update hash fragment while scrolling.
var timer;
$(window).scroll(function() {
// Don't run while smooth scrolling (from clicking on a link).
if (smoothScrolling) return;
// Debounce: only run after 250 ms of no scrolling.
clearTimeout(timer);
timer = setTimeout(function () {
var scrollTop = $(window).scrollTop() + 20; // 20 = offset
var links = [];
$("nav.toc a").each(function() {
var link = $(this);
var href = link.attr("href");
if (href && href[0] == "#") {
var element = $(href);
links.push({
link: link,
href: href,
top: element.offset().top
});
link.removeClass('active');
}
});
for (var i = 0; i < links.length; i++) {
var top = links[i].top;
var bottom = (i < links.length - 1 ? links[i+1].top : Infinity);
if (top <= scrollTop && scrollTop < bottom) {
// Mark all ancestors as active
links[i].link.parents("li").children("a").addClass('active');
if (links[i].href !== location.hash) {
history.replaceState(null, null, links[i].href);
}
break;
}
}
}, 250);
});
// add lightbox class to all image links
$(
"a[href$='.jpg'],a[href$='.jpeg'],a[href$='.JPG'],a[href$='.png'],a[href$='.gif']"

File diff suppressed because one or more lines are too long