根据其中的内容高度调整iframe的高度


69

我正在网站上打开博客页面。问题是我可以给iframe设置宽度,但高度应该是动态的,以便iframe中没有滚动条,而且看起来像是一个页面...

我尝试了各种JavaScript代码来计算内容的高度,但是所有这些代码都给出了拒绝访问权限错误,没有用。

<iframe src="http://bagtheplanet.blogspot.com/" name="ifrm" id="ifrm" width="1024px" ></iframe>

我们可以使用Ajax来计算高度还是使用PHP?

Answers:


60

要直接回答您的两个子问题:不,您不能使用Ajax进行此操作,也不能使用PHP进行计算。

我过去所做的是使用iframe页面中的触发器window.onload(不是domready,因为加载图像可能需要一段时间),将页面的身高传递给父对象。

<body onload='parent.resizeIframe(document.body.scrollHeight)'>

然后parent.resizeIframe看起来像这样:

function resizeIframe(newHeight)
{
    document.getElementById('blogIframe').style.height = parseInt(newHeight,10) + 10 + 'px';
}

等瞧,你有一个强大的大小调整触发一旦页面完全没有讨厌的渲染contentdocumentVScontentWindow摆弄:)

当然,现在人们将首先在默认高度看到您的iframe,但这可以通过首先隐藏您的iframe并仅显示“正在加载”图像来轻松解决。然后,当resizeIframe函数启动时,在其中添加两条额外的行,这些行将隐藏加载图像,并显示仿制Ajax外观的iframe。

当然,这仅适用于同一域,因此您可能希望使用代理PHP脚本来嵌入这些内容,并且一旦转到该域,您也可以将PHP的Blog的RSS feed直接嵌入到您的站点中。


我正在使用iframe加载页面。我的iframe位于主页中,加载后不会重新加载。只有在iframe中的页面会根据从以iframe为目标的主页上单击的链接进行更改。在这种情况下,如何调整iframe的高度。
这个。__curious_geek 09年

我将其添加到iframe页面的底部...当加载时间嵌套在body onload事件中时,加载时间导致了假的px高度。<script> parent.resizeIframe(document.body.scrollHeight); </ script>
atwellpub 2011年

@SchizoDuckie简短而又很好的答案
丹麦Iqbal

1
@SchizoDuckie我面临一个问题iframe,并且机身尺寸仅增加而不减少任何解决方案?
丹麦Iqbal 2012年

我发现这不是在我第一次加载父屏幕时调整大小。孩子需要一点时间来加载。我也看到同样缺乏减少。
baash05

8

您可以使用JavaScript进行此操作。

document.getElementById('foo').height = document.getElementById('foo').contentWindow.document.body.scrollHeight + "px";

该脚本使我感到困惑。我喜欢在一个真实的网站上练习:mathsearchun.blogspot.com/。“ id”是最里面的div“ HTML3”还是最外面的div“ outer-wrapper”?我在Firebug中遇到诸如“ contentWindow未定义”和“ document.getElementById(“ id”)为null”之类的错误。他们的意思是什么?
莱奥列奥波尔德·赫兹준 영

您想获得的元素是iframe,我想是亚马逊。“ contentWindow未定义”可能意味着您抓取的元素没有该属性/元素。您需要使用document.getElementById(“ amazon”)来获取iframe。
安德斯(Anders S)

1
这在Chrome和IE中有效,但在Firefox中不可行,您可以对此进行改进以包括Firefox吗?
Serj Sagan 2012年

4

在Google找到适合IFRAME的内容是一件容易的事。这是一种解决方案

<script type="text/javascript">
    function autoIframe(frameId) {
       try {
          frame = document.getElementById(frameId);
          innerDoc = (frame.contentDocument) ? frame.contentDocument : frame.contentWindow.document;
          objToResize = (frame.style) ? frame.style : frame;
          objToResize.height = innerDoc.body.scrollHeight + 10;
       }
       catch(err) {
          window.status = err.message;
       }
    }
</script>

当然,这不能解决您遇到的跨域问题。document.domain如果这些站点位于同一位置,则设置可能会有所帮助。如果您要对随机网站进行内嵌广告,我认为没有解决方案。


