【jQuery】スクロールできるモーダルウィンドウの作り方【初級編】

モーダルウィンドウの作り方を見ていきます。こだわり始めるときりがないので、今回はまず『スクロールが出来るモーダル』を作ってみます。制作途中も含めてサンプルを用意しておくのでご利用ください。


仕様を考えてみる

モーダルウィンドウと一言でいってもいろいろ考えることがあります。

  • モーダル自体のスクロール可否
  • windowsで見る場合、bodyのスクロールバー
  • モーダルの出現・終了時の挙動(アニメーションなど)
  • モーダルの中身をHTML側とJS側のどちらで書くか

例を挙げるときりがないですが、作る段階でどこまで対応するのかを考えておきましょう。

今回はスクロールできるモーダルウィンドウを作っていきます。


そもそもモーダルとは?

そもそもの話ですが、モーダルウィンドウがどのようにできているのかというのを理解しておかないと作れません。

モーダルの仕組み

body(現在開いているページ)に対して、その上からモーダル背景、更にその上にモーダル本体を表示しているというのがモーダルウィンドウの仕組みです。

なのでモーダル背景とモーダル本体を通常時に表示している部分より上に来るように指定する必要があります。


CSSで指定することは?

CSSで設定しておくのは以下の項目です。

モーダル背景に対して
positionプロパティ
幅と高さをbodyと同じに
背景色(半透明にしておくと雰囲気が出る)
モーダル本体に対して
positionプロパティ
幅と高さ(必要に応じて)
モーダルをセンタリング
背景色(透過させないほうが差分がわかりやすい)

モーダルで必要なcss設定で不明な部分については以下でご確認ください。

幅と高さについて

【CSS】width(幅)とheight(高さ)の指定方法
レスポンシブデザインが求められるからこそ、1番厄介なのが幅と高さの指定だと改めて思うのでまとめてみます。 width(幅)の指定 『px』で幅を指定 『%』で幅を指定 height(高さ)の...

positionプロパティについて

【CSS】positionとは?relativeとabsolute以外も解説
positionプロパティについて学んでいきましょう。値はstatic、relative、absolute、fixedと4つあります。また、よく一緒に使われる top、bottom、left、rightについても併せてみていきます。 posit...

CSSを設定してみる

今回はモーダル背景については<div id=”bg”>、モーダル本体には<div id=”modal”>というふうに指定します。

[CSS]

#bg {
  position:fixed; /* 階層を上にする */
  width:100%; /* 画面めいっぱい */
  height:100%; /* 画面めいっぱい */
  background:rgba(0,0,0,0.4); /* 背景色 */
}
$modal {
  position:fixed; /* 階層を上にする */
  width:90%; /* モーダルの幅 */
  height:80%; /* モーダルの高さ */
  top:50%; /* bodyの上から50%分ずらす */
  left:50%; /* bodyの左から50%分ずらす */
  transform:translate(-50%,-50%);/* 指定した位置から真ん中にずらす */
  background:#fff; /* モーダルの色 */
  overflow-y:scroll; /* 高さを指定しているので中身が超えた分はスクロールできるように */
}

コメントアウトしてあるので細かくは省きます。なお、既にfixedやabsoluteなどが元々のページで指定されている場合はz-indexで重なる順番を調整してあげましょう。

あと、ひどい参考書などではモーダル本体やモーダル背景にfixedでなくabsoluteが指定されている場合がありますが、モーダルは基本的にどの位置で開いても画面中心に来る必要があるのでfixedで指定するべきです。

【CSS】positionとは?relativeとabsolute以外も解説
positionプロパティについて学んでいきましょう。値はstatic、relative、absolute、fixedと4つあります。また、よく一緒に使われる top、bottom、left、rightについても併せてみていきます。 posit...

jQueryでやる事は?

jQueryでやることは、

jQuery側でやること

  • クリックイベントを設定
  • <div id=”bg”>、<div id=”modal”>を生成
  • <div id=”modal”>の内容生成
  • <div id=”bg”>をクリックでモーダル背景&本体を削除

少し検索エンジン(Goolgeなど)の話ですが、JS側で中身を生成するのは現状では賛否両論あります。

SEO(ページの内容を評価する仕組み)を考えた時、JS自体は読み込めるのですがクリックなどのイベント後に生成されるものに関しては検索エンジンが内容を取得できない為ページ全体が正しく評価できない状態になる可能性があります。

詳しくは『Fetch as Google』で調べてみてください。


クリックでモーダルを開く

今回はなんてことない<p>タグをボタンとして使ってみます。HTMLは以下のようにしておきます。

[HTML]

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
  <p>スイッチ</p>
  <script src="modal.js"></script>
</body>
</html>

[jQuery]

$(function(){
  $('p').click(function(){
    //ここにモーダルについて書く

    //bodyの直下に<div id="bg">と<div id="modal">を追加
    $('body').append('<div id="bg">').append('<div id="modal">');    
  });
});

<p>タグをクリックした時にfunction内を実行するという意味になります。

    $('body').append('<div id="bg">').append('<div id="modal">');

appendは指定したセレクタ内の一番最後に追加するメゾットです。詳しくはこちらをご覧ください。

