Sponsored Link
モーダルウィンドウの実装
モーダルウィンドウって?
簡単に言うと、大元のページとは別に浮かぶ子ウィンドウ。
初回アクセス時に注意書きが出てくるとか、
ページ上のボタンを押したら出てくるとか、そういうやつ。
詳しくは、Let’s wikipedia
作り方
モーダルウィンドウの導線(表示するスイッチ)はjQuery
レイアウトについてはCSSで作成する。
<h2><a id="modal-open" class="button-link">クリックするとモーダルウィンドウを開きます。</a></h2>
<div id="modal-content">
<p>ここがモーダルウィンドウの中身です</p>
<p><a id="modal-close" class="button-link">クリックするとモーダルウィンドウを閉じます</a></p>
</div>
CSSでモーダルウィンドウの形状や位置などを設定します。
/*------------------
本体
------------------*/
#modal-content {
background: #fff; /* モーダルウィンドウのbackground */
border: 2px solid #aaa; /* モーダルウィンドウのborder */
width: 50%; /* モーダルウィンドウの幅 */
z-index: 2; /* オーバーレイより高い数値に設定 */
}
/*------------------
背景(オーバーレイ)
------------------*/
#modal-overlay {
background-color:
rgba(0, 0, 0, 0.75); /* 背景のbackground */
top: 0; /* 背景の固定位置 */
left: 0; /* 背景の固定位置 */
height: 120%; /* 背景の高さ */
width: 100%; /* 背景の幅 */
z-index: 1; /* モーダルウィンドウより低い数値に設定 */
}
/*------------------
共通パーツ
------------------*/
#modal-content,
#modal-overlay {
display: none; /* 通常時は非表示 */
position: fixed; /* ウィンドウの固定 */
}
$(function() {
$("#modal-open").on("click", function() {
//------------------------------------------------------------------
// キーボード操作などにより、オーバーレイが多重起動するのを防止する
//------------------------------------------------------------------
// ボタンからフォーカスを外す
$(this).blur();
// 新しくモーダルウィンドウを起動しない
if($("#modal-overlay")[0]) return false;
// 現在のモーダルウィンドウを削除して新しく起動する
// if($("#modal-overlay")[0]) $("#modal-overlay").remove();
// オーバーレイ用のHTMLコードを、[body]内の最後に生成する
$("body").append('<div id="modal-overlay"></div>');
// #modal-overlay 及び #modalcontent をフェードインさせる
$("#modal-overlay, #modal-content").fadeIn("slow");
centeringModalSyncer();
//------------------------------------------------------------------
// #modal-overlay または #modal-close のクリック時に実行する処理
//------------------------------------------------------------------
$("#modal-overlay, #modal-close").off().on("click", function() {
// #modal-overlay 及び #modal-close をフェードアウトする
$("#modal-content, #modal-overlay").fadeOut("slow", function() {
// フェードアウト後、 #modal-overlay をHTML(DOM)上から削除
$("#modal-overlay").remove();
});
});
//------------------------------------------------------------------
// リサイズ操作をした際に、モーダルウィンドウを中央寄せにする
//------------------------------------------------------------------
// Case.1 リサイズ操作の度に実行する場合
// $(window).resize(centeringModalSyncer);
// Case.2 リサイズ操作が終了したときのみ実行する場合
var timer = false;
$(window).resize(function() {
if (timer !== false) clearTimeout(timer);
timer = setTimeout(function() {
centeringModalSyncer();
}, 200);
});
//------------------------------------------------------------------
// モーダルウィンドウを中央寄せする関数
//------------------------------------------------------------------
function centeringModalSyncer() {
// 画面(ウィンドウ)の幅、高さを取得
var w = $(window).width();
var h = window.innerHeight;
// コンテンツ(#modal-content)の幅、高さを取得
// Case.1 margin 含める場合
// var cw = $("#modal-content").outerWidth(true);
// var ch = $("#modal-content").outerHeight(true);
// Case.2 margin 含めない場合
var cw = $("#modal-content").outerWidth();
var ch = $("#modal-content").outerHeight();
// #modal-content を真ん中に配置するのに、左端と上部から何ピクセル離せばいいか?を計算してCSSのポジションを設定する
// Case.1 left と top で変数を分ける
/*
var pxleft = ((w - cw) / 2);
var pxtop = ((h - ch) / 2);
$("#modal-content").css({
"left":pxleft + "px",
"top":pxtop + "px"
});
*/
// Case.2 プロパティを持たせて一つの変数に纏める
var p_prop = {
left:((w - cw) / 2),
top:((h - ch) / 2)
};
$("#modal-content").css(p_prop);
}
});
});
リサイズ処理について
$(window).resize(centeringModalSyncer);
と、やってもいいけれどブラウザ負荷とか色々な不具合が起こるかも知れないので、
setTimeoutで処理する方法をとる。
リサイズ処理について
outerWidth outerHeightの引数について
通常でpadding + border を含む数値を取得します。
引数に True を入れると、 margin を含む数値を取得します。
幅と高さを取得 / 設定する方法
CSS オーバーレイの height と jQuery 変数 h について
CSS のオーバーレイで指定している、
height: 120%;
について、スマホ(iPhone)対策となります。
iPhoneではスクロールすると上下のナビバーが縮む(隠れる)ため、
オーバーレイが画面の高さより小さくなってしまう不具合が起こります。
そのため、少し大きめの120%で値を指定をします。
jQueryの変数 h について、
スマホ(iPhone)上で、$(window).height()
で取得できる高さは「上下のナビバーのスペースだけ縮んだ分の高さ」です。
また、$(window).height()
で取得できる高さは、微妙に少ない方向にズレることがあるそうです。
そのため、正確な高さを取得したい場合は、jQueryではなく、JavaScript本来の記述 window.innerHeight;
で取得するのがいいと思います。