「ページ A」から「ページ B」へ遷移した後に「ページ B」で hidtory.back()
が実行され「ページ A」に戻ってきたとき、「ページ A」で走っていたスクリプトの挙動について考えよう。
ちなみにブラウザの「戻る」ボタンでページを戻ったときにも全く同じ議論が通じる。
TL;DR
- ページ A で
window.addEventListener('unload', ...)
されているときは、JavaScript の状態はリセットされ再実行される - ページ A で
window.addEventListener('unload', ...)
されていないときは、JavaScript の状態はリセットされずに再開される - 下記の参考ページを読んで
hidtory.back()
後に JavaScript の挙動おかしくなりがち
長年 hidtory.back()
後の JavaScript の挙動に悩まされてきた。
例えばあるとき、 Vue.js 製のフォームで hidtory.back()
後にフォームの入力がリセットされていることが問題になった。
しかも厄介なのは、この問題が再現する場合としない場合があった。
というわけで本腰入れて調べた結果、上記に挙げた参考サイトにたどり着いた。
ページ A に window.addEventListener('unload', ...)
があるか否かによって hidtory.back()
後のスクリプトの挙動が変わる。
window.addEventListener('unload', ...)
があるとき
hidtory.back()
後には JavaScript の状態がリセットされて、最初からスクリプトが再実行される。
Vue.js や React のような 要素を動的に作るライブラリ を使用している場合、状態をリセットして <input>
タグを生成しなおすので入力内容は消えてしまう。
window.addEventListener('unload', ...)
が無いとき
hidtory.back()
後に JavaScript の状態リセットはされず、ページ遷移した直後からスクリプトが再開するように見える。
<input>
タグが生成された後の状態から再開するので入力内容は生きる。
ちなみに
window.addEventListener('unload', ...)
ではなく、古き良き window.onunload = function() { ... }
の形でリスナーを設定していても、同じ挙動になる。
誰が window.addEventListener('unload', ...)
していたのか
個人の観測範囲では、 unload
イベントにリスナーを設定することは滅多にしないことだ。
私の手元の環境では Facebook ピクセル が window.addEventListener('unload', ...)
していた。そのため Facebook 広告を配信しているか否かによって hidtory.back()
後の挙動が違って見えていた。
まとめ
挙動がまちまちだと問題になるが、挙動を均一化してしまえば何らかの対処ができると思う。
私の場合は問題がおこるページに window.addEventListener('unload', () => {})
を設定し、 window.addEventListener('unload', ...)
があるときの挙動に寄せて対処した。
ほんと勘弁して。
私からは以上です。