HTML5 从嵌套 iframe 内部调整顶级文档 iframe 的大小 [英] HTML5 Resize top-level document iframe from inside a nested iframe

查看:40
本文介绍了HTML5 从嵌套 iframe 内部调整顶级文档 iframe 的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题似乎很难理解,所以我会尽可能地说明它.

假设我有以下 index.html 正文:

parent iframe 中,我加载以下页面主体:

<iframe name="nested-navigation"></iframe><iframe name="nested-parent"></iframe>

nested-parent iframe 中,我加载了另一个页面.在另一个页面中,我需要以某种方式进入顶级 (index.html) 文档 parent iframe,以便我可以使用 nested-parent<调整其内容的高度/code> iframe 内容大小.

我使用嵌套页面正文的加载内容正确调整了 index.html 的 parent iframe 高度.但是,在接下来的嵌套中,我无法访问 index.html 文档上下文,因此无法获取 parent iframe 元素.

我需要帮助了解如何访问 index.html 的 parent iframe.我该怎么做?

页面已上线,可以在这里查看效果:

www.ngeneersinc.com

如果您单击Projects 导航链接,它将正确加载页面并调整 iframe 的大小.遗憾的是,当您单击此嵌套页面内的 Ngen 导航链接时,顶级 (index.html) iframe (parent) 不会调整大小,并且内容是剪切到上一页中设置的任何高度.

本质上,我试图在我的 javascript 函数中执行以下操作:

var e = document.getElementById("nested-parent").contentWindow;//没问题var x = e.contentWindow;//这是未定义",因为我丢失了 index.html 文档的上下文

解决方案

您可以使用以下 jQuery 插件来完成此操作:
http://benalman.com/projects/jquery-postmessage-plugin/>

然后将以下代码添加到包含在 iframe 文档父窗口中的 javascript 文件中:

var iFrames = [];var iFrameCounter = 0;//获取传入的父页面 URL,对于不支持的浏览器//window.postMessagevar parent_url = decodeURIComponent(document.location.hash.replace(/^#/, ''));//第一个参数使用 $.param 序列化(如果不是字符串)并传递给//父窗口.如果 window.postMessage 存在,则使用该参数传递参数,//否则它会在位置哈希中传递(这就是为什么需要 parent_url).//第二个参数是 targetOrigin.函数设置高度(){var id = Number(parent_url.replace(/.*#(d+)(?:&|$)/, '$1'));$.postMessage({ if_height: $(document).outerHeight(true), id: id }, parent_url, parent);};//将给定 url 的 iframe 添加到给定容器函数 CreateFrame(容器,网址){$(函数(){//以有意义的方式将父页面 URL 传递到 Iframevar src = url + '#' + encodeURIComponent(document.location.href + "#" + iFrameCounter);//将 iFrame 附加到 DOM 中.var html = '<iframe id="iFrame' + iFrameCounter + '" src="' + src + '" width="100%" scrolling="no" frameborder="0">您的浏览器不支持 iFrames!</iframe>';iFrames[iFrameCounter] = { id: "iFrame" + iFrameCounter, container: container, if_height: 0 };//将 iFrame 添加到 DOM$(容器).append($(html));iFrameCounter++;});}$(函数(){//设置一个回调来处理分派的 MessageEvent 事件.在这种情况下//支持 window.postMessage,传递的事件会有 .data, .origin 和//.source 属性.否则,这将只有 .data 属性.$.receiveMessage(function (e) {//获取frameIdvar id = Number(e.data.replace(/.*id=([d-]*).*/, '$1'));var frame = iFrames[id];//从传递的数据中获取高度.var h = Number(e.data.replace(/.*if_height=([d-]*).*/, '$1'));如果 (!isNaN(h) && h > 0 && h !== frame.if_height) {//高度改变了,更新iframe.$("#" + frame.id).css("height", (frame.if_height = h));$("#" + frame.id).css("min-height", (frame.if_height = h));$("#" + frame.id).css("max-height", (frame.if_height = h));//同时更新 iframe 的父元素.$("#" + frame.id).parent().css("height", (frame.if_height = h));$("#" + frame.id).parent().css("min-height", (frame.if_height = h));$("#" + frame.id).parent().css("max-height", (frame.if_height = h));}});});

然后使用以下代码在父窗口中创建iframe:

<div id="someiFrameContainer"></div>

然后每次 iFrame 内文档的高度发生变化时,从 iFrame 页面调用此函数:

SetHeight();

这将导致 iframe 页面向其父窗口发送一条包含其新总高度的消息(支持跨域),这将捕获消息并更新 iframe 的大小.这要求父窗口还包含上面的脚本文件,因为该文件注册了事件和函数以在使用 CreateFrame();

