jQuery モーダルを一定時間経過後に表示(背景固定) キャンペーンや広告等に モーダル解除後は背景は元の位置に

Webサイトを開いてから一定時間経過したら、キャンペーンや広告等をモーダルで表示させる方法を紹介します。
モーダル系ライブラリは使用していません。

一定時間経過といっても、JavaScriptで時間を取得し一定時間経過したかを計算しているわけではありません。
setTimeout()メソッドを使用し、モーダルを表示する関数の実行を遅らせています。

modal

使用するファイル

  • HTMLファイル(各種ファイルの読み込み、jQueryを読み込みます。)
  • CSSファイル
  • JSファイル

一定時間経過後にモーダル表示(背景固定)を実装

CODEPENで確認

「Run Pen」をクリックしてください。

モーダルがされると、背景のスクロールバーが消えてbodyが固定されていることが分かります。

See the Pen modal by blue moon (@blue-moon) on CodePen.

HTMLファイル

<head>
  <!-- 一部省略 -->
  <link rel="stylesheet" href="style.css"> <!-- ご自身のパスに変更 -->
</head>
<body>
  <p>1分後にmodalが表示されます</p>
  <div class="text">
    テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト。<br>
    テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト。<br>
    テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト。<br>
    テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト。
  </div>
  <div id="modal-overlay">
    <div class="modal-mask"></div>
      <div class="modal-container">
        <div class="modal-inner">
          <div class="modal-title">キャンペーン</div>
          <div class="modal-text">20xx年xx月xx日まで1ヶ月無料でお試しいただけます。</div>
          <button class="close">×</button>
        </div>
    </div>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="main.js"></script> <!-- ご自身のパスに変更 --> 
</body>

補足説明

特殊文字「×」を入力するには、「&times;」を入力して下さい(このブログの性質上、 コードに「&times;」を入力しても自動変換されてしまうため) 。

CSSファイル

body {
  margin: 0;
  width: 100%;  /* モーダル表示時、幅が変更されるのを防ぐ */
  color: #444;
}

p {
  margin: 30px 0 10px;
  font-weight: 700;
  text-align: center;
}

.text {
  margin: 15px auto;
  width: 80%;
  text-align: left;
}

#modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
}

.modal-mask {
  position: absolute;
  width: 100%;
  height: 100vh;
  opacity: 0.2;
  background: rgba(123,123,123,0.2); /* 背面のbodyを少しだけ暗くし、操作できないニュアンスを出す */
}

.modal-container {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 50%;
  background: #fefefe;
  transform: translate(-50%, -50%);
  box-shadow: 3px 3px 5px #888; /* 背面のbodyの上に立体的にのせているイメージ */
}

.modal-inner {
  position: relative; /* 閉じるボタンの相対位置の基準とする */
  margin: 10px auto;
  width: 90%;
  height: auto;
}

.modal-title {
  width: 100%;
  font-size: 20px;
  font-weight: 700;
  color: #ff1493;
  text-align: center;
}

.modal-text {
  padding: 5%;
  width: 100%;
  box-sizing: border-box;
  font-size: 16px;
  letter-spacing: 1px;
}

button {
  position: absolute;
  top: calc(-10% - 8px);  /* 位置の基準とする親要素のmargin分と、親要素からはみ出す距離(ここでは8px)を引く */
  right: calc(-5% - 8px);
  padding: 3px;
  width: 20px;
  height: 20px;
  border: 1px solid #fefefe;
  border-radius: 50%;
  background-color: #fefefe;
  font-size: 20px;
  box-shadow: 2px 2px 3px #888;
  line-height: 10px;
  color: #444;
  cursor: pointer;
}

補足説明

ポップアップ等の閉じるボタンは、ウィンドウから少し外側にはみ出していること多いような気がするため、それに倣ってみました。

このボタンの位置については、ウィンドウの中のmarginを考慮した値にしてください。
そうしないと、特にmarginを%で指定している場合、画面の大きさによってボタンの位置がずれてしまいます。

JSファイル

$('#modal-overlay').hide();  // モーダルは最初は非表示

const scrollPos = $(window).scrollTop();  // モーダル表示前のスクロール位置を取得

setTimeout(() => {  // 一定時間経過後に
  $('#modal-overlay').fadeIn(400);  // 0.4秒かけてモーダルを表示
  $('body').css({position: 'fixed', top: -scrollPos, left: '0'});  // オーバーレイ背面のbodyを固定(スクロール制御)
},60000);  // 一定時間を1分(60000ミリ秒)に設定

$('button, .modal-mask').click(function() {  // モーダルの右上の閉じる(×)ボタン、若しくはモーダルのオーバーレイをクリックしたら
  $('#modal-overlay').fadeOut(400);  // 0.4秒かけてモーダルを非表示
  $('body').css({position: '', top: '', left: ''});  // 背景の固定解除
  $(window).scrollTop(scrollPos);  // スクロール位置を元に戻す
});

補足説明

スクロール量をモーダル表示前に取得し、変数に代入しておくのがポイントです。
この変数を利用して、モーダル表示時には背景の位置を固定し背景のスクロールを制御しています。

一方、モーダル非表示後にはページの位置は元のままです。
この設定をしておかないと、モーダル非表示後にページはトップに戻ってしまい、ユーザビリティに影響を与えてしまう恐れがあります(ページの高さがウィンドウの高さを超えない、つまりスクロールが発生しない場合を除いては、です)。

setTimeout()

指定時間後に関数を1度だけ実行する(つまり遅延させる)メソッドです。
引数に時間をミリ秒単位で入力します。
つまり、1分は6,000ミリ秒、2分は12,000ミリ秒…となります。

ユーザーのページスクロールやページ遷移は、意外に早いような気がします。
よって、あまり長めに設定するとモーダル表示前にページ遷移される恐れもありますので、ページのコンテンツ量と相談して遅延時間を決めた方がよいかと思います。

【参考】setInterval()

setTimeout()メソッドに類似するもので、setInterval()メソッドがあります。

こちらは構文は同じですが、関数を1度ではなく指定した一定間隔で実行します。
よって、ユーザーが長時間滞在するページで、ユーザーに数時間間隔でキャンペーンや広告等を表示させたいようであれば、こちらの方が向いているかもしれません。

例えば、ユーザーが3日間開いたままにしているサイトなどで、1日間隔でキャンペーンや広告等を表示する等は、個人的にはありだと思います。
あまり間隔が短いとユーザーに煩わしさを与えてしまいますので、ご注意ください。

背景を固定しない場合を実装

もし、モーダル表示中も背面のbodyの位置は固定せず、スクロールOKというのなら、JSファイルのコードはもっと短くて済みます。

HTMLファイルとCSSファイルは、前述のものを流用しています。

CODEPENで確認

See the Pen modal_2 by blue moon (@blue-moon) on CodePen.

JSファイル

$('#modal-overlay').hide();

setTimeout(() => {
  $('#modal-overlay').fadeIn(400);
},60000);

$('button, .modal-mask').click(function() {
  $('#modal-overlay').fadeOut(400);
});

補足説明

ここでは、以下の処理を省いています。

  • スクロール位置を取得し、変数に格納
  • モーダル表示中に、オーバーレイ背面のbody固定とスクロール制御
  • モーダル表示後に、body固定解除とスクロール位置を元に戻す

最後に

先日、特定の期限までの時間を表示させる方法を紹介しました。

これと組み合わせると、多少しつこくはなりますが、ユーザーにキャンペーン参加等を促す効果が増すと思います。

タイトルとURLをコピーしました