無駄と文化

実用的ブログ

history.back() でページを戻ったときの JavaScript の挙動

「ページ A」から「ページ B」へ遷移した後に「ページ B」で hidtory.back() が実行され「ページ A」に戻ってきたとき、「ページ A」で走っていたスクリプトの挙動について考えよう。

f:id:todays_mitsui:20220214191042p:plain

ちなみにブラウザの「戻る」ボタンでページを戻ったときにも全く同じ議論が通じる。

 

TL;DR

  • ページ A で window.addEventListener('unload', ...) されているときは、JavaScript の状態はリセットされ再実行される
  • ページ A で window.addEventListener('unload', ...) されていないときは、JavaScript の状態はリセットされずに再開される
  • 下記の参考ページを読んで

nmi.jp

 

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', ...) があるときの挙動に寄せて対処した。

ほんと勘弁して。

 

私からは以上です。