UNPKG

2.2 kBJavaScriptView Raw
1/* global AHL_SIDEBAR_LINK_SELECTOR, AHL_HEADER_ANCHOR_SELECTOR */
2
3import debounce from 'lodash.debounce'
4
5export default {
6 mounted () {
7 window.addEventListener('scroll', this.onScroll)
8 },
9
10 methods: {
11 onScroll: debounce(function () {
12 this.setActiveHash()
13 }, 300),
14
15 setActiveHash () {
16 const sidebarLinks = [].slice.call(document.querySelectorAll(AHL_SIDEBAR_LINK_SELECTOR))
17 const anchors = [].slice.call(document.querySelectorAll(AHL_HEADER_ANCHOR_SELECTOR))
18 .filter(anchor => sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash))
19
20 const scrollTop = Math.max(
21 window.pageYOffset,
22 document.documentElement.scrollTop,
23 document.body.scrollTop
24 )
25
26 const scrollHeight = Math.max(
27 document.documentElement.scrollHeight,
28 document.body.scrollHeight
29 )
30
31 const bottomY = window.innerHeight + scrollTop
32
33 for (let i = 0; i < anchors.length; i++) {
34 const anchor = anchors[i]
35 const nextAnchor = anchors[i + 1]
36
37 const isActive = i === 0 && scrollTop === 0
38 || (scrollTop >= anchor.parentElement.offsetTop + 10
39 && (!nextAnchor || scrollTop < nextAnchor.parentElement.offsetTop - 10))
40
41 const routeHash = decodeURIComponent(this.$route.hash)
42 if (isActive && routeHash !== decodeURIComponent(anchor.hash)) {
43 const activeAnchor = anchor
44 // check if anchor is at the bottom of the page to keep $route.hash consistent
45 if (bottomY === scrollHeight) {
46 for (let j = i + 1; j < anchors.length; j++) {
47 if (routeHash === decodeURIComponent(anchors[j].hash)) {
48 return
49 }
50 }
51 }
52 this.$vuepress.$set('disableScrollBehavior', true)
53 this.$router.replace(decodeURIComponent(activeAnchor.hash), () => {
54 // execute after scrollBehavior handler.
55 this.$nextTick(() => {
56 this.$vuepress.$set('disableScrollBehavior', false)
57 })
58 })
59 return
60 }
61 }
62 }
63 },
64
65 beforeDestroy () {
66 window.removeEventListener('scroll', this.onScroll)
67 }
68}