hexo-theme-keep/source/js/toc.js

93 lines
3.1 KiB
JavaScript
Raw Normal View History

2021-01-25 10:08:52 +08:00
/* global KEEP */
function initTOC() {
2020-11-20 12:02:22 +08:00
KEEP.utils.navItems = document.querySelectorAll('.post-toc-wrap .post-toc li');
2020-04-21 10:47:36 +08:00
2020-11-20 12:02:22 +08:00
if (KEEP.utils.navItems.length > 0) {
2021-01-05 15:39:21 +08:00
2020-11-20 12:02:22 +08:00
KEEP.utils = {
2020-11-20 12:02:22 +08:00
...KEEP.utils,
findActiveIndexByTOC() {
2020-11-20 12:02:22 +08:00
if (!Array.isArray(KEEP.utils.sections)) return;
let index = KEEP.utils.sections.findIndex(element => {
return element && element.getBoundingClientRect().top - 20 > 0;
2020-04-21 10:47:36 +08:00
});
if (index === -1) {
2020-11-20 12:02:22 +08:00
index = KEEP.utils.sections.length - 1;
} else if (index > 0) {
index--;
}
2021-01-05 15:39:21 +08:00
this.activateNavByIndex(index);
},
2020-04-21 10:47:36 +08:00
registerSidebarTOC() {
2020-11-20 12:02:22 +08:00
KEEP.utils.sections = [...document.querySelectorAll('.post-toc li a.nav-link')].map(element => {
const target = document.getElementById(decodeURI(element.getAttribute('href')).replace('#', ''));
element.addEventListener('click', event => {
event.preventDefault();
const offset = target.getBoundingClientRect().top + window.scrollY;
window.anime({
targets: document.scrollingElement,
duration: 500,
easing: 'linear',
scrollTop: offset - 10,
complete: function () {
setTimeout(() => {
KEEP.utils.pageTop_dom.classList.add('hide');
}, 100)
}
});
});
return target;
});
},
2020-04-21 10:47:36 +08:00
2021-01-05 15:39:21 +08:00
activateNavByIndex(index) {
const target = document.querySelectorAll('.post-toc li a.nav-link')[index];
if (!target || target.classList.contains('active-current')) return;
2020-04-21 10:47:36 +08:00
document.querySelectorAll('.post-toc .active').forEach(element => {
element.classList.remove('active', 'active-current');
});
target.classList.add('active', 'active-current');
let parent = target.parentNode;
while (!parent.matches('.post-toc')) {
if (parent.matches('li')) parent.classList.add('active');
parent = parent.parentNode;
2020-04-21 10:47:36 +08:00
}
// Scrolling to center active TOC element if TOC content is taller then viewport.
const tocElement = document.querySelector('.post-toc-wrap');
window.anime({
targets: tocElement,
duration: 200,
easing: 'linear',
scrollTop: tocElement.scrollTop - (tocElement.offsetHeight / 2) + target.getBoundingClientRect().top - tocElement.getBoundingClientRect().top
});
},
showPageAsideWhenHasTOC() {
2021-01-25 10:08:52 +08:00
const styleStatus = KEEP.getStyleStatus();
const key = 'isOpenPageAside';
if (styleStatus && styleStatus.hasOwnProperty(key)) {
KEEP.utils.leftSideToggle.pageAsideHandleOfTOC(styleStatus[key]);
} else {
KEEP.utils.leftSideToggle.pageAsideHandleOfTOC(true);
}
}
}
2021-01-05 15:39:21 +08:00
2020-11-20 12:02:22 +08:00
KEEP.utils.showPageAsideWhenHasTOC();
KEEP.utils.registerSidebarTOC();
2021-01-05 15:39:21 +08:00
} else {
KEEP.utils.pageContainer_dom.removeChild(document.querySelector('.page-aside'));
}
}
2020-04-21 10:47:36 +08:00
2021-01-05 15:39:21 +08:00
if (KEEP.theme_config.pjax.enable === true && KEEP.utils) {
initTOC();
} else {
window.addEventListener('DOMContentLoaded', initTOC);
}