@@ -8,46 +8,80 @@ import * as PageTransition from "../states/page-transition";
88const unfocusPx = 3 ;
99let state = false ;
1010
11- export function set ( foc : boolean , withCursor = false ) : void {
12- if ( foc && ! state ) {
11+ let cacheReady = false ;
12+ let cache : {
13+ focus ?: HTMLElement [ ] ;
14+ cursor ?: HTMLElement [ ] ;
15+ } = { } ;
16+
17+ function initializeCache ( ) : void {
18+ if ( cacheReady ) return ;
19+
20+ const cursorSelector = "body, button, a" ;
21+ const elementsSelector = [
22+ "app" ,
23+ "header" ,
24+ "footer" ,
25+ "main" ,
26+ "#bannerCenter" ,
27+ "#notificationCenter" ,
28+ "#capsWarning" ,
29+ "#ad-vertical-right-wrapper" ,
30+ "#ad-vertical-left-wrapper" ,
31+ "#ad-footer-wrapper" ,
32+ "#ad-footer-small-wrapper" ,
33+ ] . join ( "," ) ;
34+
35+ cache . cursor = [ ...document . querySelectorAll < HTMLElement > ( cursorSelector ) ] ;
36+ cache . focus = [ ...document . querySelectorAll < HTMLElement > ( elementsSelector ) ] ;
37+
38+ cacheReady = true ;
39+ }
40+
41+ // with cursor is a special case that is only used on the initial page load
42+ // to avoid the cursor being invisible and confusing the user
43+ export function set ( value : boolean , withCursor = false ) : void {
44+ initializeCache ( ) ;
45+
46+ if ( value && ! state ) {
1347 state = true ;
48+
49+ // batch DOM operations for better performance
50+ requestAnimationFrame ( ( ) => {
51+ if ( cache . focus ) {
52+ for ( const el of cache . focus ) {
53+ el . classList . add ( "focus" ) ;
54+ }
55+ }
56+ if ( ! withCursor && cache . cursor ) {
57+ for ( const el of cache . cursor ) {
58+ el . style . cursor = "none" ;
59+ }
60+ }
61+ } ) ;
62+
1463 Caret . stopAnimation ( ) ;
15- $ ( "header" ) . addClass ( "focus" ) ;
16- $ ( "footer" ) . addClass ( "focus" ) ;
17- if ( ! withCursor ) {
18- $ ( "body" ) . css ( "cursor" , "none" ) ;
19- $ ( "button" ) . css ( "cursor" , "none" ) ;
20- $ ( "a" ) . css ( "cursor" , "none" ) ;
21- }
22- $ ( "main" ) . addClass ( "focus" ) ;
23- $ ( "#bannerCenter" ) . addClass ( "focus" ) ;
24- $ ( "#notificationCenter" ) . addClass ( "focus" ) ;
25- $ ( "#capsWarning" ) . addClass ( "focus" ) ;
26- $ ( "#ad-vertical-right-wrapper" ) . addClass ( "focus" ) ;
27- $ ( "#ad-vertical-left-wrapper" ) . addClass ( "focus" ) ;
28- $ ( "#ad-footer-wrapper" ) . addClass ( "focus" ) ;
29- $ ( "#ad-footer-small-wrapper" ) . addClass ( "focus" ) ;
3064 LiveSpeed . show ( ) ;
3165 LiveBurst . show ( ) ;
3266 LiveAcc . show ( ) ;
3367 TimerProgress . show ( ) ;
34- } else if ( ! foc && state ) {
68+ } else if ( ! value && state ) {
3569 state = false ;
70+
71+ requestAnimationFrame ( ( ) => {
72+ if ( cache . focus ) {
73+ for ( const el of cache . focus ) {
74+ el . classList . remove ( "focus" ) ;
75+ }
76+ }
77+ if ( cache . cursor ) {
78+ for ( const el of cache . cursor ) {
79+ el . style . cursor = "" ;
80+ }
81+ }
82+ } ) ;
83+
3684 Caret . startAnimation ( ) ;
37- $ ( "header" ) . removeClass ( "focus" ) ;
38- $ ( "footer" ) . removeClass ( "focus" ) ;
39- $ ( "body" ) . css ( "cursor" , "" ) ;
40- $ ( "button" ) . css ( "cursor" , "" ) ;
41- $ ( "a" ) . css ( "cursor" , "" ) ;
42- $ ( "main" ) . removeClass ( "focus" ) ;
43- $ ( "#bannerCenter" ) . removeClass ( "focus" ) ;
44- $ ( "#notificationCenter" ) . removeClass ( "focus" ) ;
45- $ ( "#capsWarning" ) . removeClass ( "focus" ) ;
46- $ ( "#app" ) . removeClass ( "focus" ) ;
47- $ ( "#ad-vertical-right-wrapper" ) . removeClass ( "focus" ) ;
48- $ ( "#ad-vertical-left-wrapper" ) . removeClass ( "focus" ) ;
49- $ ( "#ad-footer-wrapper" ) . removeClass ( "focus" ) ;
50- $ ( "#ad-footer-small-wrapper" ) . removeClass ( "focus" ) ;
5185 LiveSpeed . hide ( ) ;
5286 LiveBurst . hide ( ) ;
5387 LiveAcc . hide ( ) ;
0 commit comments