2021-01-25 10:08:52 +08:00
|
|
|
/* global KEEP */
|
2022-09-30 11:40:30 +08:00
|
|
|
|
2020-12-30 18:11:46 +08:00
|
|
|
function initTOC() {
|
2022-10-11 12:42:11 +08:00
|
|
|
const postPageContainerDom = document.querySelector('.post-page-container')
|
|
|
|
const tocContentContainer = document.querySelector('.toc-content-container')
|
2020-04-21 10:47:36 +08:00
|
|
|
|
2022-10-11 16:27:04 +08:00
|
|
|
if (KEEP.utils.hasToc) {
|
2020-11-20 12:02:22 +08:00
|
|
|
KEEP.utils = {
|
|
|
|
...KEEP.utils,
|
2020-10-21 19:36:38 +08:00
|
|
|
|
|
|
|
findActiveIndexByTOC() {
|
2022-09-30 11:40:30 +08:00
|
|
|
if (!Array.isArray(KEEP.utils.sections)) return
|
|
|
|
let index = KEEP.utils.sections.findIndex((element) => {
|
|
|
|
return element && element.getBoundingClientRect().top - 20 > 0
|
|
|
|
})
|
2020-10-21 19:36:38 +08:00
|
|
|
if (index === -1) {
|
2022-09-30 11:40:30 +08:00
|
|
|
index = KEEP.utils.sections.length - 1
|
2020-10-21 19:36:38 +08:00
|
|
|
} else if (index > 0) {
|
2022-09-30 11:40:30 +08:00
|
|
|
index--
|
2020-10-21 19:36:38 +08:00
|
|
|
}
|
2022-09-30 11:40:30 +08:00
|
|
|
this.activateNavByIndex(index)
|
2020-10-21 19:36:38 +08:00
|
|
|
},
|
2020-04-21 10:47:36 +08:00
|
|
|
|
2020-10-21 19:36:38 +08:00
|
|
|
registerSidebarTOC() {
|
2022-09-30 11:40:30 +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()
|
2022-10-12 10:23:58 +08:00
|
|
|
let winScrollY = window.scrollY
|
|
|
|
winScrollY = winScrollY === 0 ? -20 : winScrollY
|
|
|
|
const offset = target.getBoundingClientRect().top + winScrollY
|
2022-09-30 11:40:30 +08:00
|
|
|
window.anime({
|
|
|
|
targets: document.scrollingElement,
|
|
|
|
duration: 500,
|
|
|
|
easing: 'linear',
|
|
|
|
scrollTop: offset - 10,
|
2022-10-12 10:23:58 +08:00
|
|
|
complete: () => {
|
|
|
|
history.pushState(null, document.title, element.href)
|
2022-09-30 11:40:30 +08:00
|
|
|
setTimeout(() => {
|
|
|
|
KEEP.utils.pageTop_dom.classList.add('hide')
|
2022-10-12 10:23:58 +08:00
|
|
|
}, 150)
|
2022-09-30 11:40:30 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
return target
|
|
|
|
}
|
|
|
|
)
|
2020-10-21 19:36:38 +08:00
|
|
|
},
|
2020-04-21 10:47:36 +08:00
|
|
|
|
2021-01-05 15:39:21 +08:00
|
|
|
activateNavByIndex(index) {
|
2022-09-30 11:40:30 +08:00
|
|
|
const target = document.querySelectorAll('.post-toc li a.nav-link')[index]
|
|
|
|
if (!target || target.classList.contains('active-current')) return
|
|
|
|
|
|
|
|
document.querySelectorAll('.post-toc .active').forEach((element) => {
|
|
|
|
element.classList.remove('active', 'active-current')
|
|
|
|
})
|
|
|
|
target.classList.add('active', 'active-current')
|
|
|
|
let parent = target.parentNode
|
2020-10-21 19:36:38 +08:00
|
|
|
while (!parent.matches('.post-toc')) {
|
2022-09-30 11:40:30 +08:00
|
|
|
if (parent.matches('li')) parent.classList.add('active')
|
|
|
|
parent = parent.parentNode
|
2020-04-21 10:47:36 +08:00
|
|
|
}
|
2022-10-12 10:23:58 +08:00
|
|
|
// Scrolling to center active TOC element if TOC content is taller than viewport.
|
2022-09-30 11:40:30 +08:00
|
|
|
const tocElement = document.querySelector('.post-toc-wrap')
|
2020-10-21 19:36:38 +08:00
|
|
|
window.anime({
|
|
|
|
targets: tocElement,
|
|
|
|
duration: 200,
|
|
|
|
easing: 'linear',
|
2022-09-30 11:40:30 +08:00
|
|
|
scrollTop:
|
|
|
|
tocElement.scrollTop -
|
|
|
|
tocElement.offsetHeight / 2 +
|
|
|
|
target.getBoundingClientRect().top -
|
|
|
|
tocElement.getBoundingClientRect().top
|
|
|
|
})
|
2020-10-21 19:36:38 +08:00
|
|
|
},
|
|
|
|
|
2022-10-11 12:37:06 +08:00
|
|
|
handleShowWhenHasToc() {
|
2021-01-27 12:03:49 +08:00
|
|
|
const openHandle = () => {
|
2022-09-30 11:40:30 +08:00
|
|
|
const styleStatus = KEEP.getStyleStatus()
|
2022-10-11 12:37:06 +08:00
|
|
|
const key = 'isShowToc'
|
2021-01-27 12:03:49 +08:00
|
|
|
if (styleStatus && styleStatus.hasOwnProperty(key)) {
|
2022-10-12 15:55:47 +08:00
|
|
|
KEEP.utils.postHelper.hasToc(styleStatus[key])
|
2021-01-27 12:03:49 +08:00
|
|
|
} else {
|
2022-10-12 15:55:47 +08:00
|
|
|
KEEP.utils.postHelper.hasToc(true)
|
2021-01-27 12:03:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-30 11:40:30 +08:00
|
|
|
const initOpenKey = 'init_open'
|
2021-01-27 12:03:49 +08:00
|
|
|
|
|
|
|
if (KEEP.theme_config.toc.hasOwnProperty(initOpenKey)) {
|
2022-10-12 15:55:47 +08:00
|
|
|
KEEP.theme_config.toc[initOpenKey] ? openHandle() : KEEP.utils.postHelper.hasToc(false)
|
2021-01-25 10:08:52 +08:00
|
|
|
} else {
|
2022-09-30 11:40:30 +08:00
|
|
|
openHandle()
|
2021-01-25 10:08:52 +08:00
|
|
|
}
|
2020-10-19 23:02:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-01-05 15:39:21 +08:00
|
|
|
|
2022-10-11 12:37:06 +08:00
|
|
|
KEEP.utils.handleShowWhenHasToc()
|
2022-09-30 11:40:30 +08:00
|
|
|
KEEP.utils.registerSidebarTOC()
|
2020-10-19 23:02:39 +08:00
|
|
|
} else {
|
2022-10-11 12:42:11 +08:00
|
|
|
if (tocContentContainer && postPageContainerDom) {
|
|
|
|
postPageContainerDom.removeChild(tocContentContainer)
|
|
|
|
}
|
2020-10-19 23:02:39 +08:00
|
|
|
}
|
2020-12-30 18:11:46 +08:00
|
|
|
}
|
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) {
|
2022-09-30 11:40:30 +08:00
|
|
|
initTOC()
|
2020-12-30 18:11:46 +08:00
|
|
|
} else {
|
2022-09-30 11:40:30 +08:00
|
|
|
window.addEventListener('DOMContentLoaded', initTOC)
|
2020-12-30 18:11:46 +08:00
|
|
|
}
|