无论滚动位置如何,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 的网页的滚动位置