Enterキーによるモーダルウィンドウの重複と消せないバグを解消する方法

モーダルウィンドウ

解説:

 modal.htmlで見られた以下のようなバグは、以下の modal0.js のように、modal.js から return false; を取り除くことで解消される
 modal.js から return false; を取り除くことが許されないのなら、return false; の前に $('.modal').blur(); を入れることでも解消されるmodal1.html)。

↓modal.htmlで生じたバグの解説↓

 上の「モーダルウィンドウ表示」をクリックするとモーダルウィンドウが表示される。
 モーダルウィンドウの「閉じる」をクリックするとモーダルウィンドウが閉じる。
 一般的には周辺のグレーの部分をクリックしてもモーダルウィンドウが閉じるが、私がバグに遭遇したサイトは閉じるボタンをクリックしなければ閉じなかったので、同じようにした。
 モーダルウィンドウを表示して閉じる作業は、通常は何度でも繰り返せる。
 しかし、モーダルウィンドウが表示された直後にキーボードの「Enter」を叩くと、さらにモーダルウィンドウが表示される。ただし、「閉じる」のあるメインの部分は重複して表示されず、外側のグレーの部分だけが重複される。透明度が落ちたことが確認できる。「Enter」を叩き続けると、真っ黒になる。
 さて、そのように「Enter」キーでモーダルウィンドウが重複された状態でモーダルウィンドウの「閉じる」をクリックすると、「閉じる」のあるメインの部分は消えるが、外側のグレーの部分は消えない。その結果、その下のウインドウにアクセスできない。
 「閉じる」をクリックした時、外側のグレーの部分は一つづつ消えて、「閉じる」のあるメインの部分(実際はその下敷きのウインドウ)は一度に消えるようにしてある。
 そもそも、「Enter」を叩くと同じIDのブロックが重複してしまうが、IDは一つのブロックにしか許されない。IDが一つのブロックにしか存在しないことが前提なので、IDを指定して「.remove()」を行った時、一つづつしか消えないのだと思われる。それに対し、「閉じる」のあるメインの部分はclassを指定して「.remove()」を行ったので、一度に消すことができた。また、「.remove()」で一つづつ消すとき、上の行に存在するブロックから消えるようである。「Enter」キーを叩いてモーダルウィンドウが重複した場合、肝心の「閉じる」のあるメインの部分は一番の下のブロックに存在する。従って、IDを指定して「.remove()」を行い一つづつ消すと、「閉じる」のあるメインの部分は最後まで残る。

オリジナルソース:

改造したソース:

modal0.html(オリジナルは jquery_simple-modal-window.htm )

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Enterキーによるモーダルウィンドウの重複と消せないバグ</title>
<link rel="stylesheet" href="modal.css" media="all">
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.js"></script>
<script src="modal0.js"></script>
</head>
<body>

<h1>Enterキーによるモーダルウィンドウの重複と消せないバグ</h1>

<ul>
<li><a class="modal" href="#box1">モーダルウィンドウ表示</a></li>
</ul>

<div id="box1">
<p>モーダルウィンドウ</p>
<p class="modal-close"><a href="#">閉じる</a></p>
</div>

<h2>解説:</h2>
(以下略)
</body>
</html>

modal.css(オリジナルは jquery_simple-modal-window.htm 内)

@charset "utf-8";

#box1 {
    display: none;
    background-color: #ffffff;
    padding: 20px;
    width: 200px;
    text-align:center;
}
.link {
    text-align: center;
}
.modal-close {
    margin-top: 1em;
    text-align: center;
}
#modal-win {
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, .50);
    position: fixed;
    top: 0;
    left: 0;
    z-index: 100;
}
#modal-win-inner {
    box-shadow: 0 0 5px rgba(0, 0, 0, .25);
    margin: 0 auto;
    position: relative;
    z-index: 101;
    border-radius: 10px;
}
#modal-win-inner {
    position: fixed;
    width: 200px;
    top: 50%;
    right: 50%;
}
#modal-win-inner > * {
    border-radius: 10px;
}

modal0.js(オリジナルは jquery.simplemodalwindow.js )

(function($){

    $(function(){
        simpleModalWindow();
    });

    function simpleModalWindow(){

        var sp = 500;    //アニメーション速度
        var win = $(window);
        var body = $('body');

        //モーダルウィンドウ表示クリックイベント
        $(document).on('click', '.modal', function(){
            var py = win.scrollTop();
            var wh = win.height();
            var self = $(this);
            var link = self.attr('href');
            //var mWin = $('<div id="modal-win"><div id="modal-win-inner"></div></div>');
            //var mInner = mWin.find('#modal-win-inner');
                var mWin = $('<div id="modal-win"></div>');
                var mInner = $('<div id="modal-win-inner" class="inner"></div>');
            mInner.css('opacity', '0');
            body.append(mWin);
                body.append(mInner);
            var contents = $(link);
            mInner.append(contents);
            contents.css({display: 'block', zIndex: '101'});
            view(contents);
            function view(a_elm){
                var w = a_elm.outerWidth();
                var h = a_elm.outerHeight();
                var mt = (wh - h) / 2 + py;
                mInner.css({width: w, height: h, top: mt+'px'}).animate({opacity: '1'}, sp);
            }
            //return false;
        });

        //モーダルウィンドウクローズクリックイベント
        //$(document).on('click', '#modal-bg, .modal-close', function(){
        $(document).on('click', '.modal-close', function(){
            var mWin = $('#modal-win');
            //var mInner = mWin.find('#modal-win-inner');
            var mInner = $('#modal-win-inner');
            var contents = mInner.children();
            if(contents.attr("id")){
                body.append(contents);
                contents.hide();
            }
            $('#modal-win').remove();
            $('.inner').remove();
            return false;
        });

    }

})(jQuery);