简体   繁体   English

根据内容高度调整iframe高度

[英]Resize iframe height according to content height in it

I am opening my blog page in my website. 我在我的网站上打开我的博客页面。 The problem is I can give a width to an iframe but the height should be dynamic so that there is no scrollbar in the iframe, and it looks like a single page... 问题是我可以给iframe一个宽度,但高度应该是动态的,这样iframe中就没有滚动条了,它看起来像一个页面......

I have tried various JavaScript code to calculate the height of the content but all of them give an access denied permission error and is of no use. 我已经尝试了各种JavaScript代码来计算内容的高度,但是所有这些代码都提供了访问被拒绝权限错误,没有用。

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

Can we use Ajax to calculate height or maybe using PHP? 我们可以使用Ajax来计算高度或者使用PHP吗?

To directly answer your two subquestions: No, you cannot do this with Ajax, nor can you calculate it with PHP. 直接回答你的两个子问题:不,你不能用Ajax做这个,也不能用PHP计算它。

What I have done in the past is use a trigger from the iframe'd page in window.onload (NOT domready , as it can take a while for images to load) to pass the page's body height to the parent. 我过去所做的是使用window.onload的iframe页面的触发器(不是domready ,因为它可能需要一段时间才能加载图像)将页面的主体高度传递给父级。

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

Then the parent.resizeIframe looks like this: 然后parent.resizeIframe看起来像这样:

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

Et voila, you have a robust resizer that triggers once the page is fully rendered with no nasty contentdocument vs contentWindow fiddling :) 等瞧,你有一个强大的大小调整触发一旦页面完全没有讨厌的渲染contentdocument VS contentWindow摆弄:)

Sure, now people will see your iframe at default height first, but this can be easily handled by hiding your iframe at first and just showing a 'loading' image. 当然,现在人们会首先看到你的iframe处于默认高度,但是这可以通过首先隐藏你的iframe并显示“加载”图像来轻松处理。 Then, when the resizeIframe function kicks in, put two extra lines in there that will hide the loading image, and show the iframe for that faux Ajax look. 然后,当resizeIframe函数启动时,在其中放置两条额外的行来隐藏加载图像,并显示该虚拟Ajax外观的iframe。

Of course, this only works from the same domain, so you may want to have a proxy PHP script to embed this stuff, and once you go there, you might as well just embed your blog's RSS feed directly into your site with PHP. 当然,这只能在同一个域中运行,所以你可能想要一个代理PHP脚本来嵌入这些东西,一旦你去那里,你也可以用PHP直接将你的博客的RSS源直接嵌入你的网站。

你可以用JavaScript做到这一点。

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

Fitting IFRAME contents is kind of an easy thing to find on Google . 拟合IFRAME内容在Google上很容易找到 Here's one solution : 这是一个解决方案

<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>

This of course doesn't solve the cross-domain problem you are having... Setting document.domain might help if these sites are in the same place. 这当然不能解决您遇到的跨域问题...如果这些站点位于同一位置,则设置document.domain可能会有所帮助。 I don't think there is a solution if you are iframe-ing random sites. 如果你是随机网站的iframe,我认为没有解决方案。

Here's my solution to the problem using MooTools which works in Firefox 3.6, Safari 4.0.4 and Internet Explorer 7: 这是使用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);

Style the "loading" class to show an Ajax loading graphic in the middle of the iframe container. 设置“loading”类的样式,以在iframe容器的中间显示Ajax加载图形。 Then for browsers other than Internet Explorer, it will display the full height IFRAME once the loading of its content is complete and remove the loading graphic. 然后,对于Internet Explorer以外的浏览器,一旦内容加载完成,它将显示完整高度IFRAME并删除加载图形。

I just spent the better part of 3 days wrestling with this. 我只花了3天的时间来摔跤。 I'm working on an application that loads other applications into itself while maintaining a fixed header and a fixed footer. 我正在开发一个应用程序,在保持固定页眉和固定页脚的同时将其他应用程序加载到自身中。 Here's what I've come up with. 这就是我想出的。 (I also used EasyXDM, with success, but pulled it out later to use this solution.) (我也成功使用了EasyXDM,但稍后将其用于使用此解决方案。)

Make sure to run this code AFTER the <iframe> exists in the DOM. 确保在DOM中存在<iframe>之后运行此代码。 Put it into the page that pulls in the iframe (the parent). 将它放入拉入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
});

Below is my onload event handler. 下面是我的onload事件处理程序。

I use an IFRAME within a jQuery UI dialog. 我在jQuery UI对话框中使用IFRAME。 Different usages will need some adjustments. 不同的用法需要一些调整。 This seems to do the trick for me (for now) in Internet Explorer 8 and Firefox 3.5. 在Internet Explorer 8和Firefox 3.5中,这似乎对我(现在)起了作用。 It might need some extra tweaking, but the general idea should be clear. 它可能需要一些额外的调整,但一般的想法应该是清楚的。

    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);
    }
};

The trick is to acquire all the necessary iframe events from an external script. 诀窍是从外部脚本获取所有必需的iframe事件。 For instance, you have a script which creates the iFrame using document.createElement; 例如,您有一个使用document.createElement创建iFrame的脚本; in this same script you temporarily have access to the contents of the 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();
}

This works because dFrame stays in scope in those functions, giving you access to the external iFrame element from within the scope of the frame, allowing you to see the actual document height and expand it as necessary. 这是因为dFrame保留在这些函数的作用域中,使您可以从框架范围内访问外部iFrame元素,从而可以查看实际文档高度并根据需要进行扩展。 This example will work in firefox but nowhere else; 这个例子可以在firefox中使用,但不在其他地方; I could give you the workarounds, but you can figure out the rest ;) 我可以给你解决方法,但你可以弄清楚其余的;)

@SchizoDuckie's answer is very elegant and lightweight, but due to Webkit's lack of implementation for scrollHeight (see here ), does not work on Webkit-based browsers (Safari, Chrome, various and sundry mobile platforms). @ SchizoDuckie的答案非常优雅和轻量级,但由于Webkit缺乏scrollHeight的实现(参见此处 ),因此无法在基于Webkit的浏览器(Safari,Chrome,各种各样的移动平台)上运行。

For this basic idea to work on Webkit along with Gecko and Trident browsers, one need only replace 对于使用Webkit以及Gecko和Trident浏览器的这个基本想法,只需要替换

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

with

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

So long as everything is on the same domain, this works quite well. 只要一切都在同一个域上,这就行得很好。

Try this, you can change for even when you want. 试试这个,即使你想要也可以改变。 this example use jQuery. 这个例子使用jQuery。

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

Try using scrolling=no attribute on the iframe tag. 尝试在iframe标记上使用scrolling=no属性。 Mozilla also has an overflow-x and overflow-y CSS property you may look into. Mozilla还有一个overflow-xoverflow-y CSS属性,你可以看一下。

In terms of the height, you could also try height=100% on the iframe tag. 就高度而言,您还可以在iframe标记上尝试height=100%

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM