WordPressのプラグインなしで自作ポップアップを実装する

本当はあまりやりたくはないですが、他社制作のWordPressの管理を任されていまして、そこをガシガシと改修することがあります。

結構めちゃくちゃな作りになっているので、機能を追加していくよりリニューアルした方が良いのですが、そこは予算の都合などもあり、なかなか難しいところ。
そんなウェブサイトでポップアップを実装したいということがあったときのお話。

WordPressにポップアップといえば【Popup Maker】

WordPressでポップアップを実装するなら【Popup Maker】が一番便利だと思ってます。
先方の要望はポップアップにメール送信フォームを表示させ、送信ボタンをクリックした人にはクッキーを利用して一定期間フォームを表示させなくするというもの。

Popup Makerであれば、それがすぐに実現出来るので簡単だと思ってました。

念のため自分の契約しているレンタルサーバーでWordPressを構築して実装したところ上手く稼働したので、そのまま先方のテストサイトにPopup Makerをインストール、有効化したところ全く動かない。
コンソールエラーも無く、コードや設定なども一切の間違いが無く、それでも動かない。

実はこういったことが既に何度も起きているサイトなので、想定していなかったわけでもないですが、やはり面倒臭いですね。色々探ってどうにかポップアップは表示されるようになっても、希望する送信フォームとの連動が出来ない。
加えて他のプラグインが動作しなくなるという問題も起きる。

早くリニューアルして欲しい!と思いつつも、今回はどうにかしなければならない。
ということで自作することにしました。

想定しているポップアップ送信フォームのイメージ

完成形としてはこんな感じの簡単な回答フォームを想定しています。
Contact Form 7をそのまま使うので特に送信確認画面はなく、送信したらそのまま完了になり、ポップアップが閉じます。

まずはhtmlとcssから

<div id="popup" class="popup-hidden">
    <div class="popup-survey">
        <!-- Contact Form 7のショートコード -->
        

エラー: コンタクトフォームが見つかりません。

<button id="close-popup">×</button> </div> </div>

htmlは楽ですね。回答する人ばかりじゃないので、一応「×」でポップアップを閉じるようにはしています。
Contact Form 7を入れるためのショートコードを入れてあとは適当に。

続いてcss。

/* ポップアップ全体 */
#popup {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.8);
  z-index: 1000;
}

/* ポップアップが表示されるべき時 */
#popup:not(.popup-hidden) {
  display: block;
}

/* ポップアップコンテンツ */
.popup-survey {
  background-color: #fff;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 60px 20px;
  width: 90%;
  max-width: 640px;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
}

/* 閉じるボタン */
#close-popup {
  font-size: 2.4rem;
  background-color: #000;
  color: #fff;
  line-height: 1;
  padding-top: 3px;
  border: none;
  cursor: pointer;
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
}

.popup-survey__form {
  margin-top: 40px;
}
.popup-survey__form dl dt {
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 1.6rem;
  font-weight: bold;
  background: #eee;
  line-height: 1.4;
  padding: 15px;
}
.popup-survey__form dl dd {
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 1.6rem;
  padding: 20px 0 10px;
}
/* ラジオボタン */
.popup-survey__form dl dd .wpcf7-list-item {
  margin-bottom: 10px;
}
.popup-survey__form dl dd input[type="radio"] {
  margin-top: -3px;
}

/* 自由入力テキスト欄 */
.popup-survey__form dl dd textarea {
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 1.6rem;
  display: block;
  width: calc(100% - 4em);
  margin: auto;
  padding: 10px;
}

/* 送信ボタン */
.popup-survey__form .submit-btn {
  max-width: 260px;
  margin: 40px auto 0;
}
.popup-survey__form .submit-btn input[type="submit"] {
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 1.6rem;
  background: #f60;
  color: #fff;
  text-align: center;
  width: 100%;
  padding: 15px 0;
  border: none;
  cursor: pointer;
  transition: all .3s ease-in-out;
  -webkit-appearance: none;
}
.popup-survey__form .submit-btn input[type="submit"]:hover {
  opacity: .7;
}

続いてJavaScriptのコード

document.addEventListener('DOMContentLoaded', function() {
    var popup = document.getElementById('popup');
    var closePopupButton = document.getElementById('close-popup');

    // クッキーをチェックしてポップアップを表示/非表示
    if (!getCookie('answered')) {
        popup.classList.remove('popup-hidden');
    }

    // 閉じるボタンをクリックしたときの動作
    closePopupButton.addEventListener('click', function() {
        popup.classList.add('popup-hidden');
    });

    // アンケートフォームが送信されたときの動作
    document.addEventListener('wpcf7mailsent', function() {
        setCookie('answered', 'true', 30); // 30日間クッキーを保存
        popup.classList.add('popup-hidden');
    }, false);
});

// クッキーを取得する関数
function getCookie(name) {
    var value = "; " + document.cookie;
    var parts = value.split("; " + name + "=");
    if (parts.length == 2) return parts.pop().split(";").shift();
}

// クッキーをセットする関数
function setCookie(name, value, days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "")  + expires + "; path=/";
}

上記コードではクッキーの保存期間を30日にしていますが、こちらは適宜調整してください。

クッキーの有効期間を変更する場合

あまりないかもしれませんが、クッキーの期間を時間や分で設定する場合も一応書いておきます。

例えばクッキーを1時間後に期限切れにする設定は以下の通りとなります。

// アンケートフォームが送信されたときの動作
document.addEventListener('wpcf7mailsent', function() {
    setCookie('answered', 'true', 3600000); // 1時間(3600秒 = 3600000ミリ秒)
    popup.classList.add('popup-hidden');
}, false);
// クッキーをセットする関数
function setCookie(name, value, ms) {
    var expires = "";
    if (ms) {
        var date = new Date();
        date.setTime(date.getTime() + ms);
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "")  + expires + "; path=/";
}

クッキーを使用するということは、それなりの期間を要することかとは思うので、使うことはほとんど無いかと思いますが、もし使うことがあれば参考にしてみてください。