2018年のbeforeunloadイベントハンドラーの書き方メモ

2018年のbeforeunloadイベントハンドラーの書き方メモ:

ブラウザ自身またはタブを閉じる時に、大事な未保存情報がある場合、beforeunloadイベントハンドラーを登録することで、閉じる処理を止めて確認ダイアログを表示することが出来ます。

今回はreactでbeforeunloadハンドラーを書く時にはまったことをメモします。


結論

  • 確認ダイアログの表示・非表示と表示するメッセージのコントロールはbeforeunloadハンドラーのevent.returnValueだけでコントールすれば良い。
  • beforeunloadハンドラーでメッセージ文字列を返すような実装だと、変な動きがあるからです。


環境

  • Win7+IE11
  • MacOS 10.13.5 + Chrome 70.0


reactでの書き方

export default class MyComp extends React.Component { 
  constructor(props) { 
    super(props); 
 
    this.handleBeforeUnload = this.handleBeforeUnload.bind(this); 
  } 
 
  componentWillMount() { 
    // 登録 
    window.addEventListener('beforeunload', this.handleBeforeUnload); 
  } 
 
  componentWillUnmount() { 
    // 解除 
    window.removeEventListener('beforeunload', this.handleBeforeUnload); 
  } 
 
  handleBeforeUnload(e) { 
    if (this.props.hogeObject) { 
      // 仕様標準のメソッドを呼び出す 
      e.preventDefault(); 
      // returnValueに画面に表示したいメッセージを設定(Chromeはそれを無視してブラウザ定義のメッセージを表示) 
      e.returnValue = '未保存のデータがありますが、本当に閉じますか?'; 
    } 
  } 
  // ... 
} 
  • 該当条件に当たった場合、e.returnValueにメッセージ文字列を設定すると、閉じる動作が停止されます。

  • e.preventDefault()が仕様標準のお薦めなので、念のため書きます。


次のような書き方でまった!!!

ネットで調べるとよく出てくる記事には、マルチブラウザをサポートするために、e.returnValueとハンドラーの戻り値を両方返すようなお薦め実装がありますが、実に試してみたら、下記のような変な動きがあることがわかりました。

  • 最初はhogeObjectがない状態で、確認ダイアログなしで、タブを閉じれます。
  • 一旦hogeObjectがある状態にして、タブを閉じると確認ダイアログが表示されます。(ここまでまた良い)
  • 他の画面に遷移してから、もう一回この画面を表示して、hogeObjectない状態でタブを閉じると、確認ダイアログが表示されてしまいます。
  • デバッグしてみたら、handleBeforeUnloadは初回と同じように空白文字列を返しています。
  • 戻り値が空白でも、初回と違って確認ダイアログを表示するのが何故でしょうか?ブラウザがURL単位で覚えたのかな?
handleBeforeUnload(e) { 
    let msg = ''; 
    if (this.props.hogeObject) { 
      // 仕様標準のメソッドを呼び出す 
      e.preventDefault(); 
      // returnValueに画面に表示したいメッセージを設定(Chromeはそれを無視してブラウザ定義のメッセージを表示) 
      msg = '未保存のデータがありますが、本当に閉じますか?'; 
    } 
 
    e.returnValue = msg; 
    return msg; 
  } 


解決

ブラウザの裏仕様がわかりませんが、一旦標準に書いてあるe.returnValueに戻り値を設定するように修正したら、今回の問題を解決しました。


参考ドキュメント

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)