プログラミング・エンジニア転職

【プラグインなし】同一ページに複数のモーダルウィンドウを仕込む方法【CSS・jQuery】

モーダルウィンドウの作り方をまとめたので記事にしました。

この記事で紹介するモーダルウィンドウは、

  • 同一ページ内に複数のモーダルウィンドウを仕込んでおける
  • モーダルウィンドウを表示中、記事本体はスクロールできない
  • モーダルウィンドウ自体はスクロール可能
  • レスポンシブ対応

こんな機能になっています。

ソウ

もし気に入ったら、コピペして使ってみてください

モーダルウィンドウの作り方はザックリ2種類

紙の本

モーダルウィドウの作り方はザックリ2種類に大別が出来て、

  1. HTMLに記述 → CSSで一旦消す → javascriptで再表示する
  2. HTMLには記述せず、javascriptでコード生成&挿入を行う

このいずれかになります。

このうち、個人的なオススメは①です。

理由としては、

  • javascriptでHTMLを生成した場合、SEO的に正しく評価されない可能性がある
  • HTMLに直接書いてある方が管理がしやすい

こんなかんじです。

ソウ

この記事でも方法①でモーダルウィンドウを作成してます

ケース①:仕込んでおくモーダルウィンドウが一つだけの場合

実際のコードは、

  • ページ中で表示したいモーダルウィンドウが1つだけの場合
  • ページ中で表示したいモーダルウィンドウが複数ある場合

どちらかに該当するかで、コードが若干変わってきます。

まずは、より仕組みが単純な「仕込むモーダルウィンドウが一つだけの場合」を見ていきます。

具体的なコードは次のとおりです。

<a href="#" class="js-modal-open">モーダルウィンドウを開く</a>

<div class="modal js-modal">
  <div class="modal-bg js-modal-close">
  </div>
    <div class="modal-content">
      <p>ここにコンテンツが入ります。ここにコンテンツが入ります。ここにコンテンツが入ります。</p>
      <a href="#" class="js-modal-close">閉じる</a>
    </div>
</div>

<script>
  var scrollPosition;

  // モーダルウィンドウを開く
  $('.js-modal-open').on('click', function(){
    scrollPosition = $(window).scrollTop();
    $('body').addClass('fixed').css({'top': -scrollPosition});
    $('.js-modal').fadeIn();
    return false;
  });

  // モーダルウィンドウを閉じる
  $('.js-modal-close').on('click', function(){
    $('body').removeClass('fixed');
    window.scrollTo( 0 , scrollPosition );
    $('.js-modal').fadeOut();
    return false;
  });
</script>
/* これが無いとモーダルウィンドウ表示の際に余白が出る */
*{
  margin: 0;
  padding: 0;
}

/* モーダル全体(背景+本体) */
.modal{
  display: none;
  position: fixed;
  top: 0;
  height: 100vh;
  width: 100%;
}

/* モーダル背景 */
.modal-bg{
  position: absolute;
  height: 100vh;
  width: 100%;
  background: rgba(0, 0, 0, 0.8);
}

/* モーダル本体 */
.modal-content{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  overflow: scroll; /* はみ出た部分はスクロールさせる */
  height: 60%;/* これが無いと「overflow:scroll」が利かない */
  width: 60%;/* これが無いと「overflow:scroll」が利かない */
  background: white;
  padding: 40px;
}

/* モーダルウィンドウ表示中に記事本体を固定 */
body.fixed {
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
}

「index.html」の16~21行目を見れば分かりやすいですが、モーダルウィンドウが表示される流れは、

  1. <a>タグ(class:js-modal-open)をクリックしたら発火
  2. 現時点での画面の高さを計測して、記事をそこで固定
  3. その後、モーダルウィンドウを表示する

こんなかんじです。

記事本体をスクロールさせない方法

ただモーダルウィンドウを表示するだけだと、記事スクロールできてしまいます。

