1
1
import { Plugin } from '@nuxt/types' ;
2
2
import { Route } from 'vue-router' ;
3
3
4
- declare module 'vue/types/vue' {
5
- interface Vue {
6
- $scroll ( $route : Route ) : void ;
7
- }
8
- }
9
-
10
4
/**
11
5
* How does this work? A good question. It may be buggy.
12
6
*
@@ -26,23 +20,45 @@ declare module 'vue/types/vue' {
26
20
* in the layout for the pages. If it's broken, first confirm your page's
27
21
* layout does call this.$scroll() inside of watch on $route.
28
22
*/
29
- const scrollPlugin : Plugin = ( _ , inject ) => {
30
- let historyKeyMax = 0 ;
31
23
32
- inject ( 'scroll' , ( $route : Route ) : void => {
24
+ const scroll = {
25
+ /**
26
+ * To be called on navigation
27
+ */
28
+ onNavigation ( $route : Route ) : void {
33
29
const historyKey = + history . state . key ;
34
- if ( historyKeyMax < historyKey ) {
35
- historyKeyMax = historyKey ;
30
+ if ( this . _historyKeyMax < historyKey ) {
31
+ this . _historyKeyMax = historyKey ;
36
32
if ( ! $route . hash ) {
37
33
globalThis . scrollTo ( 0 , 0 ) ;
38
34
} else {
39
35
// Take over the browser's usual job of scrolling, because some won't
40
- const target = globalThis . document . getElementById ( $route . hash . slice ( 1 ) ) ;
41
- const boundingClientRect = target ?. getBoundingClientRect ( ) ;
42
- globalThis . scrollBy ( 0 , boundingClientRect ?. y ?? 0 ) ;
36
+ this . toHash ( $route . hash ) ;
43
37
}
44
38
}
45
- } ) ;
39
+ } ,
40
+ /**
41
+ * Moves to a given hash on a page if it exists. Can be given without or without a # sign
42
+ */
43
+ toHash ( hash : string ) : void {
44
+ if ( hash . startsWith ( '#' ) ) {
45
+ hash = hash . slice ( 1 ) ;
46
+ }
47
+ const target = globalThis . document . getElementById ( hash ) ;
48
+ const boundingClientRect = target ?. getBoundingClientRect ( ) ;
49
+ globalThis . scrollBy ( 0 , boundingClientRect ?. y ?? 0 ) ;
50
+ } ,
51
+ _historyKeyMax : 0 ,
46
52
} ;
47
53
54
+ const scrollPlugin : Plugin = ( _ , inject ) => {
55
+ inject ( 'scroll' , scroll ) ;
56
+ } ;
57
+
58
+ declare module 'vue/types/vue' {
59
+ interface Vue {
60
+ $scroll : typeof scroll ;
61
+ }
62
+ }
63
+
48
64
export default scrollPlugin ;
0 commit comments