【jQuery】要素を追加する様々な方法一覧【サンプルあり】
jQueryで要素を追加する色々な方法を見ていきます。 使い方サンプル一覧 appendとは? prependとは? appendToとは? prependToとは? beforeとは?...

なお、<div id=”bg”>と<div id=”modal”>はCSS上ではfixedという同じ階層にいるので、HTML上で<div id=”modal”>が後に記述されるように<div id=”bg”>を先に追加してから<div id=”modal”>を追加しましょう。

もしこの説明がわからない場合はCSSで#modalにz-indexを指定してあげましょう。

現段階では<p>タグをクリックするとモーダルのエリアだけ生成されるだけの状態です。

モーダルエリア生成のサンプルを見てみる


モーダルの中身を作る

今回は疑似的に中身を追加するので、for文でリストを作ります。

[jQuery]

$(function(){
  $('p').click(function(){
    //ここにモーダルについて書く

    //bodyの直下に<div id="bg">と<div id="modal">を追加
    $('body').append('<div id="bg">').append('<div id="modal">');

    //for文用に変数numを指定しておく
    var num = 0;

    //モーダルの中にulを生成
    $('#modal').append('<ul>');

    //今回は1~50までのリストを作成
    for(var i =0 ; i <50 ; i++){

     //50まで1ずつ数を追加
      num += 1;

     //ulの中に<li>num</li>を追加
      $('ul').append('<li>'+ num +'</li>');
    }
  });
});

for文についてはこちらをご覧ください。

【JavaScript】for文のループ処理とは?【簡略化】
JavaScriptを使って繰り返しの処理について見ていきます。 for文とは? for文の文法 1~10までのループを作る ループの終点を自動で追加 注意点 for文とは? 簡単...

現段階での状態は以下でご確認ください。

モーダルを生成・中身を追加した状態を見てみる


クリックでモーダルを閉じる

モーダルが生成されるようにはなったのですが、1度開くと閉じることが出来ませんので閉じられるようにします。

[jQuery]

$(function(){
  $('p').click(function(){
    //ここにモーダルについて書く

    //bodyの直下に<div id="bg">と<div id="modal">を追加
    $('body').append('<div id="bg">').append('<div id="modal">');

    //for文用に変数numを指定しておく
    var num = 0;

    //モーダルの中にulを生成
    $('#modal').append('<ul>');

    //今回は1~50までのリストを作成
    for(var i =0 ; i <50 ; i++){

     //50まで1ずつ数を追加
      num += 1;

     //ulの中に<li>num</li>を追加
      $('ul').append('<li>'+ num +'</li>');
    }

    //モーダルを消す処理(モーダル背景をクリックイベントに指定)
    $('#bg').click(function(){

     //モーダル背景と本体を削除
      $('#bg,#modal').remove();
    });
  });
});

注意するのはモーダルを消す処理に関しては、モーダルを開いているときに指定します。

これで完成しました。完成版は以下のボタンからサンプルページでご確認ください。

完成版モーダルを見てみる


HTML/CSS,jQueryコード

最後にコードをそれぞれ乗せておきます。コピペなどはご自由にどうぞ。(内容自体は超しょぼいですが…)

これまで説明してきた内容を理解していれば改造などもしやすいかと思います。

[HTML]

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
  <p>スイッチ</p>
  <script src="modal.js"></script>
</body>
</html>

[CSS]

#bg {
  position:fixed; /* 階層を上にする */
  width:100%; /* 画面めいっぱい */
  height:100%; /* 画面めいっぱい */
  background:rgba(0,0,0,0.4); /* 背景色 */
}
$modal {
  position:fixed; /* 階層を上にする */
  width:90%; /* モーダルの幅 */
  height:80%; /* モーダルの高さ */
  top:50%; /* bodyの上から50%分ずらす */
  left:50%; /* bodyの左から50%分ずらす */
  transform:translate(-50%,-50%);/* 指定した位置から真ん中にずらす */
  background:#fff; /* モーダルの色 */
  overflow-y:scroll; /* 高さを指定しているので中身が超えた分はスクロールできるように */
}

[jQuery]

$(function(){
  $('p').click(function(){
    //ここにモーダルについて書く

    //bodyの直下に<div id="bg">と<div id="modal">を追加
    $('body').append('<div id="bg">').append('<div id="modal">');

    //for文用に変数numを指定しておく
    var num = 0;

    //モーダルの中にulを生成
    $('#modal').append('<ul>');

    //今回は1~50までのリストを作成
    for(var i =0 ; i <50 ; i++){

     //50まで1ずつ数を追加
      num += 1;

     //ulの中に<li>num</li>を追加
      $('ul').append('<li>'+ num +'</li>');
    }

    //モーダルを消す処理(モーダル背景をクリックイベントに指定)
    $('#bg').click(function(){

     //モーダル背景と本体を削除
      $('#bg,#modal').remove();
    });
  });
});

まとめ

モーダルの基本的な使い方についてはこれで完了しました。ここからモーダルの出現・消える時にアニメーションを付けるなど更に細かく指定していくことが可能です。