From b0d654c992ecbb19cd2aa496336a89484cb5abc9 Mon Sep 17 00:00:00 2001
From: Xc <124118265@qq.com>
Date: Sat, 9 Jul 2022 15:37:45 +0800
Subject: [PATCH] docs: sidebar link anchor invalid (#8725)
---
.../doc-content/vp-table-of-content.vue | 25 +++++++--
.../vitepress/composables/active-bar.ts | 53 +++++++++++++------
2 files changed, 58 insertions(+), 20 deletions(-)
diff --git a/docs/.vitepress/vitepress/components/doc-content/vp-table-of-content.vue b/docs/.vitepress/vitepress/components/doc-content/vp-table-of-content.vue
index 451642df5e..75f59a87aa 100644
--- a/docs/.vitepress/vitepress/components/doc-content/vp-table-of-content.vue
+++ b/docs/.vitepress/vitepress/components/doc-content/vp-table-of-content.vue
@@ -13,7 +13,12 @@ import SponsorRightLogoSmallList from '../sponsors/right-logo-small-list.vue'
const headers = useToc()
const marker = ref()
const container = ref()
-useActiveSidebarLinks(container, marker)
+const useActiveSidebarLinksResult = useActiveSidebarLinks(container, marker)
+
+const manualLink = (hash: string) => {
+ useActiveSidebarLinksResult && useActiveSidebarLinksResult.manualLink(hash)
+}
+
const lang = useLang()
const sponsor = computed(() => sponsorLocale[lang.value])
@@ -28,16 +33,26 @@ const sponsor = computed(() => sponsorLocale[lang.value])
:key="link"
class="toc-item"
>
- {{ text }}
+ {{ text }}
diff --git a/docs/.vitepress/vitepress/composables/active-bar.ts b/docs/.vitepress/vitepress/composables/active-bar.ts
index 4e7c7b094b..804d860c47 100644
--- a/docs/.vitepress/vitepress/composables/active-bar.ts
+++ b/docs/.vitepress/vitepress/composables/active-bar.ts
@@ -1,27 +1,32 @@
-import { onMounted, onUnmounted, onUpdated } from 'vue'
+import { nextTick, onMounted, onUpdated } from 'vue'
import { isClient } from '@vueuse/core'
import { throttleAndDebounce } from '../utils'
import type { Ref } from 'vue'
+type ManualLinkFn = (hash: string) => void
+
export function useActiveSidebarLinks(
container: Ref,
marker: Ref
-) {
+): { manualLink: ManualLinkFn } | undefined {
if (!isClient) return
+ let scrollDom: HTMLElement
+
const onScroll = throttleAndDebounce(setActiveLink, 150)
function setActiveLink() {
const sidebarLinks = getSidebarLinks()
const anchors = getAnchors(sidebarLinks)
-
- if (
- anchors.length &&
- window.scrollY + window.innerHeight === document.body.offsetHeight
- ) {
- activateLink(anchors[anchors.length - 1].hash)
- return
- }
+ // Cancel the processing of the anchor point being forced to be the last one in the storefront
+ // if (
+ // anchors.length &&
+ // scrollDom &&
+ // scrollDom.scrollTop + scrollDom.clientHeight === scrollDom.scrollHeight
+ // ) {
+ // activateLink(anchors[anchors.length - 1].hash)
+ // return
+ // }
for (let i = 0; i < anchors.length; i++) {
const anchor = anchors[i]
const nextAnchor = anchors[i + 1]
@@ -49,6 +54,7 @@ export function useActiveSidebarLinks(
: (container.value.querySelector(
`.toc-item a[href="${decodeURIComponent(hash)}"]`
) as HTMLAnchorElement))
+
if (activeLink) {
activeLink.classList.add('active')
marker.value.style.opacity = '1'
@@ -65,16 +71,31 @@ export function useActiveSidebarLinks(
onMounted(() => {
window.requestAnimationFrame(setActiveLink)
- window.addEventListener('scroll', onScroll)
+ scrollDom = document.querySelector('.App .el-scrollbar__wrap')!
+ scrollDom.onscroll = onScroll
+ location.hash &&
+ nextTick(() => {
+ manualLink(location.hash)
+ })
})
onUpdated(() => {
activateLink(location.hash)
})
- onUnmounted(() => {
- window.removeEventListener('scroll', onScroll)
- })
+ function manualLink(hash: string) {
+ const anchor: HTMLElement | null = document.querySelector(hash)
+ if (!anchor) {
+ return
+ }
+ const top = anchor.offsetTop + anchor.offsetHeight
+ scrollDom?.scrollTo(0, top)
+ activateLink(location.hash)
+ }
+
+ return {
+ manualLink,
+ }
}
function getSidebarLinks() {
return Array.from(
@@ -106,7 +127,9 @@ function isAnchorActive(
anchor: HTMLAnchorElement,
nextAnchor: HTMLAnchorElement
) {
- const scrollTop = window.scrollY
+ const scrollTop = document.querySelector(
+ '.App .el-scrollbar__wrap'
+ )!.scrollTop
if (index === 0 && scrollTop === 0) {
return [true, null]
}