在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>
小提琴演示
在这种情况下,我该如何在屏幕上定位模态?
更新:不幸的是,我的iFrame无法填充屏幕,也无法修复它,因为它需要融入页面的其余部分,并且页面本身有足够的内容可以滚动。这不是我的设计,我最终打算重新设计整个东西,但这是我现在必须解决的问题。作为一个临时选项,我使用javascript告诉iframe父级滚动到弹出模式对话框的顶部。虽然这是可以接受的,但这不是期望的行为。
我在代码中使用angularjs和ui引导程序库,但正如您在上面看到的,这是一个引导程序问题。
如果您的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.corrollY将从父窗口获得滚动Y位置
如果你的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
- 此处使用
window.postMessage()
API-文档。用于父级和iframe之间的通信(跨域( - 传递带有iframe的currentScrollPosition和Y位置的消息
- Reveive消息并从顶部更新模态的填充
在我的情况下,解决方法是在此处使用window.postMessage()
API-文档。它需要向父级添加一些额外的代码,并在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);
在大多数浏览器中,这是一个错误(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%;
}
小提琴演示
另请参见:
- 位置:固定在iframe内部
- 具有css固定位置的iframe:可能吗
- iframe中位置固定的div不工作
.modal
具有position: fixed
属性。请改用position: relative
。