jQuery・表示時にブラウザスクロールを固定するモーダルウィンドウを作りました [IE9一部未対応]
2016/05/30 モーダルウィンドウのスクロール表示可、Esc キー閉じるを実装しました。
シンプルなモーダルウィンドウは leanModal.js が有名で、たまに使っている。
しかし余計なコードが多いのと、モーダルを表示させたときにブラウザスクロールを固定してくれないため自分で作った。
検証済みブラウザとOS
- IE 9~ ※CSS3 transition は IE9不可
- Firefox
- Google Chrome
- Safari
- Windows 7
- OS X Yosemite
- iOS 9
- Android 5
このjQueryで出来ること、出来ないこと
- 出来ること
- インラインHTMLの表示
- 上下左右真ん中に配置する
- モーダルウィンドウとオーバーレイのアニメーションは、全て CSS transition で制御
- モーダルウィンドウを表示させたとき、ブラウザ標準のスクロールを固定
- 閉じる挙動は、オーバーレイクリック、Closeボタンクリック、Escキーを押す、3つを用意
- 出来ないこと
- 前へ / 次へ のギャラリー機能
- モーダルウィンドウの表示をアニメーションではなく、シンプルなフェード表示にする
→ タッチデバイスでブラウザスクロールが出来なくなるバグが解決できないため
要点とコード
- トリガーボタンのリンクに、表示するモーダルウィンドウの id を指定
- モーダルウィンドウ用のHTMLコードを、/body 直前に配置して、ページロード時のチラつきを防止
- opacity と z-index を指定したクラスを、jQueryで追加 / 削除する
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 | <body> <div class="modal"> <a href="#modal-01"><img src="images/ph_001.jpg" width="100"></a> <!-- /.modal --></div> <div class="modal"> <a href="#modal-02"><img src="images/ph_002.jpg" width="100"></a> <!-- /.modal --></div> <div class="modal"> <a href="#modal-03"><img src="images/ph_003.jpg" width="100"></a> <!-- /.modal --></div> <div class="modal"> <a href="#modal-04"><img src="images/ph_004.jpg" width="100"></a> <!-- /.modal --></div> <section id="modal-01" class="modal-window"> <h1>ヘッディング</h1> <img src="images/ph_001.jpg" width="800" height="500"> <p>テキスト</p> <div class="close">× 閉じる</div> <!-- /#modal-01 --></section> <section id="modal-02" class="modal-window"> <h1>ヘッディング</h1> <img src="images/ph_002.jpg" width="800" height="500"> <p>テキスト</p> <div class="close">× 閉じる</div> <!-- /#modal-02 --></section> <section id="modal-03" class="modal-window"> <h1>ヘッディング</h1> <img src="images/ph_003.jpg" width="800" height="500"> <p>テキスト</p> <div class="close">× 閉じる</div> <!-- /#modal-03 --></section> <section id="modal-04" class="modal-window"> <h1>ヘッディング</h1> <img src="images/ph_004.jpg" width="800" height="500"> <p>テキスト</p> <div class="close">× 閉じる</div> <!-- /#modal-04 --></section> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script src="js/simpleModalWindow.js"></script> </body> |
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 | // モーダルウィンドウ .modal-window { width: 800px; height: 90%; overflow: auto; position: fixed; left: 0; right: 0; top: -100%; bottom: 0; z-index: -1; margin: 0 auto; padding: 40px 30px; transition: 0.4s; background: white; @include opacity(0); @include max(830) { width: 100%; height: 80%; padding: 20px; } &.block { top: 0; z-index: 99; margin: auto; @include opacity(1); } .close { width: 200px; text-align: center; cursor: pointer; margin: 0 auto; padding: 10px 0; border: 1px solid #ccc; border-radius: 3px; &:hover { color: white; background: #666; } } } // オーバーレイ #modal-overlay { width: 100%; height: 100%; left: 0; top: 0; position: fixed; z-index: -1; transition: 0.4s; background: rgba(0, 0, 0, 0.5); @include opacity(0); &.block { z-index: 9; @include opacity(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 | /* Simple Modal Window Author: KEITA HIRAI URL: keitahirai.net */ $(function() { $("body").append('<span id="modal-overlay"></span>'); var Window = $(window), hb = $("html, body"), body = $("body"), mw = $(".modal-window"), overlay = $("#modal-overlay"), scrollY; // 開く $(".modal a").click(function() { scrollY = Window.scrollTop(); body.css({ position: "fixed", top: -scrollY }); overlay.addClass("block"); $($(this).attr("href")).addClass("block"); return false; }); // 閉じる $("#modal-overlay, .modal-window .close").click(function() { body.attr("style", ""); hb.prop({scrollTop: scrollY}); overlay.removeClass("block"); mw.removeClass("block"); }); // Esc キーで閉じる Window.keydown(function(e) { if (e.keyCode == 27) { body.attr("style", ""); hb.prop({scrollTop: scrollY}); overlay.removeClass("block"); mw.removeClass("block"); } }); }); |
ベンダープレフィックスがないけど大丈夫?
gulp で自動化しましょう。
メディアクエリのミックスインは過去記事を参照。
Web制作の現場で使うjQueryデザイン入門[改訂新版] (Web Professional Books)
posted with amazlet at 15.08.18
西畑一馬
KADOKAWA/アスキー・メディアワークス
売り上げランキング: 19,488
KADOKAWA/アスキー・メディアワークス
売り上げランキング: 19,488
3コメント
平井圭太様
こんにちは。
モーダルウインドウのソースを使わせていただきました。
探し求めていたのとぴったりで、活用させていただいております。
ありがとうございます。
ひとつ、困ったことがあり、コメントさせていただきました。
モーダルウインドウを一度開く→下までスクロール→閉る→再び開いた時に、
下の方までスクロールした状態で開いてしまうのです。
(「×閉じる」のあたりですので、下の方)
ですので、本当は一番上から読んでほしいものが、途中からの表示になってしまいます。
知識が乏しく、どうしても解決できないので、もしよろしければ、お知恵をお借りできないでしょうか。
宜しくお願いいたします。
ito様
コメント頂きありがとうございました。
一度表示して下までスクロールして閉じる、そして再度表示させたときにスクロールを元に戻すというのは、Ajax等の非同期技術を利用しないと厳しいと思いますねぇ。
もしくは、モーダルを閉じたときにスクロールを上に戻すという、何かしらの独自コードを追加すればできるかもしれませんが、うーんすぐには思いつきません。
申し訳ないです。
ここで一度視点を変えてみるのはいかがでしょう?
サイト利用者にとって「モーダル表示を閉じたあと再度開いて、スクロールが上まで戻っている必要があるか」と。
一般的なWebサイト利用者は、そこまで必要としていないと思います。
平井様
お返事ありがとうございます。
・・・なるほど。。そういう考えもありですね。
レイアウトも含めて、戻らなくても見やすいものを再考してみます。
ありがとうございました。