twitter-bootstrap 无论滚动位置如何,iframe 顶部的 Bootstrap 模式。如何在屏幕上定位?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24805274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 21:08:16  来源:igfitidea点击:

Bootstrap modal at top of iframe regardless of scroll position. How do I position it on screen?

cssangularjstwitter-bootstrapiframecss-position

提问by Charles Josephs

When embedding a Bootstrap app in an iframe, modal dialogs always open at the top of the iframe, not the top of the screen. As an example, go to http://getbootstrap.com/javascript/and open an example modal on the page. Then using the sample code below which places the same bootstrap page in an iframe, find a modal and open it:

在 iframe 中嵌入 Bootstrap 应用程序时,模态对话框始终在 iframe 顶部打开,而不是在屏幕顶部。例如,转到http://getbootstrap.com/javascript/并在页面上打开一个示例模式。然后使用下面的示例代码在 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>

Demo in fiddle

小提琴演示

How do I go about positioning the modal on the screen in this scenario?

在这种情况下,如何在屏幕上定位模态?

UPDATE:Unfortunately, my iFrame cannot fill the screen, nor can I make it fixed since it needs to blend into the rest of the page and the page itself has enough content to scroll. This is not my design and I ultimately intend to rework the whole thing, but this is what I have to work around for now. As a temporary option, I'm using javascript to tell the iframe parent to scroll to the top where the modal dialog pops up. While this is acceptable, this isn't the desired behavior.

更新:不幸的是,我的 iFrame 无法填满屏幕,也无法修复它,因为它需要融入页面的其余部分,并且页面本身有足够的内容可以滚动。这不是我的设计,我最终打算重做整个事情,但这是我现在必须解决的问题。作为一个临时选项,我使用 javascript 告诉 iframe 父级滚动到弹出模态对话框的顶部。虽然这是可以接受的,但这不是所需的行为。

I'm using angularjs and the ui-bootstrap library in my code but as you can see above, it's a bootstrap issue.

我在我的代码中使用了 angularjs 和 ui-bootstrap 库,但正如你在上面看到的,这是一个引导问题。

回答by Rogério Jun Nakatani

If your iframe has the same document.domainas the parent window or it is a sub domain, you can use the code below inside the iframe:

如果您的 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.modalwill fire after you call $('#myModal').show() window.top.scrollYwill get the scrollY position from the parent window

show.bs.modal将在您调用 $('#myModal').show() 后 触发window.top.scrollY 将从父窗口获取 scrollY 位置

In case your document.domain differs from the parent, you can hack it getting the onmousedown position inside the iframe. For example:

如果您的 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);
});

回答by fgeorgiew

Quite old question but I don't see the solution/workaround I've found. It might be helpful for someone in the future.

很老的问题,但我没有看到我找到的解决方案/解决方法。这可能对将来的某人有所帮助。

I had the same issue - my iFrame doesn't fill the entire screen, it displays bootstrap's modal and it is loading content from different domain than the parent page.

我遇到了同样的问题 - 我的 iFrame 没有填满整个屏幕,它显示引导程序的模式,并且它正在加载来自与父页面不同域的内容。

TL;DR

TL; 博士

  1. Use window.postMessage()API - Documentation here. for communication between parent and iframe (cross-domain)
  2. pass message with currentScrollPosition and Y position of your iframe
  3. Reveive message and update modal's padding from the top
  1. 在此处使用window.postMessage()API -文档。用于父级和 iframe 之间的通信(跨域)
  2. 使用 iframe 的 currentScrollPosition 和 Y 位置传递消息
  3. 从顶部接收消息并更新模态的填充


In my case the workaround was to use window.postMessage()API - Documentation here. It requires to add some extra code to the parent and handle message in an iFrame.

就我而言,解决方法是在此处使用window.postMessage()API-文档。它需要向父级添加一些额外的代码并处理 iFrame 中的消息。

You can add EventListener and listen to 'scroll' event. Each time the event handling function is invoked you can get currentScrollPosition like document.scrollingElement.scrollTop. Keep in mind that your iframe can have some margin from the top in the parent page so you should also get its 'offset'. After that you can post these two values to your iframe e.g. ncp_iframe.contentWindow.postMessage(message, '*');

您可以添加 EventListener 并收听 'scroll' 事件。每次调用事件处理函数时,您都可以获得 currentScrollPosition 之类的document.scrollingElement.scrollTop。请记住,您的 iframe 可以从父页面的顶部有一些边距,因此您也应该获得它的“偏移量”。之后,您可以将这两个值发布到您的 iframe 例如ncp_iframe.contentWindow.postMessage(message, '*');

Notethat the messagehas to be a String value

请注意message必须是字符串值

After that in your iFrame you need to add EventListener and listen to 'message' event. The event handling function will pass your 'message' in event.dataproperty. Having that you can update modal padding. (Looks much better if you don't use animations e.g. fade, in classes);

之后,在您的 iFrame 中,您需要添加 EventListener 并收听 'message' 事件。事件处理函数将在event.data属性中传递您的“消息” 。有了它,您可以更新模态填充。(如果您在类中不使用动画,例如淡入淡出,看起来会好得多);

Quick Example:

快速示例:

Parent:

家长:

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);

回答by KyleMit

This is a bugin most browsers (IE appears fine) where the elements are fixed to the iframe, not the window. Typically, if you need something to be relative to the main document, it has to be in the main document.

这是大多数浏览器中的一个错误(IE 看起来不错),其中元素固定到iframe,而不是窗口。通常,如果您需要与主文档相关的内容,则它必须位于主文档中。

A workaround is to wrap your iframe in a fixed position div that takes up the whole width of the screen and then maximize the iframe within that. This appears to resolve the issue

一种解决方法是将 iframe 包裹在占据整个屏幕宽度的固定位置 div 中,然后在其中最大化 iframe。这似乎可以解决问题

HTML:

HTML:

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

CSS:

CSS:

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

Working Demo in fiddle

小提琴工作演示

See Also:

另见

回答by Salman

It is because the class .modalhas position: fixedattribute. Try position: relativeinstead.

这是因为该类.modal具有position: fixed属性。试试吧position: relative