JavaScript

【サンプル付き】JavaScriptでモーダルウィンドウを表示させる方法

※ 当サイトではアフィリエイト広告を利用しています

【サンプル付き】JavaScriptでモーダルウィンドウを表示させる方法

この記事では「JavaScriptでモーダルウィンドウを表示させる方法」について解説します。

モーダルウィンドウはWebサイトで出てくる頻出の実装の一つなので、実装方法を覚えておきましょう。

この記事を読むと...
  • JavaScriptでモーダルウィンドウを表示させる方法について分かる
  • モーダルウィンドウの実装がコピペでできる様になる

モーダルウィンドウの実装方法

コードは以下になります

See the Pen モーダル実装 by 山中滉大 (@tips-web) on CodePen.

<div class="l-modal" id="js-modal">
    <div class="p-modal">
      <div class="p-modal__contents">
        <div class="p-modalBox__button">
          <button class="c-closeButton" type="button">
            <span></span>
            <span></span>
          </button>
        </div>
        <div class="p-modal__block">
          モーダルのコンテンツ
        </div>
      </div>
    </div>
  </div>
  <section class="p-section">
    セクション
  </section>
  <section class="p-section">
    セクション
  </section>
  <section class="p-section">
    セクション
  </section>
  <section class="p-section">
    セクション
  </section>


  <div class="p-float">
    <button class="c-floatButton" type="button">
      <p class="c-floatButton__text">モーダル<br>ボタン</p>
    </button>
  </div>
.c-closeButton {
  background: #000;
  border-radius: 50%;
  z-index: 10;
  position: relative;
  width: 32px;
  height: 32px;
  border: 1px solid #fff;
 cursor: pointer;
}


.c-closeButton span {
  display: inline-block;
  position: absolute;
  top: 50%;
  left: 0;
  width: 32px;
  height: 2px;
  background: #fff;
}


.c-closeButton span:nth-child(1) {
  transform: rotate(45deg);
}


.c-closeButton span:nth-child(2) {
  transform: rotate(-45deg);
}

.c-floatButton {
  display: block;
  position: relative;
  cursor: pointer;
  background-color: orange;
  padding: 40px;
}

.c-floatButton__text {
  color: #000;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.5;
  text-align: center;
}

.p-section {
  width: 100%;
  height: 200px;
  background-color: lightcyan;
}


.p-section:nth-child(2n) {
  background-color: lightgray;
}


.l-modal {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  height: 100vh;
  width: 100%;
  display: none;
}


.l-modal.is-show {
  display: block;
}

.p-modal {
  padding-top: 100px;
  padding-bottom: 100px;
  position: relative;
  height: inherit;
  padding-left: 28px;
  padding-right: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}


.p-modal::before {
  background-color: #000;
  opacity: .5;
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

}


.p-modal__contents  {
  position: relative;
  width: 100%;
  max-width: 700px;
}


.p-modal__block {
  position: relative;
  background-color: lightblue;
  width: inherit;
  height: 400px;
  z-index: 1;
}


.p-modalBox__button {
  position: absolute;
  top: -16px;
  right: -16px;

}


.p-modalBox__button {
  text-align: center;
}

.p-float {
  z-index: 100;
  position: fixed;
  right: 34px;
  bottom: 66px;
}

document.addEventListener('DOMContentLoaded', function() {

  const modal = document.querySelector('#js-modal');
  const floatModal = document.querySelector('.c-floatButton');
  const modalClose = document.querySelector('.c-closeButton');
  const body = document.querySelector('body');


  if (!modal) {
    return false;
  }


  modalClose.addEventListener('click', function() {
    modal.classList.remove('is-show');
    resetStyles();
  });


  modal.addEventListener('click', function() {
    modal.classList.remove('is-show');
    resetStyles();
  });


  const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
  let pos;
  floatModal.addEventListener('click', function() {
    modal.classList.add('is-show');
    pos = window.pageYOffset || document.documentElement.scrollTop;
    body.style.overflow = 'hidden';
    body.style.position = 'fixed';
    body.style.width = `calc(100% - ${scrollbarWidth}px)`;
    body.style.top = -pos + 'px';
    body.style.marginRight = `${scrollbarWidth}px`;
  });


  function resetStyles() {
    body.style.overflow = 'initial';
    body.style.position = 'static';
    body.style.width = 'initial';
    body.style.marginRight = '0';
    window.scrollTo(0, pos);
  }


});

〇 モーダル非表示画面

モーダル非表示画面

〇 モーダル表示画面

モーダル表示画面

右下のフロートボタンをクリックすると、画面中央にモーダル画面が開きます。モーダルコンテンツの右上にある×ボタン、もしくは背景をクリックするとモーダルが閉じます。

また、モーダルが開いている間、モーダルの背景が上下にスクロールできないように画面を固定させています。

モーダルの作成イメージは以下になります。

モーダル実装

よりコーディングの速度を効率良く上げていきたい方はスニペットを活用するのがいいです。

