汎用的に流用できるような、簡易なモーダルを作成してみます。
サンプルコード
まずはモーダルを開くリンク部分です。
data属性で開くモーダルを設定するようにします。
1 2 | < a href = "" data-modal-link = "modal-a" >モーダルAを開く</ a > < a href = "" data-modal-link = "modal-b" >モーダルBを開く</ a > |
data-modal-linkにモーダル名を指定してください。
次にモーダル部分です。
モーダルの要素にdata-modal-contentを設定して、先ほどリンクに設定したモーダル名を入れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | < div class = "modal-bg js-modalclose" ></ div > < div class = "modal" data-modal-content = "modal-a" > < p >モーダルAのコンテンツです。</ p > < button class = "js-modalclose" >閉じる</ button > </ div > <!-- END modal-a --> < div class = "modal" data-modal-content = "modal-b" > < p >モーダルBのコンテンツです。</ p > 〜 略 〜 < p >モーダルBのコンテンツです。</ p > < button class = "js-modalclose" >閉じる</ button > </ div > <!-- END modal-b --> |
.modal-bgがモーダルの背景、.modalがモーダル部分で、背景などに設定している.js-modalcloseはクリックしたらモーダルを閉じるようにJavaScriptで設定します。
次にCSSです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | .modal-bg { display : none ; position : fixed ; top : 0 ; left : 0 ; width : 100% ; height : 100% ; z-index : 9500 ; background : rgba ( 0 , 0 , 0 , 0.75 ); } .modal.is- show { display : block ; } .modal { display : none ; position : fixed ; top : 50% ; left : 50% ; width : 600px ; z-index : 9800 ; background : #ffffff ; transform : translate ( -50% , -50% ); } .modal-bg.is- show { display : block ; } |
.modal-bg、.modal共にデフォルトでは非表示にして、.is-showが付与されると表示されるように設定しています。
最後にJavaScriptです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | $( function () { // モーダルを開く $(document).on( 'click' , '[data-modal-link]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalLink' ); modal_open(target); }); // モーダルを閉じる $( '.js-modalclose' ).on( 'click' , function (e) { e.preventDefault(); modal_close(); }); }); // モーダルを開く function modal_open(target) { $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); $( '.modal-bg' ).addClass( 'is-show' ); } // モーダルを閉じる function modal_close() { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '.modal-bg' ).removeClass( 'is-show' ); } |
クリックしたdata属性の値を使って、対になるモーダルを表示したり閉じたりしています。
モーダルのデモページ
これで基本的な動作は問題ないのですが、モーダルの配置をposition: fixed;で中央配置にしているため、モーダルBのようにモーダルないが長い場合にモーダルの上下が切れてしまいます。
この対応策として、モーダルの高さが画面高さより高い場合、position: absolute;での配置になるようにしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | $( function () { // モーダルを開く $(document).on( 'click' , '[data-modal-link]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalLink' ); modal_open(target); }); // モーダルを閉じる $( '.js-modalclose' ).on( 'click' , function (e) { e.preventDefault(); modal_close(); }); $(window).on( 'resize' , function () { modal_position(); }); }); // モーダルを開く function modal_open(target) { $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); $( '.modal-bg' ).addClass( 'is-show' ); modal_position(); } // モーダルを閉じる function modal_close() { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '.modal-bg' ).removeClass( 'is-show' ); } // モーダルの位置調整 function modal_position() { var $modal = $( '[data-modal-content].is-show' ); if ($modal.length) { var winH = $(window).height(); var modalHeight = $modal.outerHeight(); if (winH <= modalHeight) { var winSctop = $(window).scrollTop(); $modal.css({ position: 'absolute' , top: winSctop + 10, transform: 'translateX(-50%)' }); } else { $modal.removeAttr( 'style' ); } } } |
これでモーダル内が高い場合でも、スクロールですべて表示できるようになりました。
モーダルが長い場合のデモページ
モーダルを切り替える
モーダル内から別のモーダルに切り替えられるようにしてみます。
モーダル内に切り替え用のボタンを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | < div class = "modal-bg js-modalclose" ></ div > < div class = "modal" data-modal-content = "modal-a" > < p >モーダルAのコンテンツです。</ p > < button data-modal-change = "modal-b" >モーダルBへ</ button > < button class = "js-modalclose" >閉じる</ button > </ div > <!-- END modal-a --> < div class = "modal" data-modal-content = "modal-b" > < p >モーダルBのコンテンツです。</ p > 〜 略 〜 < p >モーダルBのコンテンツです。</ p > < button data-modal-change = "modal-a" >モーダルAへ</ button > < button class = "js-modalclose" >閉じる</ button > </ div > <!-- END modal-b --> |
ボタンにdata-modal-changeを設定して、値には開きたいモーダルを指定しています。
JavaScriptに切り替えの処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | $( function () { // モーダルを開く $(document).on( 'click' , '[data-modal-link]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalLink' ); modal_open(target); }); // モーダルを切り替える $(document).on( 'click' , '[data-modal-change]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalChange' ); modal_change(target); }); // モーダルを閉じる $( '.js-modalclose' ).on( 'click' , function (e) { e.preventDefault(); modal_close(); }); $(window).on( 'resize' , function () { modal_position(); }); }); // モーダルを開く function modal_open(target) { $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); $( '.modal-bg' ).addClass( 'is-show' ); modal_position(); } // モーダルを切り替える function modal_change(target) { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); modal_position(); } // モーダルを閉じる function modal_close() { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '.modal-bg' ).removeClass( 'is-show' ); } // モーダルの位置調整 function modal_position() { var $modal = $( '[data-modal-content].is-show' ); if ($modal.length) { var winH = $(window).height(); var modalHeight = $modal.outerHeight(); if (winH <= modalHeight) { var winSctop = $(window).scrollTop(); $modal.css({ position: 'absolute' , top: winSctop + 10, transform: 'translateX(-50%)' }); } else { $modal.removeAttr( 'style' ); } } } |
ページアクセス時にモーダルを表示する
特定のページからアクセスした場合にモーダルを表示するなどできるように、パラメータでモーダルを最初から開けるようにしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | $( function () { // タブのパラメータがついている時の対応 var modalParam = get_modal_param(); if ($( '[data-modal-content="' + modalParam + '"]' ).length > 0) { modal_open(modalParam); } // モーダルを開く $(document).on( 'click' , '[data-modal-link]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalLink' ); modal_open(target); }); // モーダルを切り替える $(document).on( 'click' , '[data-modal-change]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalChange' ); modal_change(target); }); // モーダルを閉じる $( '.js-modalclose' ).on( 'click' , function (e) { e.preventDefault(); modal_close(); }); $(window).on( 'resize' , function () { modal_position(); }); }); // URLのパラメータ取得 function get_modal_param() { var params = []; var param = location.search.substring(1).split( '&' ); for ( var i = 0; i < param.length; i++) { params[i] = param[i].split( '=' ); } for ( var i = 0; i < params.length; i++) { if (params[i][0] === 'modal' && params[i][1] !== undefined) { return params[i][1]; } } return false ; } // モーダルを開く function modal_open(target) { $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); $( '.modal-bg' ).addClass( 'is-show' ); modal_position(); } // モーダルを切り替える function modal_change(target) { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); modal_position(); } // モーダルを閉じる function modal_close() { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '.modal-bg' ).removeClass( 'is-show' ); } // モーダルの位置調整 function modal_position() { var $modal = $( '[data-modal-content].is-show' ); if ($modal.length) { var winH = $(window).height(); var modalHeight = $modal.outerHeight(); if (winH <= modalHeight) { var winSctop = $(window).scrollTop(); $modal.css({ position: 'absolute' , top: winSctop + 10, transform: 'translateX(-50%)' }); } else { $modal.removeAttr( 'style' ); } } } |
33〜46行目でURLのパラメータからモーダルの設定を取得して、4〜6行目で該当のモーダルを開いています。
パラメータでモーダルを開くデモページ
初回ページアクセス時のみモーダルを表示する
最後に初回アクセスのみモーダルを開くようにしてみます。
仕組み的には以前投稿している以下の記事と同じ内容です。
WebStorageで1回目のアクセス時のみモーダルを表示する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | $( function () { // 1回目のアクセスのみモーダルを表示 var firstAccess = 'modal-a' ; if (sessionStorage.getItem(firstAccess) === null ) { sessionStorage.setItem(firstAccess, 'on' ); modal_open(firstAccess); } // タブのパラメータがついている時の対応 var modalParam = get_modal_param(); if ($( '[data-modal-content="' + modalParam + '"]' ).length > 0) { modal_open(modalParam); } // モーダルを開く $(document).on( 'click' , '[data-modal-link]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalLink' ); modal_open(target); }); // モーダルを切り替える $(document).on( 'click' , '[data-modal-change]' , function (e) { e.preventDefault(); var target = $( this ).data( 'modalChange' ); modal_change(target); }); // モーダルを閉じる $( '.js-modalclose' ).on( 'click' , function (e) { e.preventDefault(); modal_close(); }); $(window).on( 'resize' , function () { modal_position(); }); }); // URLのパラメータ取得 function get_modal_param() { var params = []; var param = location.search.substring(1).split( '&' ); for ( var i = 0; i < param.length; i++) { params[i] = param[i].split( '=' ); } for ( var i = 0; i < params.length; i++) { if (params[i][0] === 'modal' && params[i][1] !== undefined) { return params[i][1]; } } return false ; } // モーダルを開く function modal_open(target) { $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); $( '.modal-bg' ).addClass( 'is-show' ); modal_position(); } // モーダルを切り替える function modal_change(target) { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '[data-modal-content = ' + target + ']' ).addClass( 'is-show' ); modal_position(); } // モーダルを閉じる function modal_close() { $( '[data-modal-content]' ).removeClass( 'is-show' ); $( '.modal-bg' ).removeClass( 'is-show' ); } // モーダルの位置調整 function modal_position() { var $modal = $( '[data-modal-content].is-show' ); if ($modal.length) { var winH = $(window).height(); var modalHeight = $modal.outerHeight(); if (winH <= modalHeight) { var winSctop = $(window).scrollTop(); $modal.css({ position: 'absolute' , top: winSctop + 10, transform: 'translateX(-50%)' }); } else { $modal.removeAttr( 'style' ); } } } |
3行目で開くモーダルを指定しています。
これで初回アクセスのみモーダルを開けくようになりました。
初回表示のみモーダルを表示するデモページ
コメントが承認されるまで時間がかかります。