69 lines
2.1 KiB
JavaScript
69 lines
2.1 KiB
JavaScript
/* global AHL_SIDEBAR_LINK_SELECTOR, AHL_HEADER_ANCHOR_SELECTOR */
|
|
|
|
import debounce from 'lodash.debounce'
|
|
|
|
export default {
|
|
mounted () {
|
|
window.addEventListener('scroll', this.onScroll)
|
|
},
|
|
|
|
methods: {
|
|
onScroll: debounce(function () {
|
|
this.setActiveHash()
|
|
}, 300),
|
|
|
|
setActiveHash () {
|
|
const sidebarLinks = [].slice.call(document.querySelectorAll(AHL_SIDEBAR_LINK_SELECTOR))
|
|
const anchors = [].slice.call(document.querySelectorAll(AHL_HEADER_ANCHOR_SELECTOR))
|
|
.filter(anchor => sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash))
|
|
|
|
const scrollTop = Math.max(
|
|
window.pageYOffset,
|
|
document.documentElement.scrollTop,
|
|
document.body.scrollTop
|
|
)
|
|
|
|
const scrollHeight = Math.max(
|
|
document.documentElement.scrollHeight,
|
|
document.body.scrollHeight
|
|
)
|
|
|
|
const bottomY = window.innerHeight + scrollTop
|
|
|
|
for (let i = 0; i < anchors.length; i++) {
|
|
const anchor = anchors[i]
|
|
const nextAnchor = anchors[i + 1]
|
|
|
|
const isActive = i === 0 && scrollTop === 0
|
|
|| (scrollTop >= anchor.parentElement.offsetTop + 10
|
|
&& (!nextAnchor || scrollTop < nextAnchor.parentElement.offsetTop - 10))
|
|
|
|
const routeHash = decodeURIComponent(this.$route.hash)
|
|
if (isActive && routeHash !== decodeURIComponent(anchor.hash)) {
|
|
const activeAnchor = anchor
|
|
// check if anchor is at the bottom of the page to keep $route.hash consistent
|
|
if (bottomY === scrollHeight) {
|
|
for (let j = i + 1; j < anchors.length; j++) {
|
|
if (routeHash === decodeURIComponent(anchors[j].hash)) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
this.$vuepress.$set('disableScrollBehavior', true)
|
|
this.$router.replace(decodeURIComponent(activeAnchor.hash), () => {
|
|
// execute after scrollBehavior handler.
|
|
this.$nextTick(() => {
|
|
this.$vuepress.$set('disableScrollBehavior', false)
|
|
})
|
|
})
|
|
return
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
beforeDestroy () {
|
|
window.removeEventListener('scroll', this.onScroll)
|
|
}
|
|
}
|