aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vuepress/lib/app/root-mixins/activeHeaderLinks.js
blob: 6cad69d5ccef2b835a8deb70bb1ea62195f7bf4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import store from '@app/store'
import throttle from 'lodash.throttle'

export default {
  mounted () {
    window.addEventListener('scroll', this.onScroll)
  },
  methods: {
    onScroll: throttle(function () {
      this.setActiveHash()
    }, 300),
    setActiveHash () {
      const sidebarLinks = [].slice.call(document.querySelectorAll('.sidebar-link'))
      const anchors = [].slice.call(document.querySelectorAll('.header-anchor'))
      .filter(anchor => sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash))

      const scrollTop = Math.max(
        window.pageYOffset,
        document.documentElement.scrollTop,
        document.body.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))

        if (isActive && decodeURIComponent(this.$route.hash) !== decodeURIComponent(anchor.hash)) {
          store.disableScrollBehavior = true
          this.$router.replace(decodeURIComponent(anchor.hash), () => {
            // execute after scrollBehavior handler.
            this.$nextTick(() => {
              store.disableScrollBehavior = false
            })
          })
          return
        }
      }
    }
  },
  beforeDestroy () {
    window.removeEventListener('scroll', this.onScroll)
  }
}