Skip to content

Commit f3c5ad3

Browse files
authored
Highlight Sidebar Links When Scrolling (#36)
1 parent 8b6ebff commit f3c5ad3

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

js/book.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,49 @@ window.onunload = function () { };
268268
previousScrollTop = document.scrollingElement.scrollTop;
269269
}, { passive: true });
270270
})();
271+
272+
(function highlightSideBarLink() {
273+
var anchorsToLink = {};
274+
var $sidebarLinks = $('#sidebar .chapter a');
275+
$sidebarLinks.each(function(_, link) {
276+
var match = link.href.match(/#(.+)$/);
277+
if (match) {
278+
anchorsToLink[ match[1] ] = link;
279+
}
280+
});
281+
282+
function getViewableHeaderId() {
283+
var visibleHeaders = getHeadersInViewport();
284+
if (visibleHeaders.length == 0) return null;
285+
286+
var viewableHeader = visibleHeaders.sort(function(header) {
287+
return header.getBoundingClientRect().y;
288+
})[0];
289+
290+
return viewableHeader.id;
291+
}
292+
293+
var sectionHeaders = $(':header').filter(function(_, el) {
294+
return anchorsToLink[ el.id ];
295+
});
296+
297+
function getHeadersInViewport() {
298+
return sectionHeaders.filter(function(_, header) {
299+
var headerRect = header.getBoundingClientRect();
300+
var headerTop = headerRect.top;
301+
var headerBottom = headerRect.bottom;
302+
303+
return headerTop >= 0 && headerBottom <= window.innerHeight;
304+
});
305+
}
306+
307+
var activeLinkClass = 'active';
308+
$('#content').on('scroll', function() {
309+
var viewableHeaderId = getViewableHeaderId();
310+
if (!viewableHeaderId) return;
311+
312+
$sidebarLinks.removeClass(activeLinkClass);
313+
var activeLink = anchorsToLink[viewableHeaderId];
314+
$(activeLink).addClass(activeLinkClass);
315+
});
316+
})();

0 commit comments

Comments
 (0)