无论滚动位置如何,iframe 顶部的引导模式。如何在屏幕上定位它?

Posted

技术标签:

【中文标题】无论滚动位置如何,iframe 顶部的引导模式。如何在屏幕上定位它?【英文标题】:Bootstrap modal at top of iframe regardless of scroll position. How do I position it on screen? 【发布时间】:2014-09-08 10:15:05 【问题描述】:

在 iframe 中嵌入 Bootstrap 应用时,模式对话框始终在 iframe 顶部打开,而不是在屏幕顶部打开。例如,转到http://getbootstrap.com/javascript/ 并在页面上打开一个示例模式。然后使用下面的示例代码将相同的引导页面放置在 iframe 中,找到一个模式并打开它:

<html>
    <head>
    </head>
    <body>
        <table >
            <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   
                        scrolling="no" src="http://getbootstrap.com/javascript/">
                    </iframe>
                </td>
            </tr>
        </table>
    </body>
</html>

Demo in fiddle

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

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

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

【问题讨论】:

【参考方案1】:

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

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

TL;DR

    使用window.postMessage() API - Documentation here。用于父级和 iframe 之间的通信(跨域) 使用当前滚动位置和 iframe 的 Y 位置传递消息 从顶部接收消息并更新模式的填充

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

您可以添加 EventListener 并监听“滚动”事件。每次调用事件处理函数时,您都可以获得像document.scrollingElement.scrollTop 这样的 currentScrollPosition。 请记住,您的 iframe 可以在父页面的顶部有一些边距,因此您还应该获得它的“偏移量”。 之后,您可以将这两个值发布到您的 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】:

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

【讨论】:

【参考方案3】:

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

一种解决方法是将 iframe 包裹在占据整个屏幕宽度的固定位置 div 中,然后在其中最大化 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%;  
 

Working Demo in fiddle

另见

position:fixed inside of an iframe iframe with a css fixed position : possible? position fixed div in iframe not working

【讨论】:

如果 iframe 填满屏幕并且可以自行滚动,这将非常有用,但不幸的是,我的 iframe 无法自行滚动,这受现有页面设计的限制。我已经用这些细节更新了我的问题和 jsfiddle【参考方案4】:

这是因为.modal 类具有position: fixed 属性。请改用position: relative

【讨论】:

我在我的上下文中尝试了这个,它产生了奇怪的相反行为,模态开始出现在视口下方。我认为这可能是因为我的 iFrame 情况与我最初发布的方式不完全相同。我更新了我的问题,更准确地描述了我的场景。

以上是关于无论滚动位置如何,iframe 顶部的引导模式。如何在屏幕上定位它?的主要内容,如果未能解决你的问题,请参考以下文章

当该页面打开时,如何在顶部设置包含 iframe 的网页的滚动位置

点击 iframe → 父窗口滚动到位置?

如何用js控制网页刷新后滚动条保持在原来的位置

如何在引导程序 3 中向下滚动带有固定标题(导航栏)的表格行时将表格标题(标题)粘贴在顶部?

如何在 iframe 中打开 ajax 成功的引导模式

如何使用从 iframe 加载的点击事件关闭引导模式