ピュアJavaScriptで
モーダル

ピュアJavaScriptでモーダル_メインビジュアル

プログラム概要

1つのサイトにて、似たようなモーダルを何度か実装することがありました。
ライブラリを使うほどではないものの、それぞれの機能が若干異なるために実装に手間が掛かっていました。そこで、必要となった機能を一通りまとめたものを、ピュアJavaScriptで制作しました。
オプションの指定で各要素の自動生成の有無や、スライド対応などなど細かく調整できます。

機能の紹介

  • モーダルの枠組みを自動生成するか否か
  • モーダル下部のボタンを自動生成するか否か
  • モーダルの左右にフロートするボタンを自動生成するか否か
  • スライドを有効にするか否か
  • スライドをループさせるか否か
  • モーダルのスクロールバーの表示位置の指定
  • モーダルを開いた状態でのスクロールに対する処理の指定
モーダルのオプション一覧
openBtnClassName モーダルを開くボタンのクラス名
[str] [No property]
初期値: [No property (‘modal-open_btn’)]
browserVerticalMargin モーダルの高さがブラウザの高さより高い場合に、モーダルをスクロール可能にした際の上下の余白の合算を指定する。
[number] [No property]
初期値: [No property (120)]
outsideCloseBlockHeight モーダルのスクロール方法が [‘outside’] の場合、モーダルの下に見えないクリック用の要素が追加される。この要素に対して、モーダルの下の余白と同じ高さを指定すると、その領域がクリックできるようになり、モーダルを閉じれるようになる。
[number] [No property]
初期値: [No property (60)]
skipCheckExists 要素の存在チェックのスキップ
[true] [false] [No property]
初期値: [No property (チェックする)]
create 要素の自動生成のプロパティ
modalInner モーダルに必要な要素(ボタンを除く)を自動・手動どちらで行うか ※必須
[‘auto’] [‘manual’]
normalBtn モーダルの下端のボタンを自動・手動で生成または生成しない
[‘auto’] [‘manual’] [null] [No property]
初期値: [No property (生成しない)]
floatBtn モーダルのフロートボタンを自動・手動で生成または生成しない
[‘auto’] [‘manual’] [null] [No property]
初期値: [No property (生成しない)]
slide スライド機能に関するプロパティ
use スライド機能を付与するか否か
[true] [false] [No property]
初期値: [No property (利用しない)]
loop スライド切り替えをループさせるか否か
[true] [false] [No property]
初期値: [No property (利用しない)]
scroll スクロールに関するプロパティ
scrollBar モーダルの高さがブラウザの高さを超える場合に、スクロールバーを表示する位置を指定する。
[‘inside’] [‘outside’] [No property]
初期値: [No property (insideスクロール)]
addFunction モーダルを開いた状態でのスクロールに対する処理の選択。
スクロールの無効化・スクロールでモーダルを閉じる・何も追加しないから選択する。
[‘stopBodyScroll’] [‘closeBodyScroll’] [null] [No property]
初期値: [No property (何も追加しない)]

オプション記入例

var setModalOptions = function() {
  var modalOptions = {
    browserVerticalMargin: 120,
    outsideCloseBlockHeight: 60,
    openBtnClassName: 'modal-open_btn',
    skipCheckExists: false,
    create: {
      modalInner: 'auto',
      normalBtn: 'auto',
      floatBtn: 'auto',
    },
    slide: {
      use: true,
      loop: false,
    },
    scroll: {
      scrollBar: 'inside',
      addFunction: 'stopBodyScroll',
    }
  };
  modal(modalOptions);
};
setModalOptions();

モーダルに必要な要素(ボタンを除く)の自動生成について

モーダルの一番外にあたる [modal-container] と、コンテンツを格納する [modal-content] の2つを自分で用意します。

<!-- モーダル -->
<div id="ID名" class="modal-container">
  <div class="modal-content">
    <!-- コンテンツ -->
  </div>
</div>

モーダルを開くボタンとモーダルの紐づけ

モーダルを開くボタンのカスタムデータ属性 [data-modal-id] に、紐づけたいモーダルのID名を指定します。

<!-- モーダルを開くボタン -->
<button type="button" data-modal-id="モーダルのID名">モーダルを開く</button>

<!-- モーダル -->
<div id="ID名" class="modal-container">
  <div class="modal-content">
    <!-- コンテンツ -->
  </div>
</div>

モーダルのグループ化

グループ化したいモーダルに対して、カスタムデータ属性の [data-modal-group] で同名を指定します。
グループ化されたモーダルは、スライド機能の対象となりますので、スライドボタンを設置してください。

<!-- モーダル -->
<div id="ID名" class="modal-container" data-modal-group="グループ名">
  <div class="modal-content">
    <!-- コンテンツ -->
  </div>
</div>

モーダルに常時スクロールバーを表示させる

通常は、モーダルの高さがブラウザの高さよりも高い場合に、スクロールバーが自動で設置されます。
モーダル内にアコーディオンメニューのような、高さが変化するコンテンツがある場合、モーダルを開いた後に高さが変化しても、補足はしていませんので、コンテンツを表示しきれない可能性があります。
このような場合は、カスタムデータ属性の [data-modal-scroll] に [always] を指定することで、常時スクロールバーが設置されるようになります。

<!-- モーダル -->
<div id="ID名" class="modal-container" data-modal-scroll="always">
  <div class="modal-content">
    <!-- コンテンツ -->
  </div>
</div>

制作について

制作目的
モーダルを必要とするページが結構な数存在する一方で、機能が細かく異なっており、都度調整が必要でしたので、諸々をまとめて組み込んでしまおうと思い制作しました。
工夫したところ
不要なJavaScriptのイベントを削除するように心掛けて制作しました。

具体的には、モーダルを開くボタンには常時クリックイベントが登録されています。
そして、モーダルを開いたタイミングで、モーダル単体、またはグループ化されたモーダルの、各種ボタンに対してクリックベントが登録されます。
モーダルを閉じると、各種ボタンのクリックイベントは不要となりますので、全て削除するようにプログラムを組みました。

モーダルを開いていない場合に、モーダルのボタンを押すことはできませんので、不要なイベントを削除することで、パフォーマンスの低下防止に努めました。
開発環境
フロントエンド
言語: HTML5 CSS3, JavaScript
エディタ
Visual Studio Code
製作期間
2020年5月~2020年6月 (1カ月)