From 3b82be760c5ceebae988369d934f30a37a7347be Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Wed, 8 Apr 2020 03:54:55 -0600 Subject: [PATCH] activate entries in sidebar TOC for all visible headings when scroll reaches bottom of page --- preview-src/index.adoc | 2 ++ src/js/02-on-this-page.js | 56 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/preview-src/index.adoc b/preview-src/index.adoc index 4550f47..6326d05 100644 --- a/preview-src/index.adoc +++ b/preview-src/index.adoc @@ -231,4 +231,6 @@ Mauris eget leo nunc, nec tempus mi? Curabitur id nisl mi, ut vulputate urna. Quisque porta facilisis tortor, vitae bibendum velit fringilla vitae! ____ +== Fin + That's all, folks! diff --git a/src/js/02-on-this-page.js b/src/js/02-on-this-page.js index 524ef25..0ede389 100644 --- a/src/js/02-on-this-page.js +++ b/src/js/02-on-this-page.js @@ -51,29 +51,53 @@ }) function onScroll () { - var activeFragment var scrolledBy = window.pageYOffset var buffer = getStyleValueAsInt(document.documentElement, 'fontSize') + var targetPosition = article.offsetTop if (scrolledBy && window.innerHeight + scrolledBy + 2 >= document.documentElement.scrollHeight) { - activeFragment = '#' + headings[headings.length - 1].id - } else { - var targetPosition = article.offsetTop - headings.some(function (heading) { - var headingTop = heading.getBoundingClientRect().top + getStyleValueAsInt(heading, 'paddingTop') - if (targetPosition < headingTop - buffer) return true - activeFragment = '#' + heading.id + if (lastActiveFragment) { + if (!Array.isArray(lastActiveFragment)) lastActiveFragment = [lastActiveFragment] + } else { + lastActiveFragment = [] + } + var activeFragments = [] + var lastIdx = headings.length - 1 + headings.forEach(function (heading, idx) { + var fragment = '#' + heading.id + if (idx === lastIdx || + heading.getBoundingClientRect().top + getStyleValueAsInt(heading, 'paddingTop') >= targetPosition) { + activeFragments.push(fragment) + if (lastActiveFragment.indexOf(fragment) < 0) links[fragment].classList.add('is-active') + } else if (~lastActiveFragment.indexOf(fragment)) { + links[lastActiveFragment.shift()].classList.remove('is-active') + } }) + list.scrollTop = list.scrollHeight - list.offsetHeight + lastActiveFragment = activeFragments.length > 1 ? activeFragments : activeFragments[0] + return } + if (Array.isArray(lastActiveFragment)) { + lastActiveFragment.forEach(function (fragment) { + links[fragment].classList.remove('is-active') + }) + lastActiveFragment = undefined + } + var activeFragment + headings.some(function (heading) { + if (targetPosition < heading.getBoundingClientRect().top + getStyleValueAsInt(heading, 'paddingTop') - buffer) { + return true + } + activeFragment = '#' + heading.id + }) if (activeFragment) { - if (activeFragment !== lastActiveFragment) { - if (lastActiveFragment) links[lastActiveFragment].classList.remove('is-active') - var activeLink = links[activeFragment] - activeLink.classList.add('is-active') - if (list.scrollHeight > list.offsetHeight) { - list.scrollTop = Math.max(0, activeLink.offsetTop + activeLink.offsetHeight - list.offsetHeight) - } - lastActiveFragment = activeFragment + if (activeFragment === lastActiveFragment) return + if (lastActiveFragment) links[lastActiveFragment].classList.remove('is-active') + var activeLink = links[activeFragment] + activeLink.classList.add('is-active') + if (list.scrollHeight > list.offsetHeight) { + list.scrollTop = Math.max(0, activeLink.offsetTop + activeLink.offsetHeight - list.offsetHeight) } + lastActiveFragment = activeFragment } else if (lastActiveFragment) { links[lastActiveFragment].classList.remove('is-active') lastActiveFragment = undefined -- 2.11.0