59133


モーダルの範囲外クリックした際にモーダルがcloseできるようにしたのですが、  
範囲外でクリックしてもモーダルを閉じることができません。

**html**

[code]

    <div class="contents">
    <button class="ModalOpen btn btn-remove btn-sm pull-right" data-target="modal-content-01">削除</button>
    </div>
    
    <div id="modal-content-01" class="modal-content-drawer">
      <div class="modal-header-drawer">
        <button type="button" class="ModalClose btn btn-sm pull-right" data-dismiss="modal" aria-label="Close">
          <i class="fa fa-times fa-2x"></i>
        </button>
        <h5>削除</h5>
      </div>
      <div class="modal-body-drawer">
        <p>削除しました</p>
      </div>
    </div>
    
[/code]

**jQuery**

[code]

    <script>
    jQuery(function(){
      var modal;
      $('.ModalOpen').click(function(){
        $('body').addClass('lock');
        modal = '#' + $(this).attr('data-target');
        $(modal).addClass('SlideIn');
      });
    
      $('.ModalClose').off().click(function(){
        if (!modal) return;
        $(modal).removeClass('SlideIn');
        $('body').removeClass('lock');
      });
    
      $('.ModalOpen').click(function(){
        $(modal).delay(3000).fadeOut('slow');
      });
    
      $(document).on('click touchstart', function(event) {
        if (!$(event.target).closest('#modal-content-01').length){
          $(modal).removeClass('SlideIn');
          $('body').removeClass('lock');
        }
      });
    });
    </script>
    
[/code]

下記の部分がうまく行きません。  
モーダルの範囲外をクリックしてもモーダルが消えない状況となっています。

[code]

    $(document).on('click touchstart', function(event) {
        if (!$(event.target).closest('#modal-content-01').length){
          $(modal).removeClass('SlideIn');
          $('body').removeClass('lock');
        }
     });
    
[/code]

まだ、経験が浅く、情報が不足している部分があるかもしれませんが、  
ご教授のほどよろしくお願いいたします。


CC BY-SA 4.0
2019-09-18T03:34:28.693
59131
2019-09-18T07:21:02.197
2019-09-18T07:21:02.197
32986
35901
question
jquery
モーダルの範囲外でクリックした際にモーダルを閉じる方法


> モーダルの範囲外をクリックしてもモーダルが消えない状況となっています。

以下のスニペットにて動作確認を行なったところ、「モーダルの範囲外をクリックしてもモーダルが消えない」問題ではなく、
**「モーダルが開かない」問題のみが再現** しました。そのため、この回答では「モーダルが開かない」問題の原因と解決策を紹介します。

[code]

    jQuery(function() {
      var modal;
      $('.ModalOpen').click(function() {
        $('body').addClass('lock');
        modal = '#' + $(this).attr('data-target');
        $(modal).addClass('SlideIn');
      });
    
      $('.ModalClose').off().click(function() {
        if (!modal) return;
        $(modal).removeClass('SlideIn');
        $('body').removeClass('lock');
      });
    
      $(document).on('click touchstart', function(event) {
        if (!$(event.target).closest('#modal-content-01').length) {
          $(modal).removeClass('SlideIn');
          $('body').removeClass('lock');
        }
      });
    });
[/code]

[code]

    body.lock::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: #000000aa;
    }
    
    .modal-content-drawer {
      display: none;
      width: 300px;
      height: 250px;
      background: #faf;
    }
    
    .SlideIn {
      display: block;
      position: relative;
      z-index: 1;
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <body>
      <div class="contents">
        <button class="ModalOpen btn btn-remove btn-sm pull-right" data-target="modal-content-01">削除</button>
      </div>
    
      <div id="modal-content-01" class="modal-content-drawer">
        <div class="modal-header-drawer">
          <button type="button" class="ModalClose btn btn-sm pull-right" data-dismiss="modal" aria-label="Close">
            <i class="fa fa-times fa-2x"></i>
          </button>
          <h5>削除</h5>
        </div>
        <div class="modal-body-drawer">
          <p>削除しました</p>
        </div>
      </div>
    </body>
[/code]

* * *

まず、今回の問題の原因は、質問文でも書かれているとおり、以下のコード内にあります。ここで考えなければならないのは、「このイベントがいつ発生するのか」です。このイベントは、「モーダル以外の箇所がクリックされたとき」に発生するのではなく、「
**ページ上のものがクリックされたとき**
」に発生します。つまり、モーダルを開くためにボタンをクリックしたときにも、このイベントが発生するということになります。

そして、モーダルを開くときにこのイベントが発生すると、 `!$(event.target).closest('#modal-
content-01').length` の結果は `true`
となり、モーダルを表示させるために適用したクラスが削除されます。このようにして、モーダルを開いた直後にモーダルが閉じてしまうことで、「モーダルが開かない」という問題が発生しています。

[code]

    $(document).on('click touchstart', function(event) {
      if (!$(event.target).closest('#modal-content-01').length) {
        $(modal).removeClass('SlideIn');
        $('body').removeClass('lock');
      }
    });
    
[/code]

* * *

これを解決するためには、「モーダルを開くときにだけ、モーダルを閉じない」ようにする必要があります。この動作は、モーダル表示用に適用したクラスを削除するときの条件を変更することで実現出来ます。具体的には以下のように、イベントを発生させた要素がモーダルを開くためのボタンではないかどうかを確認します。

[code]

    $(document).on('click touchstart', function(event) {
      if (!$(event.target).closest('#modal-content-01').length && !$(event.target).is(".ModalOpen")) {
        $(modal).removeClass('SlideIn');
        $('body').removeClass('lock');
      }
    });
    
[/code]

[code]

    jQuery(function() {
      var modal;
      $('.ModalOpen').click(function() {
        $('body').addClass('lock');
        modal = '#' + $(this).attr('data-target');
        $(modal).addClass('SlideIn');
      });
    
      $('.ModalClose').off().click(function() {
        if (!modal) return;
        $(modal).removeClass('SlideIn');
        $('body').removeClass('lock');
      });
    
      $(document).on('click touchstart', function(event) {
        if (!$(event.target).closest('#modal-content-01').length && !$(event.target).is(".ModalOpen")) {
          $(modal).removeClass('SlideIn');
          $('body').removeClass('lock');
        }
      });
    });
[/code]

[code]

    body.lock::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: #000000aa;
    }
    
    .modal-content-drawer {
      display: none;
      width: 300px;
      height: 250px;
      background: #faf;
    }
    
    .SlideIn {
      display: block;
      position: relative;
      z-index: 1;
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <body>
      <div class="contents">
        <button class="ModalOpen btn btn-remove btn-sm pull-right" data-target="modal-content-01">削除</button>
      </div>
    
      <div id="modal-content-01" class="modal-content-drawer">
        <div class="modal-header-drawer">
          <button type="button" class="ModalClose btn btn-sm pull-right" data-dismiss="modal" aria-label="Close">
            <i class="fa fa-times fa-2x"></i>
          </button>
          <h5>削除</h5>
        </div>
        <div class="modal-body-drawer">
          <p>削除しました</p>
        </div>
      </div>
    </body>
[/code]


CC BY-SA 4.0
2019-09-18T05:10:52.937
59133
2019-09-18T05:10:52.937
32986
59131
answer