【JavaScript】複数のモーダルを設置する方法

今回は、自身のポートフォリオで実装している「複数のモーダルを設置する方法」を解説していきます。

モーダル一つだけというのはよく見かけますが、複数の場合の記事が少なかったので初心者の方でも実装できるように分かりやすく解説していきたいと思います。

また、今回はjQueryは使用しません。
なぜなら、私がJavaScriptの理解を深めたいからです笑
jQueryはとても便利なのですが、やはりベースとなるJavaScriptの理解は重要なので今回はvanilla JSで実装していきます。

処理の流れ・考え方

モーダル表示・非表示の基本的な考えは「classの切り替え」です。

簡単に流れをまとめると....

①ページ読み込み時はモーダル自体が非表示になっている。
②クリックイベントで表示用のクラスが付与されモーダルが画面に現れる。
③「✖」をクリックするとクラスが外され非表示になる

この「クラスの切り替え」をJavaScriptが行っています。

複数のモーダルを設置したい場合には、もう一つ大切な考え方があります。
それが、ボタンとモーダルの「紐づけ」です。

複数モーダルの場合は、モーダルのボタンと表示させるモーダルの紐づけが必要

この紐づけを行わないと、ブラウザがどの要素にclassを付与すればいいのか判断できません。
そこで、「data属性」と呼ばれるカスタムデータ属性を使用します。

data属性とは
グローバル属性 - HTML: HyperText Markup Language | MDN

data属性による紐づけの方法

①モーダルのボタンとモーダルにdata属性を持たせる。
②モーダルのボタンをクリックした時にdata属性の値を取得し、同じdata属性の値を持つモーダル要素を探す。
③data属性の値が一致したモーダルの要素に「is_open」というclassを付与し、モーダルを表示させる。

①について、今回は次のように設定しました。
 モーダルのボタン:data-modal-open="任意の値"
 モーダル:data-modal="任意の値"
 そして、この「任意の値」を同じ値に設定して紐づけます。
 (例. modal-1、modal-2、modal-3)

実際のコード:JavaScriptの解説

実際のコードがこちらです。
今回はHTML/CSSの解説は省きます。


See the Pen
yLOXqwP
by naomi homma (@naomi-homma)
on CodePen.

//modalを出す
const modalWrapOpen = function(e) {
  //クリックしたボタンのdata属性の値を取得
  const dataModalOpen = e.currentTarget.dataset.modalOpen;
  //works_modal_wrapper classが付与されている要素を全て取得
  //取得した全ての要素からdata属性の値が同じ要素を探す
  //取得した要素へis_open classを付与する
  Array.from(document.querySelectorAll('.works_modal_wrapper')).forEach((e, i) => {
    if(e.getAttribute('data-modal') === dataModalOpen){
      e.classList.toggle('is_open');
    }
  })
}

//クリックイベントの定義:複数なのでforEachでイテレートさせる
//works_modal_open classが付与された要素を全て取得
//全ての要素に対してクリックイベントを定義する
Array.from(document.querySelectorAll('.works_modal_open')).forEach((modalOpenElement) => {
  modalOpenElement.addEventListener('click', modalWrapOpen);
})

// modalを消す
const modalCloseAction = function(e) {
  //✖が押された要素の親要素(works_modal_wrapper classを持つ)を取得
  //その要素に対してis_openクラスの切り替えを行う
  const targetModal = e.currentTarget.closest('.works_modal_wrapper');
  targetModal.classList.toggle('is_open')
};

//全ての要素に対してクリックイベントを定義する
Array.from(document.querySelectorAll('.works_modal_close')).forEach((modalCloseElement) => {
  modalCloseElement.addEventListener('click', modalCloseAction)
})

今回は以上になります!

誤りやアドバイスなどありましたらコメント頂けますと嬉しいです。


↓↓私の師匠、もりけんさんの武骨日記。問題集、要チェック

kenjimorita.jp