• トップ
  • ブログ一覧
  • JavaScriptで離脱防止アラートを表示する(ブラウザバック・リロード・タブ閉じ)
  • JavaScriptで離脱防止アラートを表示する(ブラウザバック・リロード・タブ閉じ)

    おか(エンジニア)おか(エンジニア)
    2022.02.08

    IT技術

    JavaScriptで離脱防止アラートを表示する(ブラウザバック・リロード・タブ閉じ)

    リロード・タブが閉じられる時の対応

    保存されていないデータがあるときに、誤ってページを閉じてしまわないようにアラートを出すやり方を紹介します。ブラウザで戻るボタンやリロードボタンが押された時、タブを閉じようとしたときに動きます。

    beforeunloadを使います。ウィンドウや文書がアンロード(リロードやタブを閉じる)時のイベントです。同様に onbeforeunload でも設定できますが、addEventListener の方が推奨されています。

    1window.addEventListener('beforeunload', (e: BeforeUnloadEvent) => {
    2  const message = '入力内容が保存されない可能性があります。ページを離れますか?'
    3    e.preventDefault()
    4    e.returnValue = message
    5    return message
    6})
    7
    8window.onbeforeunload = (e: BeforeUnloadEvent) => {
    9    // ...
    10})

    returnValueなどを設定してはいますが、表示させる文章を操作することはできません。
    以前は指定可能だったようですが、よろしくないメッセージ(「ページを離れるとウイルスにかかるぞー!」みたいな)が設定されることもあったため、現在はブラウザごとに規定の文章になっているようです。

    ブラウザバック時の対応

    基本的には popstate イベント を利用します。
    履歴がスタック状にブラウザに記録されている中で、その記録を取り出すときのイベントです。ブラウザバック時、このイベントが実行されています。

    1window.history.pushState(null, document.title); // 必要であれば、セッション履歴スタックに状態を追加
    2window.addEventListener('popstate', () => {
    3    // 任意の処理
    4    // history.back()やhisotry.go()などを用いて任意のページに移動するようにします
    5});

    注意点:MDNにも書いてあるように、実行されるとキャンセルできません。それを踏まえた上での実装を!

    調べていると、popstateを使用せず、onhashchangeなどハッシュの変更を検知することで、ブラウザバックの対応をすることもあるそうです。状況に合わせて使いたいですね。

    各フレームワーク・ライブラリの使えそうなメソッド

    ブラウザバック時などに使えそうな各ライブラリ・フレームワークのメソッドをいくつか見つけたので、軽くご紹介します。

    Vue

    Vue Router - beforeRouteLeave

    編集中に誤って経路を離れるのを防ぐ時を想定して作られてます。
    詳細:ナビゲーションガード | Vue Router

    1beforeRouteLeave (to, from, next) {
    2    if (window.confirm('入力内容が保存されない可能性があります。ページを離れますか?')) {
    3        next()
    4    } else {
    5        next(false)
    6    }
    7}

    React

    先に React での注意点です。アンマウント時にイベントを解除しておかないと、該当箇所以外でもイベントが実行されます!

    1useEffect(() => {
    2    // addEventListenerなどでイベント登録
    3    return () => {
    4        // removeEventListenerなどでイベント解除
    5    }
    6}, [])

     

    react-router-dom - history.block

    react-routerの中に入っているweb用のルーターライブラリ。
    そのhistory.blockも編集中に誤ってページを離れるのを防ぐのに適してます。
    詳細:Blocking Transitions

    1// 表示するメッセージを指定
    2history.block('入力内容が保存されない可能性があります。ページを離れますか?')
    3
    4// ブロック解除
    5history.block(true)
    6
    7// 任意の処理もできる
    8history.block(() => {
    9    if (window.confirm('入力内容が保存されない可能性があります。ページを離れますか?')) {
    10        // ...
    11    }
    12})

     

    Next.js - router.beforePopstate

    popstate が起きる前に処理を追加できます。
    詳細:next/router router.beforePopState|Next.js

    1useEffect(() => {
    2    router.beforePopState(({ url, as, options }) => {
    3        if (as === '/about') {
    4        return false // falseを返すとNext.jsはpopstateを処理しない
    5     }
    6    return true
    7    })
    8}, [])

    さいごに

    デフォルトのJavaScriptだけでなく、ライブラリのメソッドもご紹介しましたが、状況に適したやり方を使っていけたらいいですね!

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background