iFrame postMessage一旦模态加载

时间:2014-06-08 18:17:04

标签: javascript jquery html css iframe

我有一个父页面可以在模态中加载iFrame。我希望iFrame和包含模式根据内容高度动态调整大小。

虽然我可以在加载父页面时使用postMessage将子页面的高度发送到父页面,但高度始终是错误的,因为模态还不可见。

一旦模态实际从display:none变为display:block?

,我怎样才能发送高度

这就是我现在正在做的事情:

父页面

function receiveMessage(e) {
    // Check to make sure that this message came from the correct domain.
    if (e.origin !== "http://www.example.com")
        return;

    // Update the div element to display the message.
    alert("Message Received: " + e.data);
    var pixels = e.data;
    pixels +=32;
    console.log(pixels);
    $('#modal').css('height', pixels+'px');
    $('#iframe').css('height', pixels+'px');

}

儿童页面

  function sendHeight () {
    var containerHeight = $('#main_container').height();
    alert("Height " + containerHeight);
    parent.postMessage(containerHeight, 'http://www.example.com');
  };

4 个答案:

答案 0 :(得分:6)

编辑2:

这并不是为了回答Chrome / Firefox / etc onload差异的问题(在加载图像之前使用较小的帧高度来激活chrome onload,但如果您已经使用自己的代码解决了这个问题,则可以执行此操作显示具有适当高度的模态。

JS

// edited old function
function receiveMessage(event) {
  if (event.origin !== "http://example.com") return;
  $('#modal').css('height', parseInt(event.data, 10) + 10 + 'px');
  $('#iframe').css('height', parseInt(event.data, 10) + 'px');
}
// new code
$('#show').click(function(e) {
  // use if CSS hides modal initially
  $('#modal').css('display', 'block');
  // use if hidden with inline style
  $('#modal').show();
  $('#iframe').attr('src', $('#iframe').data('src'));
});

HTML

<div id="modal" style="display: none;"><!-- for inline styling -->
  <iframe data-src="http://example.com" src="" id="iframe">
  </iframe>
</div>
<button id="show">Open the modal</button>  

GLHF

编辑:

(我已经删除了答案的原始部分,因为我知道你的要求)
Still got the inspiration from here though.

拿#2:

我碰巧在多个域下运行相同的服务器,我终于可以使用它( yay )。

因此父网页子网页位于不同的域中。

父页面只允许重新调整 madness ,如果它自己的原点与子项传递的内容相匹配postMessage(); - 中的论据,从而消除了那些想像我们这些大孩子那样重新调整大小的那些傻瓜。

子页面只允许重新调整大小,如果它来自您附近的引擎盖(在receiveMessage()中指定为条件) - 也称为匹配原点

这是你已经知道的,但由于我很慢(当然其他Google员工也会如此),我在这里拼写我们

以下是我更正后的代码:

父:

var addEvent = function (element, myEvent, fnc) {
    return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false));
};
addEvent(window, "message", receiveMessage);
function receiveMessage(event) {
  if (event.origin !== "http://www.myChildPageInsideMe.com") return;
  $('#iframe').css('height', parseInt(event.data, 10) + 10 + 'px');
}

Child / iFrizzame:

<body onload="parent.postMessage(document.body.scrollHeight, 'http://www.theOverBearingMotherPage.com');">

随意使用您喜欢的任何事件处理代码。 我喜欢我的:)

当然......

see it in action here (page on different domain than iFrame)


答案 1 :(得分:2)

您可以使用区间函数来检查模态何时实际可见,然后应用所有更改:

var timer;
timer = setInterval( checkelemnt, 300 );
function checkelemnt(){

    //is the modal visible yet?

    if(! $("#modal':visible").length)
    {
        //wait
    }else{
        //resize the modal
        //and clear the interval

        clearInterval( timer );
    }

}

另一个简洁的解决方案是使用easyXDM,特别是如果您尝试对iframe进行跨域调用

答案 2 :(得分:1)

这是我在程序中使用的内容。希望它可以帮助你

父页面

function dyniframesize(frameId) {
        var pTar = null;
        if (document.getElementById) {
            pTar = document.getElementById(frameId);
        } else {
            eval('pTar = ' + frameId + ';');
        }
        if (pTar && !window.opera) {
            // begin resizing iframe
            pTar.style.display = "block";
            pTar.height = "10px";   // 
            if (pTar.contentDocument && pTar.contentDocument.body.scrollHeight) {
                pTar.height = pTar.contentDocument.body.scrollHeight;
                pTar.width = pTar.contentDocument.body.scrollWidth;
            } else if (pTar.Document && pTar.Document.body.scrollHeight) {
                // ie5+
                pTar.height = pTar.Document.body.scrollHeight;
                pTar.width = pTar.Document.body.scrollWidth;
            }
        }
    }

<iframe id="frm" name="frm" marginheight="0" marginwidth="0" frameborder="0" scrolling="auto" onload="javascript:dyniframesize('frm');" width="100%" src=""></iframe>

答案 3 :(得分:1)

听起来您可以控制父框架和子框架中的内容。优异。

我建议:

  1. 一旦孩子能够处理消息,使用postMessage()从孩子向父母发送消息
  2. 然后,一旦父级显示子级并且子级可见
  3. ,就会从父级向子级发送消息
  4. 然后,孩子将消息发送给父母,了解其内容维度
  5. 父母然后调整iframe和每个所需尺寸的模态
  6. 缺点是可能会有点闪烁。您可以为模态提供一个大的负left CSS属性或类似的东西,以呈现出用户的视线。

    安全说明:请务必检查邮件事件的origin和/或source属性,以确保您已收到来自可信/预期来源的邮件。