web-dev-qa-db-ja.com

Bootstrapスクロール位置に関係なく、iframeの上部にモーダル。画面上に配置するにはどうすればよいですか?

Bootstrapアプリをiframeに埋め込む場合、モーダルダイアログは常に画面の上部ではなくiframeの上部で開きます。例として http:// getbootstrap.com/javascript/ そして、ページでモーダルの例を開きます。次に、同じbootstrapページをiframeに配置する以下のサンプルコードを使用して、モーダルを見つけて開きます。

<html>
    <head>
    </head>
    <body>
        <table width="100%">
            <tr><td colspan="2" style="height:80px;background-color:red;vertical-align:top">Here's some header content I don't control</td></tr>
            <tr><td style="width:230px;height:10080px;background-color:red;vertical-align:top">Here's some sidebar content I don't control either</td>
                <td valign="top">
                    <iframe width="100%" height="10000px" 
                        scrolling="no" src="http://getbootstrap.com/javascript/">
                    </iframe>
                </td>
            </tr>
        </table>
    </body>
</html>

フィドルのデモ

このシナリオでモーダルを画面に配置するにはどうすればよいですか?

UPDATE:残念ながら、iFrameは画面全体に表示できません。また、ページの残りの部分とページ自体にブレンドする必要があるため、修正することもできません。スクロールするのに十分なコンテンツがあります。これは私の設計ではなく、最終的には全体を作り直すつもりですが、これは今のところ回避しなければならないことです。一時的なオプションとして、javascriptを使用して、モーダルダイアログがポップアップする一番上までスクロールするようにiframeの親に指示しています。これは許容できますが、これは望ましい動作ではありません。

コードでangularjsとui-bootstrapライブラリを使用していますが、上記のように、bootstrapの問題です。

16
Charles Josephs

Iframeが親ウィンドウと同じ document.domain であるか、サブドメインである場合、iframe内で以下のコードを使用できます。

    $('#myModal').on('show.bs.modal', function (e) {
        if (window.top.document.querySelector('iframe')) {
            $('#myModal').css('top', window.top.scrollY); //set modal position
        }
    });

show.bs.modalは、$( '#myModal')。show()windowを呼び出した後に起動します。 top.scrollYは、親ウィンドウからscrollYの位置を取得します

Document.domainが親と異なる場合は、それをハックしてiframe内のonmousedown位置を取得できます。例えば:

$('#htmlElement').on('mousedown', function (event) {
    event.preventDefault();
    $('#myModal').data('y', event.pageY); // store the mouseY position
    $('#myModal').modal('show');
});
$('#myModal').on('show.bs.modal', function (e) {
    var y = $('#myModal').data('y'); // gets the mouseY position
    $('#myModal').css('top', y);
});

かなり古い質問ですが、私が見つけた解決策/回避策がわかりません。将来誰かに役立つかもしれません。

同じ問題が発生しました-iFrameが画面全体に表示されず、ブートストラップのモーダルが表示され、親ページとは異なるドメインからコンテンツが読み込まれます

TL; DR

  1. window.postMessage() AP​​Iを使用します- ドキュメントはこちら 。親とiframe間の通信用(クロスドメイン)
  2. 現在のScrollPositionとiframeのY位置を含むメッセージを渡す
  3. メッセージを受け取り、モーダルのパディングを上から更新します

私の場合、回避策はwindow.postMessage() AP​​I -- ドキュメントはこちら を使用することでした。親にコードを追加し、iFrameでメッセージを処理する必要があります。

EventListenerを追加して、「スクロール」イベントをリッスンできます。イベント処理関数が呼び出されるたびに、_document.scrollingElement.scrollTop_のようなcurrentScrollPositionを取得できます。 iframeは親ページの上部からある程度のマージンがある可能性があるため、「オフセット」も取得する必要があることに注意してください。その後、これら2つの値をiframeに投稿できます。 ncp_iframe.contentWindow.postMessage(message, '*');

messageは文字列値でなければならないことに注意してください

その後、iFrameでEventListenerを追加し、「メッセージ」イベントをリッスンする必要があります。イベント処理関数は、_event.data_プロパティで「メッセージ」を渡します。それがあれば、モーダルパディングを更新できます。 (クラスでフェードなどのアニメーションを使用しない場合は、はるかに見栄えが良くなります);

簡単な例:

親:

_window.addEventListener('scroll', function(event){
  var myIframe = document.querySelector('#myIframe');
  var topOffset = myIframe.getBoundingClientRect().top + window.scrollY;
  var currentScroll = document.scrollingElement.scrollTop;
  myIframe.contentWindow.postMessage(topOffset + ':' + currentScroll, '*');
});_

iFrame:

_window.addEventListener('message', function(event) {
  var messageContent = event.data.split(':');
  var topOffset = messageContent[0];
  var currentScroll = messageContent[1];

  //calculate padding value and update the modal top-padding

}, false);_
2
fgeorgiew

これは、ほとんどのブラウザ(IEは正常に表示されます)のバグであり、要素はウィンドウではなくiframeに固定されています。通常、メインドキュメントに関連するものが必要な場合は、メインドキュメントに含める必要があります。

回避策は、画面の幅全体を占める固定位置divでiframeをラップし、その中でiframeを最大化することです。これで問題が解決したようです

[〜#〜] html [〜#〜]

<div class="fixframe">
    <iframe src="http://getbootstrap.com/javascript/"></iframe>
</div>

[〜#〜] css [〜#〜]

.fixframe {
    position: fixed;
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;    
} 
.fixframe iframe {
   height: 100%;
   width: 100%;  
} 

フィドルでの作業デモ

関連項目

1
KyleMit

これは、クラス.modalposition: fixed属性があるためです。代わりにposition: relativeを試してください。

0
Salman