web-dev-qa-db-ja.com

Bootstrap iOS 12のモーダルiframeがコンテンツの背後に隠れている

私はBootstrap 4.1 iOSのSafariのiframe内に表示される4.1モーダルで問題を抱えています。テストされた他のすべてのブラウザは期待どおりに機能します(iOS 11のSafariでも)。この問題はiOSに固有のようです12。

問題を示す最小限の例 を作成しました。最初の2つのボタンは期待どおりに機能しているように見えますが、最後の4つのボタンは問題を確認できます。下に移動すると、それぞれのボタンが悪化し、最後のボタンがスクロールまたは内部の要素にフォーカスしようとすると、一緒に消えます。モーダル(下のスクリーンショットを参照):

enter image description hereenter image description hereenter image description here

Iframeのコンテンツをスクロールできるようにする代わりに、messageイベントを介して親と子の間でメッセージを渡すことにより、iframeのコンテンツをスクロールした後、高さを調整するため、この機能を少し正統ではない方法で処理していることに注意しますハンドラーとpostMessagehttps://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage これは、何かがおかしいと思われる場所です(ただし、まだこれを追跡します(前述のとおり、これはバージョン12を実行しているiOSデバイスでのみ問題になります)。

編集する

この問題はiOS 12のSafariに固有のものではないことが最近発見されましたが、chromeも同様です。

以下のコードは、前の最小限のサンプルリンクからのものです。

親(/modal-test/index.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Title</title>

    <link rel="stylesheet" href="./bootstrap.min.css">

    <script src="./jquery.min.js"></script>
    <script src="./popper.min.js"></script>
    <script src="./bootstrap.min.js"></script>

    <script>
        $(document).ready(function(){

            $ifCon = $("#ifCon");

            window.addEventListener("message", function(event){
                if(event.data.method === "returnWindowSize"){
                    $ifCon.height(event.data.content);
                }
            }, false);

        });
    </script>

    <style>

        #ifCon {
            display: flex;
            width: 100%;
            height: 100%;
            flex-direction: column;
            background-color: #F2F2F2;
            overflow: hidden;
            border-radius:10px;
            border:1px solid grey;
            margin-left:auto;
            margin-right:auto;
            /*box-shadow:2px 2px 3px #000;*/
            box-shadow: 0px 1px 3px 0px rgba(0,0,0,0.75);
        }
        #ifCon iframe {
            flex-grow: 1;
            border: none;
            margin: 0;
            padding: 0;
        }

    </style>


</head>
<body>

    <div class="container">

        <div class="row">

            <div class="col text-center">

                <div id="ifCon">
                    <iframe height="100%" width="100%" scrolling="no" src="/modal-test/frameable.html"></iframe>
                </div>

            </div>

        </div>

    </div>

</body>
</html>

