プラグインを使わずにJQueryとdata関数を用いてスクロールするモーダルウィンドウを作る方法を紹介します。
そもそもモーダル(ウィンドウ)とは?
モーダルとは以下画像のように「メインの画面に被るようにして表示される小さなウィンドウ」の一つを指します。(他にはポップアップとダイアログがある。違いについてはこちらを参照)
出典:【jQuery】スクロールできるモーダルウィンドウの作り方【初級編】すんすけブログ
https://sunsukeblog.com/jquery_modalwindow
モーダルの基本構造はメインのbodyを覆うようにモーダルの背景(オーバーレイと呼ばれたりする)が覆い被さり、その上にモーダルの本体が乗っている、という形になっています。
オーバーレイ(overlay)はover(何かを全体的に覆っている)+ lay(〜を横たえる、横に置く)という意味で、「薄い膜のようなものをふわっと広げて敷いてる目隠し」のようなイメージです。bodyに薄く目隠しをすることで、小ウィンドウに注目させる意図があります。
モーダルウィンドウが出ている時というのは「小ウィンドウの操作しかできない状態」なのがモーダルの一番の特徴です。
その背景としてこちらのサイトで説明されてるのがとても分かりやすいです。
「モーダル(modal)」は「モードレス(modeless)」と対になる言葉です。それぞれ、「モードがある状態」と、「モードが無い状態」を表します。
「モード」は、例えば「入力モード」「編集モード」などの例を思い浮かべていただければわかりやすいかと思いますが、何か特定のことをするための「形式・様式」のことです。
逆にいうと、その特定のこと以外をすることに制限を加えることを意味します。「編集モード」の時は、思い起こすと、編集以外のことはできないイメージがあるかと思います。
【初心者向け】モーダル・ポップアップ・ダイアログの意味の違い 株式会社リラクス様ブログより
https://rilaks.jp/blog/ui/modal-pop-up-dialog/
ということで、モーダルは「操作の制限が加わった制御状態」なのですが、逆に言えばそこまでしてユーザーの操作に制御を加えるのは「そのタイミングでユーザーに集中的に見て欲しいものがあるから」とも言えます。
なのでユーザーに損失が起こる可能性のあるような場面、例えば「アカウントやファイルの削除」といった「後戻りできない不可逆性のある行為」をする直前で使われたり、ポリシー変更やシステム変更など「重要だけどユーザーが自主的に取得しないような情報をお知らせしたいような場面」で使われるのにふさわしい一方で、求めもしないのに出てきたり(サブスクのお願いとか)、特にスマホで出てくる(アプリのDLを促したり)と画面を占領してしまいユーザーをイライラさせがちなので、作り手の配慮が求められる機能だとも言えると思います。
完成形のデモと作成手順
最終的に完成を目指すモーダルのデモを載せておきます。
このモーダルを作る手順としては
- クリックした時にイベントが発生するボタンの作成
- モーダルウィンドウとオーバーレイをdisplayで非表示にしておく
- z-indexでモーダルウィンドウが一番手前、そのすぐ下にオーバーレイが重なるように数値を指定する
- クリックというイベントが発生したら表示・非表示されるようJQueryで制御する
を主に意識すると作成しやすいと思います。
HTML
<!-- モーダルを開くボタン -->
<div class="modal-open"><a>開く</a></div>
<!-- モーダルウィンドウ -->
<div class="modal-window">
<!-- 閉じるボタン -->
<div class="modal-close"><a>閉じる</a></div>
</div>
<!-- オーバーレイ -->
<div id="modal-overlay"></div>
ポイント
- まずはクリックしたらモーダルウィンドウとオーバーレイが開くボタン、そして閉じるボタンを作成します。閉じるボタンはモーダルウィンドウの子要素にします。
- またオーバーレイとモーダルウィンドウそのものも同時に作成しておきます。
CSS(モーダルとオーバーレイ)
.modal-window {
display: none;
width: 300px;
height: 300px;
padding: 60px;
background: #ffffff;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
}
#modal-overlay {
display: none;
width: 100%;
height: 100%;
background: #000000;
z-index: 99;
position: fixed;
top: 0;
left: 0;
opacity: 0.3;
}
ポイント
- モーダルウィンドウとオーバーレイのdisplayをnoneにして最初は非表示にします。
- モーダルウィンドウは画面中央に表示されるようにしています。
- オーバーレイは画面左上に固定し画面全体に表示されるように幅と高さを100%に指定しています。
- z-indexでモーダルウィンドウがオーバーレイよりも手前に来るように数値を設定しています(モーダルウィンドウが100でオーバーレイが99)。z-indexとはz軸方向のインデックス(索引)順を指定するものです。数値が高いほど手前に来ます。
CSS(ボタンの装飾)
.modal-open {
a {
display: block;
margin:0 auto;
width: 176px;
height: 48px;
line-height: 48px;
border-radius: 8px;
background: #3f51b5;
box-shadow: 0 3px 6px #00000029;
color: #fff;
text-align:center;
cursor: pointer;
}
}
.modal-close {
a {
position:absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
width: 176px;
height: 48px;
line-height: 48px;
border-radius: 8px;
background: #c46e35;
box-shadow: 0 3px 6px #00000029;
color: #fff;
text-align:center;
cursor: pointer;
}
}
ポイント
- 開くボタンと閉じるボタンの装飾をしておきます。ボタンの装飾については完全にお好みです。
JQuery
jQuery(".modal-open").on("click", function () {
$(".modal-window, #modal-overlay").fadeIn();
return false;
});
jQuery(".modal-close").on("click", function () {
$(".modal-window, #modal-overlay").fadeOut();
return false;
});
ポイント
- modal-openをクリックしたら、fadeInメソッドにてモーダルウィンドウとオーバーレイがフワッと表示されるようにします。
- そしてmodal-closeをクリックしたら、今度はfadeOutメソッドにてモーダルウィンドウとオーバーレイがフワッと非表示になるようにしています。
ここまでで作ったモーダルがこちらです。
ここまででモーダルウィンドウの基本的な構造と、JQueryでモーダルを制御する方法について学びました。ここからはモーダルウィンドウ内でスクロールさせる方法とdata属性の使い方について学びます。
モーダルウィンドウ内でスクロールさせる方法
モーダルでスクロールする利用シーンを想定し架空の利用規約を追記します。
<!-- モーダルウィンドウ -->
<div class="modal-window">
<!-- 以下に架空の利用規約を追加 -->
<div class="modal-content">
<h3 class="modal__main-title">利用規約</h3>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
</div>
<!-- 閉じるボタン -->
<div class="modal-close""><a>閉じる</a></div>
</div>
<!-- オーバーレイ -->
<div id="modal-overlay""></div>
CSS
CSSのポイントはoverflow: scroll;とheightで高さを持たせることです。これだけでスクロールするようになります。overflowは必ずコンテンツに対して指定するようにします。間違ってもmodal本体には設定しないように注意です。
.modal-content {
text-align: center;
height: 200px;
width: 200px;
overflow: scroll;
margin: 0 auto;
}
.modal__main-title {
font-weight: 700;
font-size: 24px;
}
.modal__sub-title {
font-size: 20px;
font-weight: 700;
&:nth-child(n + 2) {
margin-top: 40px;
}
}
これで出来たモーダルが以下になります。
data関数を使う
data関数を使います。
data関数を使うと何がいいの?というと、一番は保守性が良くなるという利点があります。
使い方等についてはこちらの記事を参考にしてみて下さい。
JQuery
jQuery(".modal-open").on("click", function (e) {
e.preventDefault();
let target = $(this).data('target');
$(target).fadeIn();
return false;
});
jQuery(".modal-close, #modal-overlay").on("click", function (e) {
e.preventDefault();
let target = $(".modal-close").data('target');
$(target).fadeOut();
return false;
});
解説
function (e) {e.preventDefault();
function (e) {e.preventDefault();でaタグ本来の動作を停止しています。
let target = $(this).data('target');
変数targetにdata属性の情報(target-modal)が代入されています。thisというのはイベントが発生した要素を指すため、このthisはクリックというイベントが発生している.modal-openを指します。
data(‘target’)のtargetをなぜ入力しているのか?ですが、仮に複数の属性値が存在した場合、例えばdata-age=”30″, data-name=”taro”, data-tel=”080-3333-1111″とあった場合にdata(‘age’)と指定してあげれば、ageの値30のみ取得ができますが、data()の場合だと全ての値(”30″, “taro”, “080-3333-1111″)を取得してしまうことになります。
今回はdata属性はtargetのみしか記述してないですが、仮に後々に新たなdata属性を作成した時に、data()のままだと、全てのdata属性の値を取得してしまうことになる為、data(‘target’)と指定しているわけです。
HTML
<!-- モーダルを開くボタン -->
<div class="modal-open" data-target=".target-modal"><a>開く</a></div>
<!-- モーダルウィンドウ -->
<div class="modal-window target-modal">
<!-- 架空の利用規約 -->
<div class="modal-content">
<h3 class="modal__main-title">利用規約</h3>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
<div class="modal__sub-title">タイトル</div>
<p class="modal__text">テキスト</p>
</div>
<!-- 閉じるボタン -->
<div class="modal-close" data-target=".target-modal"><a>閉じる</a></div>
</div>
<!-- オーバーレイ -->
<div id="modal-overlay" class="target-modal"></div>
解説
<!-- モーダルを開くボタン -->
<div class="modal-open" data-target=".target-modal"><a>開く</a></div>
<!-- 閉じるボタン -->
<div class="modal-close" data-target=".target-modal"><a>閉じる</a></div>
</div>
開くボタンと閉じるボタンにそれぞれdata-target=”.target-modal”を追加しています。
data-〇〇というのはdata属性とかカスタム属性とか呼ばれますが、言ってみれば単なる属性情報です。属性情報というのは人間で言うなら名前や身長、体重、出身地、国籍、職業などのその人個人に付帯する情報で、属性情報を知ることでその人が何者かが分かります。
人間同様に要素に属性情報がないと、要素の特定が難しいです。今回もdiv要素にdata属性という属性情報を加えてあげることで、その要素に手を加えたくなった時に便利なわけです。
<!-- モーダルウィンドウ -->
<div class="modal-window target-modal">
<!-- オーバーレイ -->
<div id="modal-overlay" class="target-modal"></div>
モーダルウィンドウとオーバーレイにtarget-modalという名のクラス属性を追加します。
data属性の中身と同一名にすることで、target変数と一致し、fadeIn(), fadeOut()メソッドが実行されるわけです。
これで作成したモーダルが冒頭のデモと同じものになりました。
参考になれば嬉しいです。
コメント