WEB制作、マーケティングに関する情報をお届けします。ホームページ制作会社、テラのブログ

Javascriptでページ離脱時にオリジナルのポップアップを表示させる方法

タグ:

お問い合わせ入力最中に離脱しようとした場合に使用するダイアログ。通常はブラウザの標準ダイアログが表示されますが、これを拒否する方法があります。ブラウザを離れようとした際に表示される広告などにも使用されることもありますね。
今回はそんな『ページ離脱時にオリジナルのポップアップを表示させる方法』を紹介します。

※GoogleChromeでは標準ダイアログやページ遷移を完全に制御はできません。尚且つ、ユーザーが意図しない動作をさせることになるため非推奨です。どうしてもページを離れるユーザーに対して見せたいものなどがある場合にのみ使用しましょう。
推奨される方法はこちら

コードの紹介

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
<style>
.contents {
    position: relative;
    height: 100vh;
    width: 100%;
}
.contents a{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%)
}
.popup {
    display: none; /* 初期状態で非表示 */
    position: fixed; /* 固定位置 */
    top: 50%; /* 画面の縦中央 */
    left: 50%; /* 画面の横中央 */
    transform: translate(-50%, -50%); /* 中央に寄せるための変形 */
    background-color: #fff; /* 背景色 */
    padding: 20px; /* 内側の余白 */
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 影を付ける */
    z-index: 1000; /* 他の要素より前面に表示 */
    border-radius: 10px; /* 角丸にする */
}

.popup ul {
    list-style-type: none; /* リストのマーカーを消す */
    padding: 0; /* 内側の余白を消す */
    display: flex; /* 横並びにする */
    justify-content: space-around; /* 均等に並べる */
}

.popup ul li {
    margin: 0 5px; /* リストアイテム間の余白 */
}

.popup ul li button {
    padding: 10px 20px; /* ボタンの内側の余白 */
    border: none; /* ボーダーを消す */
    background-color: #0073aa; /* ボタンの背景色 */
    color: #fff; /* ボタンの文字色 */
    cursor: pointer; /* カーソルをポインターに */
    border-radius: 5px; /* 角丸にする */
}
.popup ul li button:hover {
    background-color: #005f8a; /* ホバー時の背景色 */
}
</style>
</head>
<body>
<!--HTML-->
<div class="contents" style="height:100vh;width: 100%;">
    <a href="./">他のページへ移動する</a>
</div>
<div class="popup">
    <p>まだ、資料請求が完了しておりません。<br>入力内容が破棄されますがよろしいですか?</p>
    <ul>
        <li><button class="popup_close" type="button" data-action="confirm">はい</button></li>
        <li><button class="popup_close" type="button" data-action="cancel">いいえ</button></li>
    </ul>
</div>
</body>
</html>

Javascript

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script>
(function($) {
    $(document).ready(function() {
        var isPopupShown = false;
        var hrefToNavigate = null;
        var isBackNavigation = false;
        
        // 初期の状態を履歴にプッシュ
        history.replaceState(null, document.title, window.location.href);
        history.pushState(null, document.title, window.location.href);
        
        // popstateイベントをリスン
        window.addEventListener('popstate', function(event) {
            showPopup(event, 'back');
        });
        
        // 離脱確認のポップアップ表示
        function showPopup(event, type, href) {
            event.preventDefault();
            $('.popup').show();
            isPopupShown = true;
            hrefToNavigate = href;
            if (type === 'back') {
                isBackNavigation = true;
            }
        }
        
        // ポップアップを閉じる
        function closePopup() {
            $('.popup').hide();
            isPopupShown = false;
            hrefToNavigate = null;
            isBackNavigation = false;
        
            // 戻る操作を取り消す
            history.pushState(null, document.title, window.location.href);
        }
        
        // ポップアップ閉じるボタンのクリックイベント
        $('.popup_close').on('click', function() {
            var action = $(this).data('action');
            if (action === 'confirm') {
                if (isBackNavigation) {
                    history.back();
                } else if (hrefToNavigate) {
                    window.location.href = hrefToNavigate;
                }
            } else {
                closePopup();
            }
        });
        
        // ページ離脱時に標準ダイアログを表示
        $(window).on('beforeunload', function(event) {
            if (!isPopupShown) {
                var message = '本当にこのページを離れますか?';
                event.returnValue = message;
                return message;
            }
        });
        
        // リンククリック時にポップアップ表示
        $('a').on('click', function(event) {
            showPopup(event, 'link', $(this).attr('href'));
        });
    });
})(jQuery);
</script>

コードの解説

HTMLの説明は割愛してJavascriptのみ解説していきます。