しかしそれだと、ユーザーの使い勝手が悪くなるため、「index.html」の18行目で、

  • body本体にfixedを付けつつ
  • topからの高さを指定する

こんな制御を行うことで、モーダルウィンドウの表示中は、記事をスクロールできないようにしています。

モーダルウィンドウをスクロールさせる方法

記事本体はスクロール出来ないようにしたいですが、モーダルウィンドウはスクロール可能にしたいところです。

ソウ

特に長文をスマホで表示する場合などは必須かと

これを実現しているが、「base.css」の30~32行目です。

「overflow:scroll」を設定することで、はみ出た要素はスクロール表示が出来るようにしています。

ソウ

モーダル本体に幅と高さを指定しないと、スクロール出来ないので注意

ケース②:同一ページ中に複数のモーダルウィンドウを仕込む方法

モーダルウィンドウを複数仕込む場合、少しコードを書き直す必要が出てきます。

修正のポイントとしては、

  • 各モーダルウィンドウに個別の識別子を指定する
  • jQuery(javascript)はクリックされた識別子だけを操作する

この2点です。

具体的なコードは次のとおりです。

<a href="#" class="js-modal-open" data-target="modal01">モーダルウィンドウ1を開く</a>
<a href="#" class="js-modal-open" data-target="modal02">モーダルウィンドウ2を開く</a>
<a href="#" class="js-modal-open" data-target="modal03">モーダルウィンドウ3を開く</a>

<div id="modal01" class="modal js-modal">
  <div class="modal-bg js-modal-close">
  </div>
    <div class="modal-content">
      <p>同一ページに複数のモーダルウィンドウが存在する場合。同一ページに複数のモーダルウィンドウが存在する場合。</p>
      <a href="#" class="js-modal-close">閉じる</a>
    </div>
</div>

<div id="modal02" class="modal js-modal">
  <div class="modal-bg js-modal-close">
  </div>
    <div class="modal-content">
      <p>ここにコンテンツ2が入ります。ここにコンテンツ2が入ります。ここにコンテンツ2が入ります。</p>
      <a href="#" class="js-modal-close">閉じる</a>
    </div>
</div>

<div id="modal03" class="modal js-modal">
  <div class="modal-bg js-modal-close">
  </div>
    <div class="modal-content">
      <p>ここにコンテンツ3が入ります。ここにコンテンツ3が入ります。ここにコンテンツ3が入ります。</p>
      <img src="img/soccer.jpg" class="aaa">
      <a href="#" class="js-modal-close">閉じる</a>
    </div>
</div>

<script>
// モーダルウィンドウを開く
$('.js-modal-open').on('click', function(){
  var target = $(this).data('target');
  var modal = document.getElementById(target);
  scrollPosition = $(window).scrollTop();

  $('body').addClass('fixed').css({'top': -scrollPosition});
  $(modal).fadeIn();
  return false;
});

// モーダルウィンドウを閉じる
$('.js-modal-close').on('click', function(){
  $('body').removeClass('fixed');
  window.scrollTo( 0 , scrollPosition );
  $('.js-modal').fadeOut();
  return false;
});
</script>
ソウ

CSSは先ほどと同じなので省略します

サンプルページはこちらになります。

ポイントは、data属性(data-target)を使って、<a>タグとモーダルウィンドウとjQueryを繋げている部分です。

「index.html」の52~60行目にありますが、具体的な流れとしては、

  1. <a>タグをクリックする
  2. <a>タグに設定してるdata属性と同じ名称のIDを取得する
  3. ②で取得したIDのモーダルウィンドウを表示する

こんなかんじですね。

ちなみに「data属性」はHTML5から新たに出来た機能で、クラスやIDみたいな扱い方ができるみたいですね。

プラグイン不要なモーダルウィンドウについて解説しました!

「まとめ」と書かれた画像

モーダルウィンドウってレベルが高いイメージですが、仕組みが分かれば単純ですね。