@@ -14,29 +14,39 @@ import config from '../config.js';
14
14
export function Events ( Base ) {
15
15
return class Events extends Base {
16
16
$resetEvents ( source ) {
17
- const { auto2top } = this . config ;
17
+ const { auto2top, loadNavbar } = this . config ;
18
+ const { path, query } = this . route ;
18
19
19
- // If 'history', rely on the browser's scroll auto-restoration when going back or forward
20
+ // Note: Scroll position set by browser on forward/ back (i.e. "history")
20
21
if ( source !== 'history' ) {
21
22
// Scroll to ID if specified
22
- if ( this . route . query . id ) {
23
- this . #scrollIntoView( this . route . path , this . route . query . id ) ;
23
+ if ( query . id ) {
24
+ this . #scrollIntoView( path , query . id , true ) ;
24
25
}
25
26
// Scroll to top if a link was clicked and auto2top is enabled
26
- if ( source === 'navigate' ) {
27
+ else if ( source === 'navigate' ) {
27
28
auto2top && this . #scroll2Top( auto2top ) ;
28
29
}
29
30
}
30
31
31
- if ( this . config . loadNavbar ) {
32
+ // Move focus to content
33
+ if ( query . id || source === 'navigate' ) {
34
+ this . focusContent ( ) ;
35
+ }
36
+
37
+ if ( loadNavbar ) {
32
38
this . __getAndActive ( this . router , 'nav' ) ;
33
39
}
34
40
}
35
41
36
42
initEvent ( ) {
43
+ // Bind skip link
44
+ this . #skipLink( '#skip-to-content' ) ;
45
+
37
46
// Bind toggle button
38
47
this . #btn( 'button.sidebar-toggle' , this . router ) ;
39
48
this . #collapse( '.sidebar' , this . router ) ;
49
+
40
50
// Bind sticky effect
41
51
if ( this . config . coverpage ) {
42
52
! isMobile && on ( 'scroll' , this . __sticky ) ;
@@ -53,6 +63,22 @@ export function Events(Base) {
53
63
#enableScrollEvent = true ;
54
64
#coverHeight = 0 ;
55
65
66
+ #skipLink( el ) {
67
+ el = dom . getNode ( el ) ;
68
+
69
+ if ( el === null || el === undefined ) {
70
+ return ;
71
+ }
72
+
73
+ dom . on ( el , 'click' , evt => {
74
+ const target = dom . getNode ( '#main' ) ;
75
+
76
+ evt . preventDefault ( ) ;
77
+ target && target . focus ( ) ;
78
+ this . #scrollTo( target ) ;
79
+ } ) ;
80
+ }
81
+
56
82
#scrollTo( el , offset = 0 ) {
57
83
if ( this . #scroller) {
58
84
this . #scroller. stop ( ) ;
@@ -75,6 +101,20 @@ export function Events(Base) {
75
101
. begin ( ) ;
76
102
}
77
103
104
+ focusContent ( ) {
105
+ const { query } = this . route ;
106
+ const focusEl = query . id
107
+ ? // Heading ID
108
+ dom . find ( `#${ query . id } ` )
109
+ : // First heading
110
+ dom . find ( '#main :where(h1, h2, h3, h4, h5, h6)' ) ||
111
+ // Content container
112
+ dom . find ( '#main' ) ;
113
+
114
+ // Move focus to content area
115
+ focusEl && focusEl . focus ( ) ;
116
+ }
117
+
78
118
#highlight( path ) {
79
119
if ( ! this . #enableScrollEvent) {
80
120
return ;
0 commit comments