Fixes #466. Adds support for header highlighting using intersection observer.

This commit is contained in:
Abijeet 2017-11-02 01:14:06 +05:30
parent 0d5d77d8ab
commit 1031c61d0c
2 changed files with 56 additions and 0 deletions

View file

@ -150,6 +150,59 @@ let setupPageShow = window.setupPageShow = function (pageId) {
unstickTree(); unstickTree();
} }
}); });
// Check if support is present for IntersectionObserver
if ('IntersectionObserver' in window &&
'IntersectionObserverEntry' in window &&
'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
$(document).ready(function () {
// fetch all the headings.
let headings = document.querySelector('.page-content').querySelectorAll('h1, h2, h3, h4, h5, h6');
// if headings are present, add observers.
if (headings.length > 0) {
addNavObserver(headings);
}
});
}
let $pageNav = null;
function addNavObserver(headings) {
// Setup the intersection observer.
// margin top = -25px to trigger the threshold change before the heading
// has completely left the viewport on the top.
let intersectOpts = {
rootMargin: '-25px 0px 0px 0px',
threshold: 1.0
}
$pageNav = $('.sidebar-page-nav');
let pageNavObserver = new IntersectionObserver(cbHeadingVisible, intersectOpts);
// observe each heading
for (let i = 0; i !== headings.length; ++i) {
pageNavObserver.observe(headings[i]);
}
}
function cbHeadingVisible(entries, observer) {
let element = null;
for (let i = 0; i !== entries.length; ++i) {
let currentEntry = entries[i];
// check if its currently visible and its distance from top of viewport is less than 100
if (currentEntry.intersectionRatio <= 1 && currentEntry.boundingClientRect.y < 100) {
element = currentEntry.target;
} else {
break;
}
}
if (!element) {
return;
}
let elementId = element.id;
$pageNav.find('a').removeClass('current-heading');
$pageNav.find('a[href="#' + elementId + '"]').addClass('current-heading');
}
}; };
module.exports = setupPageShow; module.exports = setupPageShow;

View file

@ -82,6 +82,9 @@
.h6 { .h6 {
margin-left: $nav-indent*4; margin-left: $nav-indent*4;
} }
.current-heading {
font-weight: bold;
}
} }
// Sidebar list // Sidebar list