From 3adc965dd09490b7efa1cce9f09b0a3b30970277 Mon Sep 17 00:00:00 2001 From: 简律纯 Date: Wed, 19 Apr 2023 17:30:39 +0800 Subject: ✨优化文档 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/composables/useScrollspy.ts | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 docs/composables/useScrollspy.ts (limited to 'docs/composables/useScrollspy.ts') diff --git a/docs/composables/useScrollspy.ts b/docs/composables/useScrollspy.ts new file mode 100644 index 0000000..5962d0d --- /dev/null +++ b/docs/composables/useScrollspy.ts @@ -0,0 +1,39 @@ +import type { Ref } from 'vue' + +/** + * Scrollspy allows you to watch visible headings in a specific page. + * Useful for table of contents live style updates. + */ +export const useScrollspy = () => { + const observer = ref() as Ref + const visibleHeadings = ref([]) as Ref + const activeHeadings = ref([]) as Ref + + const observerCallback = (entries: IntersectionObserverEntry[]) => + entries.forEach((entry) => { + const id = entry.target.id + + if (entry.isIntersecting) { visibleHeadings.value.push(id) } else { visibleHeadings.value = visibleHeadings.value.filter(t => t !== id) } + }) + + const updateHeadings = (headings: Element[]) => + headings.forEach((heading) => { + observer.value.observe(heading) + }) + + watch(visibleHeadings, (val, oldVal) => { + if (val.length === 0) { activeHeadings.value = oldVal } else { activeHeadings.value = val } + }, { deep: true }) + + // Create intersection observer + onBeforeMount(() => (observer.value = new IntersectionObserver(observerCallback))) + + // Destroy it + onBeforeUnmount(() => observer.value?.disconnect()) + + return { + visibleHeadings, + activeHeadings, + updateHeadings + } +} -- cgit v1.2.3-70-g09d2