docs: sidebar link anchor invalid (#8725)

This commit is contained in:
Xc
2022-07-09 15:37:45 +08:00
committed by GitHub
parent e939850863
commit b0d654c992
2 changed files with 58 additions and 20 deletions

View File

@@ -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])
</script>
@@ -28,16 +33,26 @@ const sponsor = computed(() => sponsorLocale[lang.value])
:key="link"
class="toc-item"
>
<a class="toc-link" :href="link" :title="text">{{ text }}</a>
<a
class="toc-link"
:href="link"
:title="text"
@click="manualLink(link)"
>{{ text }}</a
>
<ul v-if="children">
<li
v-for="{ link: childLink, text: childText } in children"
:key="childLink"
class="toc-item"
>
<a class="toc-link subitem" :href="childLink" :title="text">{{
childText
}}</a>
<a
class="toc-link subitem"
:href="childLink"
:title="text"
@click="manualLink(childLink)"
>{{ childText }}</a
>
</li>
</ul>
</li>

View File

@@ -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<HTMLElement>,
marker: Ref<HTMLElement>
) {
): { 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]
}