时自动处理这些消息

The problem may seem hard to understand, so I will illustrate it as best I can.

Say I have the following index.html body:

<iframe name="parent"></iframe>

And inside the parent iframe, I load the following page body:

<iframe name="nested-navigation"></iframe>
<iframe name="nested-parent"></iframe>

And inside nested-parent iframe, I load another page. Inside this other page, I need to somehow get to the top-level (index.html) documents parent iframe, so that I can resize the height of its contents using the nested-parent iframe content size.

I correctly resize the index.html's parent iframes height using the loaded contents of the nested pages body. However, in the next nesting, I am unable to reach the index.html document context, and thus am unable to get the parent iframe element.

I need help on figuring out how to reach the index.html's parent iframe. How would I do this?

The page is online and the effects can be viewed here:

www.ngeneersinc.com

If you click the Projects navigation link, it will correctly load the page and resize the parent iframe. Sadly, when you click on the Ngen navigation link inside this nested page, the top-level (index.html) iframe (parent) does not get resized and the content is cut to whatever the height was set to in the previous page.

EDIT:

Essentially, I am trying to do the following in my javascript function:

var e = document.getElementById("nested-parent").contentWindow; // which is OK
var x = e.contentWindow; // which is 'undefined' because I lost the context of the index.html document

解决方案

You can use the following jQuery plugin to accomplish this:
http://benalman.com/projects/jquery-postmessage-plugin/

Then add the following code to a javascript file that you include inside the iframe document and the parent window:

var iFrames = [];
var iFrameCounter = 0;

// Get the parent page URL as it was passed in, for browsers that don't support
// window.postMessage
var parent_url = decodeURIComponent(document.location.hash.replace(/^#/, ''));

// The first param is serialized using $.param (if not a string) and passed to the
// parent window. If window.postMessage exists, the param is passed using that,
// otherwise it is passed in the location hash (that's why parent_url is required).
// The second param is the targetOrigin.
function SetHeight() {
    var id = Number(parent_url.replace(/.*#(d+)(?:&|$)/, '$1'));
    $.postMessage({ if_height: $(document).outerHeight(true), id: id }, parent_url, parent);
};

// Adds the iframe for the given url to the given container
function CreateFrame(container, url) {
    $(function () {
        // Pass the parent page URL into the Iframe in a meaningful way
        var src = url + '#' + encodeURIComponent(document.location.href + "#" + iFrameCounter);

        // Append the iFrame into the DOM.
        var html = '<iframe id="iFrame' + iFrameCounter + '" src="' + src + '" width="100%" scrolling="no" frameborder="0">Your browser lacks support for iFrames!</iframe>';
        iFrames[iFrameCounter] = { id: "iFrame" + iFrameCounter, container: container, if_height: 0 };

        // Add iFrame to DOM
        $(container).append($(html));
        iFrameCounter++;
    });
}

$(function () {
    // Setup a callback to handle the dispatched MessageEvent event. In cases where
    // window.postMessage is supported, the passed event will have .data, .origin and
    // .source properties. Otherwise, this will only have the .data property.
    $.receiveMessage(function (e) {

        // Get frameId
        var id = Number(e.data.replace(/.*id=([d-]*).*/, '$1'));

        var frame = iFrames[id];

        // Get the height from the passsed data.
        var h = Number(e.data.replace(/.*if_height=([d-]*).*/, '$1'));

        if (!isNaN(h) && h > 0 && h !== frame.if_height) {
            // Height has changed, update the iframe.
            $("#" + frame.id).css("height", (frame.if_height = h));
            $("#" + frame.id).css("min-height", (frame.if_height = h));
            $("#" + frame.id).css("max-height", (frame.if_height = h));

            // Also update the parent element of the iframe.
            $("#" + frame.id).parent().css("height", (frame.if_height = h));
            $("#" + frame.id).parent().css("min-height", (frame.if_height = h));
            $("#" + frame.id).parent().css("max-height", (frame.if_height = h));
        }
    });
});

Then use the following code to create the iframe in the parent window:

<script type="text/javascript">
     $(document).ready(function () {
         CreateFrame("#someiFrameContainer", url);
     });
</script>
<div id="someiFrameContainer"></div>

Then everytime the height of the document inside the iFrame changes call this function from the iFrame page:

SetHeight();

This will cause the iframe page to send a message containing its new total height to its parent window (supports cross-domain), which will catch the message and update the size of the iframe. This requires that the parent window also includes the script file from above, as this file registers the events and functions to handle these messages automatically when using CreateFrame();

这篇关于HTML5 从嵌套 iframe 内部调整顶级文档 iframe 的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