From 9ef85fe858170e3533f379379e4520b94ec473f8 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sat, 12 Oct 2024 15:04:18 +0800 Subject: [PATCH] fix(theme): incorrect anchor link scrolling, close #266 (#268) --- theme/src/client/composables/outline.ts | 12 ++++++++---- theme/src/client/utils/shared.ts | 21 --------------------- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/theme/src/client/composables/outline.ts b/theme/src/client/composables/outline.ts index 4774efb7..e1c7af49 100644 --- a/theme/src/client/composables/outline.ts +++ b/theme/src/client/composables/outline.ts @@ -2,9 +2,9 @@ import type { InjectionKey, Ref } from 'vue' import type { Router } from 'vuepress/client' import type { ThemeOutline } from '../../shared/index.js' import { onContentUpdated } from '@vuepress-plume/plugin-content-update/client' +import { useThrottleFn, watchDebounced } from '@vueuse/core' import { inject, onMounted, onUnmounted, onUpdated, provide, ref } from 'vue' import { useRouter } from 'vuepress/client' -import { throttleAndDebounce } from '../utils/index.js' import { useAside } from './aside.js' import { useData } from './data.js' @@ -164,6 +164,7 @@ export function resolveHeaders(headers: MenuItem[], range?: ThemeOutline): MenuI export function useActiveAnchor(container: Ref, marker: Ref): void { const { isAsideEnabled } = useAside() const router = useRouter() + const routeHash = ref(router.currentRoute.value.hash) let prevActiveLink: HTMLAnchorElement | null = null @@ -215,6 +216,7 @@ export function useActiveAnchor(container: Ref, marker: Ref< } function activateLink(hash: string | null): void { + routeHash.value = hash || '' if (prevActiveLink) prevActiveLink.classList.remove('active') @@ -242,11 +244,13 @@ export function useActiveAnchor(container: Ref, marker: Ref< marker.value.style.opacity = '0' } } - - updateHash(router, hash || '') } - const onScroll = throttleAndDebounce(setActiveLink, 100) + const onScroll = useThrottleFn(setActiveLink, 100) + + watchDebounced(routeHash, () => { + updateHash(router, routeHash.value) + }, { debounce: 500 }) onMounted(() => { requestAnimationFrame(setActiveLink) diff --git a/theme/src/client/utils/shared.ts b/theme/src/client/utils/shared.ts index 08962a3b..60f43a9e 100644 --- a/theme/src/client/utils/shared.ts +++ b/theme/src/client/utils/shared.ts @@ -36,24 +36,3 @@ export function isActive( export function normalize(path: string): string { return decodeURI(path).replace(HASH_RE, '').replace(EXT_RE, '') } - -export function throttleAndDebounce(fn: () => void, delay: number): () => void { - let timeoutId: NodeJS.Timeout - let called = false - - return () => { - if (timeoutId) - clearTimeout(timeoutId) - - if (!called) { - fn() - called = true - setTimeout(() => { - called = false - }, delay) - } - else { - timeoutId = setTimeout(fn, delay) - } - } -}