子(/modal-test/frameable.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Title</title>

    <link rel="stylesheet" href="./bootstrap.min.css">

    <script src="./jquery.min.js"></script>
    <script src="./popper.min.js"></script>
    <script src="./bootstrap.min.js"></script>

    <script>

        var $embedContent, modalState;


        $(document).ready(function(){

            $embedContent = $('#embedContent');

            parent.postMessage({method:"returnWindowSize", content:$embedContent.height()}, '*');


            $('.modal').on('shown.bs.modal', function(e){

                modalState = {
                    id:$(this).attr('id'),
                    contentElement:$(this).find('.modal-content'),
                    initialContentContainerHeight:$embedContent.height(),
                    invokerElement:$(e.relatedTarget)
                };

                adjustModal();

            });

            $('.modal').on('hidden.bs.modal', function(e){
                modalState = null;
                $(this).find('.modal-content').css("margin-top", "0px");
                $embedContent.css('height', 'auto');
                parent.postMessage({method:"returnWindowSize", content:$embedContent.height()}, '*');
            });


        });


        function adjustModal(){

            if(modalState.contentElement.css('margin-top') !== modalState.invokerElement.offset().top){
                modalState.contentElement.animate({'margin-top':modalState.invokerElement.offset().top}, 200, "linear");
            }

            if(

                // modal position + modal height is greater than or equal to the height of the embedContent so we need to resize the
                // embedContent (make it taller)
                ((modalState.invokerElement.offset().top + modalState.contentElement.height()) >= $embedContent.height()) ||

                // modal position + modal height is less than or equal to the height of the embedContent AND the current height of the
                // embedContent is greater than or equal to the size of the embedContent height when the modal was originally shown
                (((modalState.invokerElement.offset().top + modalState.contentElement.height()) <= $embedContent.height()) &&
                    ($embedContent.height() > modalState.initialContentContainerHeight))

            ){
                var newEmbedContentHeight = modalState.invokerElement.offset().top + modalState.contentElement.height() + 30;
                $embedContent.height(newEmbedContentHeight);
                parent.postMessage({method:"returnWindowSize", content:newEmbedContentHeight}, '*');
            }

        }

    </script>


</head>
<body>


    <div id="embedContent" class="container">

        <div class="row" style="height:200px;margin-top:100px;">
            <div class="col text-center">
                <button id="btn1" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
                  Launch demo modal
                </button>
            </div>
        </div>

        <div class="row" style="height:200px;">
            <div class="col text-center">
                <button id="btn2" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
                  Launch demo modal
                </button>
            </div>
        </div>

        <div class="row" style="height:200px;">
            <div class="col text-center">
                <button id="btn3" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
                  Launch demo modal
                </button>
            </div>
        </div>

        <div class="row" style="height:200px;">
            <div class="col text-center">
                <button id="btn3" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
                  Launch demo modal
                </button>
            </div>
        </div>

        <div class="row" style="height:200px;">
            <div class="col text-center">
                <button id="btn3" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
                  Launch demo modal
                </button>
            </div>
        </div>

        <div class="row" style="height:200px;">
            <div class="col text-center">
                <button id="btn3" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
                  Launch demo modal
                </button>
            </div>
        </div>

    </div>


    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" 
        aria-labelledby="exampleModalLabel" aria-hidden="true" data-focus="false" style="overflow-y:hidden;">
      <div class="modal-dialog" role="document">
        <div class="modal-content" style="margin-top:500px;">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <form>
              <div class="form-group">
                <label for="exampleFormControlInput1">Email address</label>
                <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="[email protected]">
              </div>
              <div class="form-group">
                <label for="exampleFormControlInput1">Email address</label>
                <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="[email protected]">
              </div>
              <div class="form-group">
                <label for="exampleFormControlSelect1">Example select</label>
                <select class="form-control" id="exampleFormControlSelect1">
                  <option>1</option>
                  <option>2</option>
                  <option>3</option>
                  <option>4</option>
                  <option>5</option>
                </select>
              </div>
              <div class="form-group">
                <label for="exampleFormControlSelect1">Example select</label>
                <select class="form-control" id="exampleFormControlSelect1">
                  <option>1</option>
                  <option>2</option>
                  <option>3</option>
                  <option>4</option>
                  <option>5</option>
                </select>
              </div>
              <div class="form-group">
                <label for="exampleFormControlSelect1">Example select</label>
                <select class="form-control" id="exampleFormControlSelect1">
                  <option>1</option>
                  <option>2</option>
                  <option>3</option>
                  <option>4</option>
                  <option>5</option>
                </select>
              </div>
              <div class="form-group">
                <label for="exampleFormControlSelect1">Example select</label>
                <select class="form-control" id="exampleFormControlSelect1">
                  <option>1</option>
                  <option>2</option>
                  <option>3</option>
                  <option>4</option>
                  <option>5</option>
                </select>
              </div>
            </form>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary">Save changes</button>
          </div>
        </div>
      </div>
    </div>




</body>
</html>
7
whitwhoa

#ifConのCSSに追加

#ifCon {
  height: 100vh;
 }

あなたの好みに合わせて数字をいじってください、VHはビューの高さを100%に設定します。

0
matthewesp