JavaScript

Javascriptのonbeforeunloadとonunloadについて

せっかく勉強したけど、今後は使わなさそうで忘れそうなのでメモ程度に。

Javascriptの話でウインドウを閉じようとしたときには以下のメソッドが勝手に実行される。

 ・window.onbeforeunload
 ・window.onunload

これらは以下のような流れで実行される。

2018y05m06d_113913243.jpg

これだけみるとonbeforeunloadもonunloadも一緒じゃん!と思えてくるので、
挙動や違いを下に記載しておく。

onbeforeunload

 ・returnでなにかを返すと画面を終了するかのダイアログが出現する。
  (nullやundefinedを返してもダイアログが出たのでreturn;でしかダイアログを出さない方法がわからなかった)
 ・上記のダイアログでCancelした場合、画面終了処理が中断され、ウインドウは残ったままになる。(onunload処理が行われない)
 ・上記のダイアログでOKした場合、onunload処理が走る。
 ・ダイアログの文字はchromeだと変更不可だが、IEならば任意の文字列を追加できる。
 ・onbeforeunload内の処理はダイアログが出る前に処理されてしまう。
 ・onbeforeunload内の処理は確実に行われる。

onunload

 ・この処理が終了した際にウインドウが終了し消える。
 ・処理が終了していなくても、一定時間(?)経つとウインドウが先に終了し消える。
 ・上記の先にウインドウが消えた状態でも、処理内容がシングルスレッド処理であれば確実に処理が行われるが、処理中はPCを操作できない状態になる。
 ・画面が消えたときに非同期の処理が行われていない場合はその非同期処理が行われない。
なので、画面閉じる間にバックエンドで処理しようと思ってもできないことが多々ある。
できないときの流れのイメージとしては、
①画面のonunloadを実行
②上記処理内でPUTなりでバックエンドに処理を投げる(非同期)
③結果を得る前に画面が先に消える。
④結果を得たあとの処理は実行されない。
という感じで起こり得る。しかも、バックエンド処理も正常にできるかあやしい。

両メソッド共通事項

 ・終了時だけでなく、画面更新(F5や更新ボタン)でも実行される。
 ・自画面の画面終了処理(window.close())を実施できない。
 ・他画面の画面終了処理はできる。
 ・画面新規作成(window.open())はできる。

最後に

つらつらと書いたが、厄介なのはやはりonunloadの挙動。
処理終了していなくても画面が勝手に消えるし、非同期処理だと処理が行われないことも多々あって困った。
私は結局、終了時に新規画面作ってそっちで処理するみたいにしてしまった気がする。
マルチスレッドにできるWebWorkerを使えるならそれもよいかもしれない。