1
您缺少高度分配的单位,即“ px”。这不是在标准模式下引起故障吗?
月牙食

2

这是使用MooTools解决此问题的方法,该工具可在Firefox 3.6,Safari 4.0.4和Internet Explorer 7中运行:

var iframe_container = $('iframe_container_id');
var iframe_style = {
    height: 300,
    width: '100%'
};
if (!Browser.Engine.trident) {
    // IE has hasLayout issues if iframe display is none, so don't use the loading class
    iframe_container.addClass('loading');
    iframe_style.display = 'none';
}
this.iframe = new IFrame({
    frameBorder: 0,
    src: "http://www.youriframeurl.com/",
    styles: iframe_style,
    events: {
        'load': function() {
            var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document;
            var h = this.measure(function(){
                return innerDoc.body.scrollHeight;
            });            
            this.setStyles({
                height: h.toInt(),
                display: 'block'
            });
            if (!Browser.Engine.trident) {
                iframe_container.removeClass('loading');
            }
        }
    }
}).inject(iframe_container);

设置“加载”类的样式,以在iframe容器的中间显示一个Ajax加载图形。然后,对于Internet Explorer以外的浏览器,一旦其内容加载完成,它将显示全高IFRAME,并删除加载图形。


0

下面是我的 onload事件处理程序。

我在jQuery UI对话框中使用IFRAME 。不同的用法将需要一些调整。在Internet Explorer 8和Firefox 3.5中,这似乎对我来说是成功的诀窍。它可能需要一些额外的调整,但是总体思路应该很清楚。

    function onLoadDialog(frame) {
    try {
        var body = frame.contentDocument.body;
        var $body = $(body);
        var $frame = $(frame);
        var contentDiv = frame.parentNode;
        var $contentDiv = $(contentDiv);

        var savedShow = $contentDiv.dialog('option', 'show');
        var position = $contentDiv.dialog('option', 'position');
        // disable show effect to enable re-positioning (UI bug?)
        $contentDiv.dialog('option', 'show', null);
        // show dialog, otherwise sizing won't work
        $contentDiv.dialog('open');

        // Maximize frame width in order to determine minimal scrollHeight
        $frame.css('width', $contentDiv.dialog('option', 'maxWidth') -
                contentDiv.offsetWidth + frame.offsetWidth);

        var minScrollHeight = body.scrollHeight;
        var maxWidth = body.offsetWidth;
        var minWidth = 0;
        // decrease frame width until scrollHeight starts to grow (wrapping)
        while (Math.abs(maxWidth - minWidth) > 10) {
            var width = minWidth + Math.ceil((maxWidth - minWidth) / 2);
            $body.css('width', width);
            if (body.scrollHeight > minScrollHeight) {
                minWidth = width;
            } else {
                maxWidth = width;
            }
        }
        $frame.css('width', maxWidth);
        // use maximum height to avoid vertical scrollbar (if possible)
        var maxHeight = $contentDiv.dialog('option', 'maxHeight')
        $frame.css('height', maxHeight);
        $body.css('width', '');
        // correct for vertical scrollbar (if necessary)
        while (body.clientWidth < maxWidth) {
            $frame.css('width', maxWidth + (maxWidth - body.clientWidth));
        }

        var minScrollWidth = body.scrollWidth;
        var minHeight = Math.min(minScrollHeight, maxHeight);
        // descrease frame height until scrollWidth decreases (wrapping)
        while (Math.abs(maxHeight - minHeight) > 10) {
            var height = minHeight + Math.ceil((maxHeight - minHeight) / 2);
            $body.css('height', height);
            if (body.scrollWidth < minScrollWidth) {
                minHeight = height;
            } else {
                maxHeight = height;
            }
        }
        $frame.css('height', maxHeight);
        $body.css('height', '');

        // reset widths to 'auto' where possible
        $contentDiv.css('width', 'auto');
        $contentDiv.css('height', 'auto');
        $contentDiv.dialog('option', 'width', 'auto');

        // re-position the dialog
        $contentDiv.dialog('option', 'position', position);

        // hide dialog
        $contentDiv.dialog('close');
        // restore show effect
        $contentDiv.dialog('option', 'show', savedShow);
        // open using show effect
        $contentDiv.dialog('open');
        // remove show effect for consecutive requests
        $contentDiv.dialog('option', 'show', null);

        return;
    }

    //An error is raised if the IFrame domain != its container's domain
    catch (e) {
        window.status = 'Error: ' + e.number + '; ' + e.description;
        alert('Error: ' + e.number + '; ' + e.description);
    }
};

