我有一个iframe,你可以在下面的链接上看到的; -
http://one2onecars.com
该iframe是在屏幕中心的在线预订。 我的问题是,虽然iframe的高度是好的网页加载,我需要以某种方式自动调整高度作为页面内容进行调整。 例如,如果我在网上预订做一个邮政编码搜索它创建了一个下拉菜单,然后让“下一步”按钮无法查看。
我需要发生的是,当网上预订的内容改变时,iframe自动调整到IFRAME(动态),因为它的新高度不加载任何其他页面。
我一直在使用jQuery来尝试解决这个问题尝试了几种不同的脚本,但他们都似乎只是自动调整iframe的高度时,第一次加载页面,而不是作为的iframe中的内容发生变化。
这甚至可能做什么?
我此刻的代码是在目前设定高度: -
<div id="main-online-booking">
<iframe id="main-online-frame" class="booking-dimensions" src="http://www.marandy.com/one2oneob/login-guest.php" scrolling="no" frameborder="0"></iframe>
</div>
#main-online-booking {
height: 488px;
border-bottom: 6px #939393 solid;
border-left: 6px #939393 solid;
border-right: 6px #939393 solid;
z-index: 4;
background-color: #fff;
}
.booking-dimensions {
width: 620px;
height: 488px;
}
如果有人能帮助我,我将非常感谢!
的setInterval
该 只要 (校正由于浏览器技术的进步,看到大卫·布拉德肖的答案 )向后兼容的方式与iframe来实现这一目标是使用setInterval
和照看自己的iframe的内容。 当它改变它的高度,更新的iframe的大小。 有没有这样的情况下,你可以听出来,这将使它很容易很遗憾。
一个基本的例子 ,如果在尺寸上已经改变了iframe中的内容是主要的页面流的一部分,这只会工作。 如果元素是浮动或定位,那么你将不得不针对他们专门寻找高度的变化。
jQuery(function($){
var lastHeight = 0, curHeight = 0, $frame = $('iframe:eq(0)');
setInterval(function(){
curHeight = $frame.contents().find('body').height();
if ( curHeight != lastHeight ) {
$frame.css('height', (lastHeight = curHeight) + 'px' );
}
},500);
});
显然,这取决于你想你可以修改这个代码的角度来看,这样它的iframe的作品,在本身,而不是预期是主要页面的一部分内容。
跨域问题
你会发现的问题是,由于浏览器的安全性它不会让,如果它是一个不同的主机的主网页上您访问iframe的内容,所以实际上没有什么可以做,除非你有添加的一种方式任何脚本出现在iframe的HTML。
阿贾克斯
有些人所提出的建议尝试使用通过AJAX的第三方服务,除非该服务支持这种方法,这将是非常不可能的,你就可以得到它的工作 - 特别是如果它是一个订票服务,将最有可能需要通过HTTPS / SSL操作。
因为它似乎你有完全控制iframe中的内容,你有充分的选择向你开放,AJAX与JSONP将是一种选择。 然而,警告的一个词。 如果您的预订系统是多步骤,你需要确保你有一个精心设计的用户界面 - 可能还有一些历史/片段管理代码 - 如果你是往下走的AJAX路线。 这一切都是因为你永远无法知道当用户将决定向前或向后导航在他们的浏览器(其中一个iframe会自动处理,在合理范围内)。 一个精心设计的UI可以从这样做有损用户。
跨域通信
如果你有两面的控制(这听起来像你这样做),你也可以选择使用跨域通信选项window.postMessage
-在这里看到更多的信息https://developer.mozilla.org/en-US/docs/DOM /window.postMessage
现代浏览器和部分IE8有一些新的功能,使这项任务比它更容易使用的是。
PostMessage的
所述的postMessage API提供一种简单的方法在iFrame之间comunicating和它的父。
要发送消息给你怎么称呼它,如下所示父页面。
parent.postMessage('Hello parent','http://origin-domain.com');
在另一个方向上,我们可以将消息发送到所述iFrame用下面的代码。
var iframe = document.querySelector('iframe');
iframe.contentWindow.postMessage('Hello my child', 'http://remote-domain.com:8080');
要recevie消息创建消息事件的事件listerner。
function receiveMessage(event)
{
if (event.origin !== "http://remote-domain.com:8080")
return;
console.log(event.data);
}
if ('addEventListener' in window){
window.addEventListener('message', receiveMessage, false);
} else if ('attachEvent' in window){ //IE
window.attachEvent('onmessage', receiveMessage);
这些例子使用origin属性,以限制该消息被发送到并检查它来自何处。 它可以指定*
允许发送到任何域,你可以在某些情况下,你可能要接受来自任何域的消息。 但是,如果你这样做,你需要考虑安全问题并实现传入消息自己的检查,以确保它包含了你的期望是什么。 在这种情况下的iframe可以发布它的高度为“*”,因为我们可能有一个以上的父域。 然而,这是检查传入消息来自iFrame的一个好主意。
function isMessageFromIFrame(event,iframe){
var
origin = event.origin,
src = iframe.src;
if ((''+origin !== 'null') && (origin !== src.substr(0,origin.length))) {
throw new Error(
'Unexpect message received from: ' + origin +
' for ' + iframe.id + '. Message was: ' + event.data
);
}
return true;
}
MutationObserver
在更现代broswers另一个进步是MutationObserver它可以让你观看在DOM变化; 所以现在可以检测到可能影响iFrame的大小,而不必经常在使用setInterval轮询的变化。
function createMutationObserver(){
var
target = document.querySelector('body'),
config = {
attributes : true,
attributeOldValue : false,
characterData : true,
characterDataOldValue : false,
childList : true,
subtree : true
},
observer = new MutationObserver(function(mutations) {
parent.postMessage('[iframeResize]'+document.body.offsetHeight,'*');
});
log('Setup MutationObserver');
observer.observe(target, config);
}
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
if (MutationObserver){
createMutationObserver();
}
工作了一个精确的高度
获取的iFrame的准确高度是不应该的那样简单,因为你有六个不同性质的选择,你可以检查他们都不给不断正确的答案。 最好的解决办法,我想出了这个函数,你不使用CSS溢出身体标记,工作这么久。
function getIFrameHeight(){
function getComputedBodyStyle(prop) {
return parseInt(
document.defaultView.getComputedStyle(document.body, null),
10
);
}
return document.body.offsetHeight +
getComputedBodyStyle('marginTop') +
getComputedBodyStyle('marginBottom');
}
这是IE9版本,为多长IE8版本中看到这个答案 。
如果你这样做溢出身体,你不能修复您的代码停止这一点,那么无论使用的offsetHeight
或scrollHeight
的属性document.documentElement
是你的最佳选择。 两者都有优点和缺点,它充其量只是来测试,看看它为你的作品。
其他问题
其他的事情要考虑的因素包括,具有页面上有一个IFRAME,CSS:复选框和:将鼠标悬停导致页面调整大小事件,避免I帧的身体和HTML代码中使用高度自动的,最后被调整窗口的大小。
IFrame的调整器库
我裹着这一切在一个简单的扶养免费的图书馆,还提供了这里就不讨论了一些额外的功能。
https://github.com/davidjbradshaw/iframe-resizer
这适用于IE8 +。
我写这个剧本,它的工作完美的我。 随意使用它!
function ResizeIframeFromParent(id) {
if (jQuery('#'+id).length > 0) {
var window = document.getElementById(id).contentWindow;
var prevheight = jQuery('#'+id).attr('height');
var newheight = Math.max( window.document.body.scrollHeight, window.document.body.offsetHeight, window.document.documentElement.clientHeight, window.document.documentElement.scrollHeight, window.document.documentElement.offsetHeight );
if (newheight != prevheight && newheight > 0) {
jQuery('#'+id).attr('height', newheight);
console.log("Adjusting iframe height for "+id+": " +prevheight+"px => "+newheight+"px");
}
}
}
你可以调用一个循环中的作用:
<script>
jQuery(document).ready(function() {
// Try to change the iframe size every 2 seconds
setInterval(function() {
ResizeIframeFromParent('iframeid');
}, 2000);
});
</script>
使用这个脚本:
$(document).ready(function () {
// Set specific variable to represent all iframe tags.
var iFrames = document.getElementsByTagName('iframe');
// Resize heights.
function iResize() {
// Iterate through all iframes in the page.
for (var i = 0, j = iFrames.length; i < j; i++) {
// Set inline style to equal the body height of the iframed content.
iFrames[i].style.height = iFrames[i].contentWindow.document.body.offsetHeight + 'px';
}
}
// Check if browser is Safari or Opera.
if ($.browser.safari || $.browser.opera) {
// Start timer when loaded.
$('iframe').load(function () {
setTimeout(iResize, 0);
});
// Safari and Opera need a kick-start.
for (var i = 0, j = iFrames.length; i < j; i++) {
var iSource = iFrames[i].src;
iFrames[i].src = '';
iFrames[i].src = iSource;
}
} else {
// For other good browsers.
$('iframe').load(function () {
// Set inline style to equal the body height of the iframed content.
this.style.height = this.contentWindow.document.body.offsetHeight + 'px';
});
}
});
注意:使用它的网络服务器。