当 iframe 内容的高度发生变化时自动调整 iframe 高度(同域)
Posted
技术标签:
【中文标题】当 iframe 内容的高度发生变化时自动调整 iframe 高度(同域)【英文标题】:Auto resize iframe height when the height of the iframe contents change (same domain) 【发布时间】:2012-12-16 06:50:52 【问题描述】:我正在页面内加载 iframe,iframe 内容的长度会不时更改。我已经实施了以下解决方案。但是高度是固定的,因为只有在 iframe.onload 时才会调用 dyniframesize。
是否可以不时调整 iframe 的大小以改变 iframe 的高度?
<iframe src ="popup.html" frameborder="0" margin margin frameborder="0" scrolling="auto" id="ifm" name="ifm" onload="javascript:dyniframesize('ifm');" ></iframe>
function dyniframesize(down)
var pTar = null;
if (document.getElementById)
pTar = document.getElementById(down);
else
eval('pTar = ' + down + ';');
if (pTar && !window.opera)
//begin resizing iframe
pTar.style.display="block"
if (pTar.contentDocument && pTar.contentDocument.body.offsetHeight)
//ns6 syntax
pTar.height = pTar.contentDocument.body.offsetHeight +20;
pTar.width = pTar.contentDocument.body.scrollWidth+20;
else if (pTar.Document && pTar.Document.body.scrollHeight)
//ie5+ syntax
pTar.height = pTar.Document.body.scrollHeight;
pTar.width = pTar.Document.body.scrollWidth;
</script>
【问题讨论】:
【参考方案1】:据我所知,没有一种非常自然的方法可以做到这一点,但有一些选择。
setInterval()
您可以使用setInterval()
重复检查 iframe 的内容高度并在需要时进行调整。这很简单,但效率很低。
事件监听器
iframe 内容(以及高度)中的任何内容更改通常由某些事件触发。例如,即使您从 iframe 外部添加内容,“添加”也可能是由单击按钮触发的。这可能对您有用:Live demo here (click).
var myIframe = document.getElementById('myIframe');
window.addEventListener('click', resizeIframe);
window.addEventListener('scroll', resizeIframe);
window.addEventListener('resize', resizeIframe);
myIframe.contentWindow.addEventListener('click', resizeIframe);
function resizeIframe()
console.log('resize!');
变异观察者
此解决方案适用于所有最新的浏览器 - http://caniuse.com/mutationobserver
Live demo here (click).
这真的很简单,应该可以捕捉到相关的变化。如果没有,您可以将其与上面的事件侦听器解决方案结合使用,以确保更新!
var $myIframe = $('#myIframe');
var myIframe = $myIframe[0];
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
myIframe.addEventListener('load', function()
setIframeHeight();
var target = myIframe.contentDocument.body;
var observer = new MutationObserver(function(mutations)
setIframeHeight();
);
var config =
attributes: true,
childList: true,
characterData: true,
subtree: true
;
observer.observe(target, config);
);
myIframe.src = 'iframe.html';
function setIframeHeight()
$myIframe.height('auto');
var newHeight = $('html', myIframe.contentDocument).height();
$myIframe.height(newHeight);
荣誉奖:上溢/下溢事件。
Read about it here(有很多)。
和see my demo here(在 IE 11 中不起作用!)。
这个是很酷的解决方案,但它不再适用于 IE。可能可以对其进行调整,但我宁愿使用上述解决方案之一,即使对于旧版浏览器我不得不回退到 1 秒 setInterval
,只是因为它比这个解决方案简单得多。
【讨论】:
使用 MutationObserver 时,在 webkit 中它会在图像加载完成之前触发,因此您必须检测添加/更改的 IMG 节点,然后将负载侦听器附加到它们。 @DavidBradshaw 最后一个选项似乎再次可行。【参考方案2】:实际上,您应该通过访问父窗口并更改 iframe 的高度从 iframe 执行此操作。
因为 iframe 中的文档通常会更好地知道它的主体是否改变了它的大小(您实际上可以将它绑定到 body.onload 之类的东西,而不是使用间隔来检查 iframe 中是否发生了变化)。
【讨论】:
您能否详细说明一下身体如何“知道”它何时改变了它的大小? 如果你的 iframe 能够动态改变它的高度(比如从 ajax 请求中插入一些数据),你总是可以“注入”像 window.parent.document.getElementById('myframe').style 这样的代码.height = window.document.body.offsetHeight (或类似的东西)在从 ajax 插入数据之后。否则,您将只需要在 iframe 中的 body.onload 中使用此代码。 您的回答并不是建议“动态”调整大小。很明显,在进行 ajax 调用后必须手动调用更新函数。他希望它能够自我更新。 好吧,(IMO)你的解决方案对我来说似乎有点“肮脏”,而且也很明显。我只是建议了“正确的做法”(如我所见)。 我注意到第一个解决方案效率低下,为了完整性我将其包括在内。第二种解决方案干净简单。第三个很棒而且超级高效,但是很复杂。我一会儿再补充。我不会亲自对此投反对票,我只是指出您的答案与问题无关..我想您可能会很高兴知道这一点。【参考方案3】:您可以使用自定义事件在iframe
和父级之间发出信号。
在iframe
:
if (window.parent !== window)
window.oldIframeHeight = 0;
window.setInterval(function()
var currentHeight = document.body.offsetHeight;
if (currentHeight !== window.oldIframeHeight)
window.parent.postMessage(currentHeight.toString(), "*");
window.oldIframeHeight = currentHeight;
, 100)
然后,在父级中:
window.addEventListener("message", function (e)
var h = parseInt(e.data, 10);
if (!isNaN(h))
$('#iframe').height(h)
, false);
【讨论】:
【参考方案4】:我编写了一个小型库,它使用了 mutationaObserver 和 eventListners,回退到 IE8-10 的 setInterval 并且适用于同域和跨域。它可以调整高度和宽度。
http://davidjbradshaw.github.io/iframe-resizer/
【讨论】:
由于页面的复杂性,仅对我有用。感谢您与社区分享。很好的例子。 =) +1【参考方案5】:iFrame 视图
<script type="text/javascript">
var height = $("body").outerHeight();
parent.SetIFrameHeight(height);
</script>
主视图
<script type="text/javascript">
SetIFrameHeight = function(height)
$("#iFrameWrapper").height(height);
</script>
【讨论】:
以上是关于当 iframe 内容的高度发生变化时自动调整 iframe 高度(同域)的主要内容,如果未能解决你的问题,请参考以下文章