0

@SchizoDuckie的答案非常优雅,轻巧,但是由于Webkit缺少对scrollHeight的实现(请参见此处),因此在基于Webkit的浏览器(Safari,Chrome,各种移动平台)上不起作用。

为了使这一基本思想与Gecko和Trident浏览器一起在Webkit上运行,只需替换一下

<body onload='parent.resizeIframe(document.body.scrollHeight)'>

<body onload='parent.resizeIframe(document.body.offsetHeight)'>

只要所有内容都在同一个域中,就可以很好地工作。


根据quirksmode.org/dom/w3c_cssom.html和快速测试,scrollHeight可在Safari和Chrome(OS X)上运行。在我的测试中,OffsetHeight在两种浏览器中均无法正常工作。
user462982

0

我只是花了3天的大部分时间为此而努力。我正在开发一个应用程序,该应用程序将其他应用程序加载到自身中,同时保持固定的标头和固定的页脚。这是我想出的。(我也成功使用过EasyXDM,但后来将其拔出以使用此解决方案。)

确保<iframe>在DOM存在后运行此代码。将其放入拉入iframe(父级)的页面中。

// get the iframe
var theFrame = $("#myIframe");
// set its height to the height of the window minus the combined height of fixed header and footer
theFrame.height(Number($(window).height()) - 80);

function resizeIframe() {
    theFrame.height(Number($(window).height()) - 80);
}

// setup a resize method to fire off resizeIframe.
// use timeout to filter out unnecessary firing.
var TO = false;
$(window).resize(function() {
    if (TO !== false) clearTimeout(TO);
    TO = setTimeout(resizeIframe, 500); //500 is time in miliseconds
});

0

诀窍是从外部脚本获取所有必需的iframe事件。例如,您有一个脚本,该脚本使用document.createElement创建iFrame;在同一脚本中,您可以临时访问iFrame的内容。

var dFrame = document.createElement("iframe");
dFrame.src = "http://www.example.com";
// Acquire onload and resize the iframe
dFrame.onload = function()
{
    // Setting the content window's resize function tells us when we've changed the height of the internal document
    // It also only needs to do what onload does, so just have it call onload
    dFrame.contentWindow.onresize = function() { dFrame.onload() };
    dFrame.style.height = dFrame.contentWindow.document.body.scrollHeight + "px";
}
window.onresize = function() {
    dFrame.onload();
}

之所以可行,是因为dFrame保留在这些功能的范围内,使您可以从框架范围内访问外部iFrame元素,从而可以查看实际的文档高度并根据需要进行扩展。这个例子将在Firefox中运行,但在其他地方都无法运行。我可以给您解决方法,但是您可以找出其余的方法;)


在响应中触发快乐。上面的Scott使用了类似的脚本,但是contentWindow.onresize的包含允许您在iframe的内容更改时调整其大小。这对于流体宽度iframe也很有用。
汤坎贝尔

是什么fobj在这个脚本是指什么?
akaihola 2012年

我认为这是一个转录错误。我复制了一些代码,却忘记了在一个上下文中交换fobj。它应该是dFrame。固定的答案。
坎贝尔汤

0

试试这个,您甚至可以在需要时进行更改。本示例使用jQuery。

$('#iframe').live('mousemove', function (event) {   
    var theFrame = $(this, parent.document.body);
    this.height($(document.body).height() - 350);           
});

-3

尝试scrolling=no在iframe广告代码中使用属性。Mozilla还有一个overflow-xand overflow-yCSS属性,您可能会研究。

在高度方面,您也可以尝试height=100%使用iframe广告代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.