From 43201c4c449614f28009019286b25302baf0c1c6 Mon Sep 17 00:00:00 2001 From: smchen Date: Mon, 11 Oct 2021 11:23:05 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9toc=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.vitepress/devui-theme/components/PageToc.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/.vitepress/devui-theme/components/PageToc.vue b/docs/.vitepress/devui-theme/components/PageToc.vue index 5efcd8af..eac97c55 100644 --- a/docs/.vitepress/devui-theme/components/PageToc.vue +++ b/docs/.vitepress/devui-theme/components/PageToc.vue @@ -27,7 +27,7 @@ const headers = useToc() .devui-content-nav { width: 240px; position: fixed; - top: 90px; + top: 50px; right: 0; height: 100%; z-index: 1; -- Gitee From 7e01bc453dfcf0210235ada1d7ec159db1c6f761 Mon Sep 17 00:00:00 2001 From: smchen Date: Mon, 11 Oct 2021 15:10:24 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=96=87=E6=A1=A3=E5=BF=AB?= =?UTF-8?q?=E9=80=9F=E5=AE=9A=E4=BD=8D=E5=A2=9E=E5=8A=A0=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E4=BB=A5=E5=8F=8Aactive=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devui-theme/components/Page.vue | 1 + .../devui-theme/components/PageToc.vue | 21 ++- .../devui-theme/composables/active-bar.ts | 136 ++++++++++++++++++ 3 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 docs/.vitepress/devui-theme/composables/active-bar.ts diff --git a/docs/.vitepress/devui-theme/components/Page.vue b/docs/.vitepress/devui-theme/components/Page.vue index 2aee748b..cb29a342 100644 --- a/docs/.vitepress/devui-theme/components/Page.vue +++ b/docs/.vitepress/devui-theme/components/Page.vue @@ -27,6 +27,7 @@ import PageToc from "./PageToc.vue" @media (min-width: 720px) { .page { margin-left: 16.4rem; + margin-right: 40px; } } diff --git a/docs/.vitepress/devui-theme/components/PageToc.vue b/docs/.vitepress/devui-theme/components/PageToc.vue index eac97c55..69006af3 100644 --- a/docs/.vitepress/devui-theme/components/PageToc.vue +++ b/docs/.vitepress/devui-theme/components/PageToc.vue @@ -1,22 +1,29 @@ @@ -73,14 +80,14 @@ const headers = useToc() a.current { color: $devui-link; } - - &.active { - color: $devui-link; - } } } } +.active { + color: $devui-link !important; +} + @media (max-width: 1800px) { .devui-content-nav { width: 150px; diff --git a/docs/.vitepress/devui-theme/composables/active-bar.ts b/docs/.vitepress/devui-theme/composables/active-bar.ts new file mode 100644 index 00000000..b8d10d5c --- /dev/null +++ b/docs/.vitepress/devui-theme/composables/active-bar.ts @@ -0,0 +1,136 @@ +import { onMounted, onUnmounted, onUpdated } from 'vue' + +import type { Ref } from 'vue' + +// 防抖节流控制 +export const throttleAndDebounce = (fn: () => any, delay: number) => { + let timeout: ReturnType + let called = false + return () => { + if (timeout) { + clearTimeout(timeout) + } + if (!called) { + fn() + called = true + setTimeout(() => { + called = false + }, delay) + } else { + timeout = setTimeout(fn, delay) + } + } +} + +export function useActiveSidebarLinks( + container: Ref, + marker: Ref +) { + 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 + } + for (let i = 0; i < anchors.length; i++) { + const anchor = anchors[i] + const nextAnchor = anchors[i + 1] + const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor) + if (isActive) { + history.replaceState( + null, + document.title, + hash ? (hash as string) : ' ' + ) + activateLink(hash as string) + return + } + } + } + + let prevActiveLink: HTMLAnchorElement | null = null + + function activateLink(hash: string) { + deactiveLink(prevActiveLink) + + const activeLink = (prevActiveLink = + hash == null + ? null + : (container.value.querySelector( + `.devui-item a[href="${decodeURIComponent(hash)}"]` + ) as HTMLAnchorElement)) + if (activeLink) { + activeLink.classList.add('active') + marker.value.style.opacity = '1' + marker.value.style.top = `${activeLink.offsetTop}px` + } else { + marker.value.style.opacity = '0' + marker.value.style.top = '33px' + } + } + + function deactiveLink(link: HTMLElement) { + link && link.classList.remove('active') + } + + onMounted(() => { + window.requestAnimationFrame(setActiveLink) + window.addEventListener('scroll', onScroll) + }) + + onUpdated(() => { + activateLink(location.hash) + }) + + onUnmounted(() => { + window.removeEventListener('scroll', onScroll) + }) +} +function getSidebarLinks() { + return Array.from( + document.querySelectorAll('.devui-content-nav .devui-link') + ) as HTMLAnchorElement[] +} +function getAnchors(sidebarLinks: HTMLAnchorElement[]) { + return ( + Array.from( + document.querySelectorAll('.content .header-anchor') + ) as HTMLAnchorElement[] + ).filter((anchor) => + sidebarLinks.some((sidebarLink) => sidebarLink.hash === anchor.hash) + ) +} +function getPageOffset() { + return (document.querySelector('.nav-bar') as HTMLElement).offsetHeight +} +function getAnchorTop(anchor: HTMLAnchorElement) { + const pageOffset = getPageOffset() + try { + return anchor.parentElement.offsetTop - pageOffset - 15 + } catch (e) { + return 0 + } +} +function isAnchorActive( + index: number, + anchor: HTMLAnchorElement, + nextAnchor: HTMLAnchorElement +) { + const scrollTop = window.scrollY + if (index === 0 && scrollTop === 0) { + return [true, null] + } + if (scrollTop < getAnchorTop(anchor)) { + return [false, null] + } + if (!nextAnchor || scrollTop < getAnchorTop(nextAnchor)) { + return [true, decodeURIComponent(anchor.hash)] + } + return [false, null] +} -- Gitee From 9006a014d20613a638ad70b0590f245696e84b87 Mon Sep 17 00:00:00 2001 From: smchen Date: Mon, 11 Oct 2021 15:27:49 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E6=96=87=E4=BB=B6=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.vitepress/devui-theme/components/PageToc.vue | 2 +- .../devui-theme/composables/{active-bar.ts => activeBar.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/.vitepress/devui-theme/composables/{active-bar.ts => activeBar.ts} (100%) diff --git a/docs/.vitepress/devui-theme/components/PageToc.vue b/docs/.vitepress/devui-theme/components/PageToc.vue index 69006af3..d1666e33 100644 --- a/docs/.vitepress/devui-theme/components/PageToc.vue +++ b/docs/.vitepress/devui-theme/components/PageToc.vue @@ -1,7 +1,7 @@