コードを保管してコピペで対応できる様にしておきましょう。

時短コーディングへの第一歩はこちらから▶︎

HTMLの解説

モーダル部分のHTMLは以下になります。

  <div class="l-modal" id="js-modal">
    <div class="p-modal">
      <div class="p-modal__contents">
        <div class="p-modalBox__button">
          <button class="c-closeButton" type="button">
            <span></span>
            <span></span>
          </button>
        </div>
        <div class="p-modal__block">
          モーダルのコンテンツ
        </div>
      </div>
    </div>
  </div>

モーダル表示時の黒背景は後述するCSSの疑似要素で作成しています。

モーダルを表示した後、モーダルを非表示にするためのボタンもbuttonタグで作成します。

モーダルには、JavaScriptで制御するためにId属性を付与しておきます。

CSSの解説

モーダル表示時の黒背景は以下の疑似要素で作成しています。

.p-modal {
  padding-top: 100px;
  padding-bottom: 100px;
  position: relative;
  height: inherit;
  padding-left: 28px;
  padding-right: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}


.p-modal::before {
  background-color: #000;
  opacity: .5;
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

}

モーダルは初期時様態は非表示、is-showクラスが付与されたとき表示するので、以下のように記述します。

.l-modal {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  height: 100vh;
  width: 100%;


 /* 初期状態は非表示 */
  display: none;
}

/* is-showクラス付与でモーダル表示 */
.l-modal.is-show {
  display: block;
}

JavaScriptの解説

まず以下のように処理に必要な要素を以下のように取得し、変数に格納します。

 const modal = document.querySelector('#js-modal'); // モーダル要素を取得
 const floatModal = document.querySelector('.c-floatButton'); // フロートモーダル要素を取得
 const modalClose = document.querySelector('.c-closeButton'); // モーダルの閉じるボタン要素を取得
 const body = document.querySelector('body'); // body要素を取得

モーダルの閉じるボタン(c-closeButton)をクリックしたら、モーダルに付与されていたis-showクラスを削除する処理を作成します。

modalClose.addEventListener('click', function() {
    modal.classList.remove('is-show');
});

また、モーダルを表示した後、モーダル自身や背景をクリックするとモーダルが閉じるように、上記と同様の処理を作成します。

modal.addEventListener('click', function() {
    modal.classList.remove('is-show'); 
});

右下のフロートボタンをクリックしてモーダルが開く処理は以下になります。

floatModal.addEventListener('click', function() {
    modal.classList.add('is-show'); 
});

モーダルが開いている間、画面をスクロールできないように画面固定にする処理は以下になります。

背景固定時の画面カクつきを抑えるための処理も行います。

以下はスクロールバーの幅を計算したものを、変数に格納しています。

const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; // スクロールバーの幅を計算
let pos;

モーダルを開く処理に以下の記述を追記します。

floatModal.addEventListener('click', function() {
    modal.classList.add('is-show'); // モーダルの表示クラスを追加


    // 以下追記
    pos = window.pageYOffset || document.documentElement.scrollTop; // スクロール位置を保存
    body.style.overflow = 'hidden'; 
    body.style.position = 'fixed'; // body要素を固定位置に設定
    body.style.width = `calc(100% - ${scrollbarWidth}px)`; // スクロールバーの幅を考慮した幅に設定
    body.style.top = -pos + 'px'; // スクロール位置を補正
    body.style.marginRight = `${scrollbarWidth}px`; // スクロールバーの幅分のマージンを設定
  });

上記の記述をすると、モーダル表示時bodyタグにスタイルが適用されます。検証ツールを開くと、bodyタグにスタイルが適用されているのが分かります。

検証ツール

最後に、モーダルを閉じた際に画面固定処理を初期化する処理を作成します。

  function resetStyles() {
    body.style.overflow = 'initial';
    body.style.position = 'static';
    body.style.width = 'initial';
    body.style.marginRight = '0';
    window.scrollTo(0, pos);
  }

作成した関数は、以下のようにモーダルを閉じる処理にそれぞれ追記していきます。

  modalClose.addEventListener('click', function () {
    modal.classList.remove('is-show');


    // 初期化処理を追記
    resetStyles(); // スタイルをリセット
  });


  modal.addEventListener('click', function () {
    modal.classList.remove('is-show');

    // 初期化処理を追記
    resetStyles(); // スタイルをリセット
  });

まとめ

JavaScriptでモーダルウィンドウを表示させる方法について解説しました。

一つ一つ何の処理が必要なのか考えながら実装していきましょう。

  • この記事を書いた人
アバター画像

こうだい

兼業でWeb制作事業|31歳|本業畑違いで知識0から学習開始→1年目で初案件獲得→2年で月の兼業受注金額70万円達成|4年目で100万円達成|兼業でも稼げることを確信|Web制作メンター|制作費無料のホームページ制作事業運営|コーディング・ホームページ制作についてお気軽にお問い合わせください

-JavaScript
-,