@@ -127,28 +127,31 @@ function useHistoryListeners(
127127 }
128128
129129 function beforeUnloadListener ( ) {
130- const { history } = window
131- if ( ! history . state ) return
132- history . replaceState (
133- assign ( { } , history . state , { scroll : computeScrollPosition ( ) } ) ,
134- ''
135- )
130+ if ( document . visibilityState === 'hidden' ) {
131+ const { history } = window
132+ if ( ! history . state ) return
133+ history . replaceState (
134+ assign ( { } , history . state , { scroll : computeScrollPosition ( ) } ) ,
135+ ''
136+ )
137+ }
136138 }
137139
138140 function destroy ( ) {
139141 for ( const teardown of teardowns ) teardown ( )
140142 teardowns = [ ]
141143 window . removeEventListener ( 'popstate' , popStateHandler )
142- window . removeEventListener ( 'beforeunload' , beforeUnloadListener )
144+ window . removeEventListener ( 'pagehide' , beforeUnloadListener )
145+ document . removeEventListener ( 'visibilitychange' , beforeUnloadListener )
143146 }
144147
145148 // set up the listeners and prepare teardown callbacks
146149 window . addEventListener ( 'popstate' , popStateHandler )
147- // TODO: could we use 'pagehide' or 'visibilitychange' instead?
148150 // https://developer.chrome.com/blog/page-lifecycle-api/
149- window . addEventListener ( 'beforeunload' , beforeUnloadListener , {
150- passive : true ,
151- } )
151+ // note: iOS safari does not fire beforeunload, so we
152+ // use pagehide and visibilitychange instead
153+ window . addEventListener ( 'pagehide' , beforeUnloadListener )
154+ document . addEventListener ( 'visibilitychange' , beforeUnloadListener )
152155
153156 return {
154157 pauseListeners,
0 commit comments