var isPopupShown = false;
var hrefToNavigate = null;
var isBackNavigation = false;

まずは、ポップアップに表示させるか、リンクをクリックされた時の値、戻るボタンをクリックした際に正規の動作同様に戻れるようにするのかといった判断を行う必要があるため、それぞれ使用する変数にfalse、nullを入れておきます。

history.replaceState(null, document.title, window.location.href);
history.pushState(null, document.title, window.location.href);

戻るボタンをクリックした際にブラウザの標準ダイアログはを拒否するために今回はhistoryというオブジェクトを使用します。
historyオブジェクトはブラウザの閲覧履歴を管理するオブジェクトです。
(ブラウザのデフォルトのダイアログを使用する場合はhistoryオブジェクトは使用しません。)
『history.replaceState()』は現在の閲覧履歴を保存することができます。
『history.pushState()』は前の閲覧履歴を追加することができます。
通常はブラウザの戻るボタンをクリックするとダイアログが表示されてしまいますが、ページ遷移をさせずに前ページの情報参照させることで、ブラウザ固有の標準ダイアログは拒否することができます。

window.addEventListener('popstate', function(event) {
    showPopup(event, 'back');
});

『window.addEventListener(‘popstate’, function(event) {}』でブラウザバックした際に実行させ、ポップアップ表示を行います。

function showPopup(event, type, href) {
    event.preventDefault();
    $('.popup').show();
    isPopupShown = true;
    hrefToNavigate = href;
    if (type === 'back') {
        isBackNavigation = true;
    }
}

離脱確認のポップアップ表示させます。
ポップアップの表示させて『isPopupShown(ポップアップ)』、『hrefToNavigate(リンク)』を設定します。バックボタンの場合に『back』が含まれていた場合はバックボタンにtrueを入れておきます。これ以降に書く、ポップアップのはい、いいえをクリックした場合の条件分岐使用します。

function closePopup() {
    $('.popup').hide();
    isPopupShown = false;
    hrefToNavigate = null;
    isBackNavigation = false;

    // 戻る操作を取り消す
    history.pushState(null, document.title, window.location.href);
}

ポップアップを閉じた場合の処理を書きます。
ポップアップを閉じる場合は『isPopupShown(ポップアップ)』、『hrefToNavigate(リンク)』、『isBackNavigation(ブラウザのバックボタン)』は初期化します。
前ページ情報に『history.pushState(null, document.title, window.location.href)』で今のページを一つ前のページ閲覧履歴に追加します。

$('.popup_close').on('click', function() {
    var action = $(this).data('action');

    if (action === 'confirm') {
        if (isBackNavigation) {
            history.back();
        } else if (hrefToNavigate) {
            window.location.href = hrefToNavigate;
        }
    } else {
        closePopup();
    }
});

ポップアップのはい、いいえのいずれかのボタンを押した際に実行させます。『$(this).data(‘action’);』で、はい、いいえに振っているdata属性のactionの値を取得します。はいをクリックした場合はdata属性にcofirmが振ってあります。confirmと一致しなかった場合はポップアップを閉じます。また、一致した場合の処理を書きます。もし、『isBackNavigation(ブラウザバック)』にtureが入っていればブラウザバックで戻らせます。『isBackNavigation(ブラウザバック)』にfalseが入っていれば、『hrefToNavigate(リンク)』に値があるかどうかを確認して、値があった場合はそのURLへとリダイレクトがかかります。

$('a').on('click', function(event) {
    showPopup(event, 'link', $(this).attr('href'));
});

ポップアップのはい、いいえのいずれかのボタンを押した際に実行させます。

今回の方法は非推奨!

今回紹介した方法はブラウザの履歴を書き換えてユーザーの意図しない動きを強制的に行っています。
推奨される方法ではありません。『どうしても』というときに使用してください。

推奨される方法とは?

デフォルトのダイアログを立ち上げるだけであれば問題はないでしょう。また、その場合は数行で処理は完結します。

<script>
window.addEventListener('beforeunload', function (event) {
  event.preventDefault();
})
</script>

まとめ

以上、『Javascriptでページ離脱時にオリジナルのポップアップを表示させる』でした。
基本的に推奨できない方法ではありますがオリジナルのポップアップを表示させる際にはこのような処理が必要かと思います。どうしても必要という場合に参考にしてください。

テラ合同会社(東京都)

テラは2014年に東京都でスタートアップしたホームページ制作会社です。ホームページ制作以外にも広告運用、マーケティング、ブランディング、印刷物など幅広い領域をサポートしています。
コーポレートサイトはこちらをご覧ください。