【モーダルウィンドウ】プラグインを利用せずjQueryで実装

モーダルウィンドウをプラグインを利用せず、html、CSS、jQueryの記述で実装します。レスポンシブ対応です。モーダルウィンドウは画面中央に表示させ、bodyのスクロールバーは非表示にします。

サンプルデモはこちら

まず、htmlのコードです。
モーダルウィンドウのdivタグにidを付与し、モーダルウィンドウを開くリンクのaタグのdata-target属性で対象のidを指定しています。

<ul>
	<li><a data-target="category01" class="modal-open">モーダルウィンドウ01</a></li>
	<li><a data-target="category02" class="modal-open">モーダルウィンドウ02</a></li>
	<li><a data-target="category03" class="modal-open">モーダルウィンドウ03</a></li>
</ul>
<div id="modal_wrap">
	<div id="category01" class="modal-content">
		<div class="modal-header">
			<p class="modal-title">モーダルウィンドウ01:タイトル</p>
			<button type="button" class="close modal-close">×</button>
		</div>
		<div class="modal-body">
			<p>モーダルウィンドウ01:ダミーテキストダミーテキストダミーテキスト</p>
		</div>
		<div class="modal-footer">
			<button type="button" class="btn modal-close">閉じる</button>
		</div>
	</div>
	<div id="category02" class="modal-content">
		<div class="modal-header">
			<p class="modal-title">モーダルウィンドウ02:タイトル</p>
			<button type="button" class="close modal-close">×</button>
		</div>
		<div class="modal-body">
			<p>モーダルウィンドウ02:ダミーテキストダミーテキストダミーテキスト</p>
		</div>
		<div class="modal-footer">
			<button type="button" class="btn modal-close">閉じる</button>
		</div>
	</div>
	<div id="category03" class="modal-content">
		<div class="modal-header">
			<p class="modal-title">モーダルウィンドウ03:タイトル</p>
			<button type="button" class="close modal-close">×</button>
		</div>
		<div class="modal-body">
			<p>モーダルウィンドウ03:ダミーテキストダミーテキストダミーテキスト</p>
		</div>
		<div class="modal-footer">
			<button type="button" class="btn modal-close">閉じる</button>
		</div>
	</div>
</div>

続いてCSSのコードです。
jQueryで動的に追加するオーバーレイにCSSを記述します。モーダルウィンドウよりも後ろに重なるようにz-index: 1にします。そしてモーダルウィンドウはz-index: 2にします。また、オーバーレイとモーダルウィンドウはposition: fixedにします。そしてモーダルウィンドウの方はtopもleftも指定しません。画面中央に表示されるように、表示位置はjQueryで動的に指定します。

.modal-open {
	text-decoration: underline;
	cursor: pointer;
}
.modal-overlay {
	z-index: 1;
	display: none;
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 120%;
	background: rgba(0, 0, 0, 0.5);
}
.modal-content {
	z-index: 2;
	display: none;
	position: fixed;
	max-width: 500px;
	margin: 0 15px;
	border: 1px solid rgba(0, 0, 0, 0.2);
	border-radius: 0.3rem;
	background: #fff;
}
.modal-header {
	display: flex;
	justify-content: space-between;
	padding: 1rem;
	border-bottom: 1px solid #dee2e6;
}
.modal-header .close {
	cursor: pointer;
	background: transparent;
	border: 0;
	font-size: 1.5rem;
	font-weight: 700;
	line-height: 1;
	color: #000;
	outline: none;
	opacity: .5;
}
.modal-header .close:hover {
	opacity: .75;
}
.modal-body {
	padding: 1rem;
}
.modal-footer {
	display: flex;
	justify-content: flex-end;
	padding: 1rem;
	border-top: 1px solid #dee2e6;
}
.btn {
	display: inline-block;
	font-weight: 400;
	color: #fff;
	text-align: center;
	vertical-align: middle;
	user-select: none;
	outline: none;
	background: #6c757d;
	border: 1px solid #6c757d;
	padding: 0.375rem 0.75rem;
	font-size: 1rem;
	line-height: 1.5;
	border-radius: 0.25rem;
	transition: 0.15s;
	cursor: pointer;
}
.btn:hover {
	background: #5a6268;
	border-color: #545b62;
	opacity: 0.7;
	transition: 0.7s;
}

最後にjQueryのコードです。
モーダルウィンドウを開くリンクをクリックした時の動作は、以下の順番で処理します。
1. bodyのスクロールバーを非表示
2. 非表示にしたbodyのスクロールバーの幅を計算し、その幅の分だけページの余白を調整
※bodyのスクロールバーがない場合はページの余白調整をしない
3. オーバーレイのdivタグをhtmlに追加しフェードインで表示
4. モーダルウィンドウを開くリンクのaタグに設定したdata-target属性から、対象のモーダルウィンドウのdivタグに付与したidを取得し、変数modalに格納
5. モーダルウィンドウが画面中央に表示されるようにCSSでtopとleftを指定
6. モーダルウィンドウをフェードインで表示

モーダルウィンドウを閉じるボタンもしくはオーバーレイをクリックした時の動作は、以下の順番で処理します。
1. bodyのスクロールバーを表示
2. bodyのスクロールバーの幅の分だけ調整していたページの余白を0に
3. モーダルウィンドウを非表示
4. オーバーレイのdivタグをフェードアウトで非表示にしhtmlから削除

$(function() {
	$('.modal-open').click(function() {
		clientWidth = $('body').width();
		$('body').css({ 'overflow':'hidden' });
		clientWidthNoScrollBar = $('body').width();
		diff = clientWidthNoScrollBar - clientWidth;
		if (diff > 0) {
			$('body').css({ 'padding-right':diff });
		}
		$('#modal_wrap').append('<div class="modal-overlay"></div>');
		$('.modal-overlay').fadeIn();
		var modal = '#' + $(this).attr('data-target');
		modalResize();
		$(modal).fadeIn();

		$('.modal-overlay, .modal-close').off().click(function() {
			$('body').css({ 'overflow':'auto' });
			$('body').css({ 'padding-right':'0' });
			$(modal).hide();
			$('.modal-overlay').fadeOut('fast', function() {
				$('.modal-overlay').remove();
			});
		});

		$(window).on('resize', function() {
			modalResize();
		});

		function modalResize() {
			var w = $(window).width();
			var h = $(window).height();
			var x = (w - $(modal).outerWidth(true)) / 2;
			var y = (h - $(modal).outerHeight(true)) / 2;
			$(modal).css({'left': x + 'px','top': y + 'px'});
		}
	});
});
タイトルとURLをコピーしました