【JS/jQuery】離脱防止ポップアップを自作する方法|コピペ可能なコード付き

2021年12月9日

ECサイトやランディングページ(LP)で「ユーザーが離脱しようとした瞬間にポップアップを表示してコンバージョン率を上げたい」というニーズは多くあります。

本記事では JavaScriptファイル1つで完結する離脱防止ポップアップ の自作方法を紹介します。HTMLやCSSもJSから動的に挿入するため、既存ページに <script> タグを追加するだけで導入できます。

注:本コードはjQueryを使用します。 jQuery未導入の環境では、後述のHTML読み込み方法に従いjQueryを先に読み込んでください。

実装できる機能

  • 自動ポップアップ:ページ表示から指定秒数後に自動で表示
  • ブラウザバック検知:戻るボタンが押されたときにポップアップを表示
  • 2回目以降の抑制:同一セッション内で複数回表示させないよう制御
  • ブラウザバック無効化:オプションで戻るボタン自体を無効にすることも可能

設定値の説明

コード冒頭の変数を変更するだけでカスタマイズできます。

auto_popup true:自動ポップアップあり / false:なし
back_popup true:ブラウザバック時にポップアップ / false:なし
multi_popup true:2回目以降も表示 / false:1回だけ表示
prevent_back true:ブラウザバック自体を無効化
pop_time 自動ポップアップが出るまでの秒数
img_path ポップアップ内に表示する画像のパス
set_href 画像クリック時のリンク先URL

JavaScriptコード

以下を js/popup.js などのファイルに保存してください。

// 自動ポップアップを止める場合は"false"
const auto_popup = true

// ブラウザポップアップを止める場合は"false"
const back_popup = true

// ポップアップを2回出さないときにfalse
const multi_popup = true

// ブラウザバックをさせない場合は"true"にする
const prevent_back = false

// ポップアップを出すタイミングを設定(秒)
const pop_time=5

// 画像ファイルの相対path
const img_path="img/img_00.jpg"

// リンク先
const set_href="index2.html"




$(function () {
    let pop_flg = false
    let back_flg = false
    let insertHtml=`
    <!-- ポップアップ -->
    <div class="modal_wrap">
    <input id="modal_trigger" type="checkbox" >
        <div class="modal_overlay">
        <label id="modal_label" for="trigger" class="modal_trigger"></label>
        <div id="modal_content" class="modal_content">
            <a href="${set_href}">
                <img src="${img_path}" alt="">
            </a>
        </div>
    </div>
    </div>
    <!-- ポップアップ -->
    `

    let insertCSS=`
    <style>
    .modal_wrap input {
        display: none;
    }

    .modal_overlay {
        display: flex;
        justify-content: center;
        overflow: auto;
        position: fixed;
        top: 0;
        left: 0;
        z-index: 9999;
        width: 100%;
        height: 100%;
        background-color: rgba(50, 50, 50, 0.6);
        opacity: 0;
        transition: opacity 0.2s, transform 0s 0.2s;
        transform: scale(0);
    }

    .modal_trigger {
        position: absolute;
        width: 100%;
        height: 100%;
    }

    .modal_content {
        position: absolute;
        top: 50%;
        left: 50%;
        align-self: flex-start;
        width: 80%;
        max-width: 600px;
        
        padding: 30px 30px 15px;
        box-sizing: border-box;
        background: rgb(255, 255, 255);
        line-height: 1.4em;

        transform: translate(-50%, -50%);
        -webkit-transform: translate(-50%, -50%);
        -ms-transform: translate(-50%, -50%);
        transition: 0.5s;
        line-height: 1.4;
        font-weight: 100;
        box-shadow: rgba(0, 0, 0, 0.4) 0px 12px 27px 2px;

        
    }


    .modal_wrap input:checked~.modal_overlay {
        opacity: 1;
        transform: scale(1);
        transition: opacity 0.2s;
    }

    .modal_content img{
        max-width: 100%;
    }
    </style>
    `


    document.getElementsByTagName('head')[0]
        .insertAdjacentHTML('beforeend', insertCSS);
    document.getElementsByTagName('body')[0]
        .insertAdjacentHTML('afterbegin', insertHtml);


    if(back_popup){
        $(document).ready(function () {
            (function (b) {
                var c = function () {
                    this.initialize();
                };
                c.prototype = {
                    initialize: function () {
                        history.replaceState("beforeunload", null, null);
                        history.pushState(null, null, null);
                        b(window).on("popstate", b.proxy(this.popstate, this));
                    },
                    popstate: function (b) {
                        if(pop_flg && !multi_popup){
                            history.go(-1)
                        }
                        if (b.originalEvent.state === "beforeunload") {
                            viewBackGuide();     
                            back_flg=true                  
                        }
                    },
                };
                new c();
            })($);
        });
    }

    //ポップアップ領域をクリックされた場合、ポップアップを閉じる
    $("#modal_label").on('click', function () {
        $("#modal_trigger").prop('checked', false);
    });
    

    function viewBackGuide() {
        if(prevent_back){
            history.pushState(null, null, null);
        }
        $("#modal_trigger").prop('checked', true);
    }
    if(auto_popup){
        if(!back_flg){
            setTimeout(function(){
                $("#modal_trigger").prop('checked', true)
                pop_flg=true
            }, pop_time*1000);
        }
    }
});
 

HTML(読み込み方)

jQueryと上記JSファイルを </body> の直前で読み込むだけです。既存のHTMLに追記するだけで動作します。

<!DOCTYPE html>
<html lang="ja">
<head>
 ・
 ・
</head>
<body>
 ・
 ・
 ・ 
<!-- JQueryとJSファイル読み込むコードを追加する -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="js/popup.js"></script>
</body>
</html>

よくある質問

WordPressのページでも使えますか?

使えます。jQueryはWordPressにデフォルトで含まれているため、popup.js をメディアライブラリにアップロードして functions.php で読み込むか、プラグイン「Code Snippets」でスクリプトを追加する方法が簡単です。

画像ではなくテキストやボタンを表示したい場合は?

insertHtml 内の <a><img></a> の部分を任意のHTMLに書き換えてください。テキストやボタン、フォームなども表示できます。

ポップアップが表示されない場合は?

jQueryが正しく読み込まれているか確認してください。ブラウザのデベロッパーツール(F12)のコンソールにエラーが出ていないか確認すると原因を特定しやすいです。また、popup.js よりも前にjQueryを読み込む順序にしてください。

自動ポップアップだけ無効にしたい場合は?

const auto_popup = false に変更してください。ブラウザバック検知のポップアップは引き続き動作します。

jQueryを使わずに実装できますか?

本コードはjQueryに依存しているため、jQuery未導入の環境では動作しません。jQuery不要(バニラJS)で同様の機能を実装したい場合は、$(document).ready(...)document.addEventListener('DOMContentLoaded', ...) に、$('#modal_trigger').prop('checked', true)document.getElementById('modal_trigger').checked = true に書き換えることで対応できます。

関連記事:ブラウザの戻るボタンを押したときにモーダルウィンドウを出すには

Javascript

Posted by Next-k