|
6 | 6 | un-top="[var(--header-size)]" |
7 | 7 | un-left="[calc(var(--action-bar-size)+var(--sidebar-size))]" |
8 | 8 | > |
9 | | - <!--draggable line--> |
10 | | - <div class="absolute z-2 left-0 top-0 h-full w-.25 bg-transparent cursor-col-resize"/> |
11 | 9 | <!--content area--> |
12 | 10 | <div class="relative w-full h-full"> |
13 | 11 | <OverlayScrollbarsComponent |
|
17 | 15 | defer |
18 | 16 | > |
19 | 17 | <article |
20 | | - ref="content" |
21 | | - class="px-10 py-6 VPDoc text-3.5" |
| 18 | + ref="article" |
| 19 | + class="px-10 py-6 VPDoc text-4" |
22 | 20 | :class="[ 'w-full' ]" |
23 | 21 | style="white-space: wrap;" |
24 | 22 | > |
25 | | - <Content/> |
| 23 | + <Content ref="content"/> |
26 | 24 | </article> |
27 | 25 | </OverlayScrollbarsComponent> |
28 | 26 | </div> |
|
33 | 31 | import 'overlayscrollbars/styles/overlayscrollbars.css'; |
34 | 32 | import scrollbarOptions from '../../config/scrollbarOptions'; |
35 | 33 | import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue'; |
36 | | - import { onMounted, ref, watch } from 'vue'; |
37 | | - import { useRoute } from 'vitepress'; |
| 34 | + import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'; |
| 35 | + import { onContentUpdated, useRoute } from 'vitepress'; |
38 | 36 | import emitter from '../../emitter'; |
39 | 37 |
|
40 | 38 | const scrollbars = ref<any | null>(null); |
41 | | - const content = ref<HTMLElement | null>(null); |
| 39 | + const article = ref<HTMLElement | null>(null); |
42 | 40 |
|
43 | 41 | const route = useRoute(); |
44 | 42 |
|
45 | 43 | // Listen for routing changes and scroll to the top |
46 | 44 | watch(() => route.path, () => { |
47 | | - scrollbars.value?.osInstance()?.elements()?.viewport?.scrollTo({ top: 0 }); |
| 45 | + nextTick(() => { |
| 46 | + scrollbars.value?.osInstance()?.elements()?.viewport?.scrollTo({ top: 0 }); |
| 47 | + }); |
| 48 | + }, { |
| 49 | + immediate: true |
48 | 50 | }); |
49 | 51 |
|
| 52 | + function hashChange() { |
| 53 | + if (location.hash) { |
| 54 | + const _hashText = decodeURIComponent(location.hash.replace('#', '')); |
| 55 | + console.log('scroll-to-hash', _hashText); |
| 56 | + emitter.emit('scroll-to-hash', _hashText); |
| 57 | + } |
| 58 | + } |
| 59 | +
|
| 60 | + onContentUpdated(() => { |
| 61 | + setTimeout(() => { |
| 62 | + hashChange(); |
| 63 | + }, 240); |
| 64 | + }) |
| 65 | +
|
50 | 66 | onMounted(() => { |
| 67 | + setTimeout(() => { |
| 68 | + hashChange(); |
| 69 | + }, 240); |
| 70 | + // Listen for scroll-to-hash events |
51 | 71 | emitter.on('scroll-to-hash', (hash: string) => { |
| 72 | + if (hash === '' || hash === null || hash === undefined) { |
| 73 | + return; |
| 74 | + } |
52 | 75 | const target = document.getElementById(hash); |
53 | 76 | if (!target) { |
54 | 77 | return; |
55 | 78 | } |
56 | | - // Gets the distance of the target element relative to the top of the content viewport |
| 79 | + // Gets the distance of the target element relative to the top of the article viewport |
57 | 80 | const targetTop = |
58 | 81 | target.getBoundingClientRect().top - |
59 | | - content.value!.getBoundingClientRect().top - |
| 82 | + article.value!.getBoundingClientRect().top - |
60 | 83 | Number.parseInt( |
61 | 84 | getComputedStyle(document.documentElement) |
62 | 85 | .fontSize.replace('px', '') |
|
65 | 88 | scrollbars.value?.osInstance()?.elements()?.viewport?.scrollTo({ top: targetTop, behavior: 'smooth' }); |
66 | 89 | }); |
67 | 90 | }); |
| 91 | +
|
| 92 | + onUnmounted(() => { |
| 93 | + emitter.off('scroll-to-hash'); |
| 94 | + }); |
68 | 95 | </script> |
69 | 96 |
|
70 | 97 | <style scoped lang="scss"> |
|
0 commit comments