使用 jquery.ba-postmessage 的 iframe 动态高度跨域

Posted

技术标签:

【中文标题】使用 jquery.ba-postmessage 的 iframe 动态高度跨域【英文标题】:iframe dynamic height cross-domain using jquery.ba-postmessage 【发布时间】:2012-02-02 15:42:43 【问题描述】:

我相信这个问题将来会帮助数百人。但该脚本有点超出我的 jQuery 能力。我有 jQuery 的基本技能,但不能解决这个问题。

基本上,我需要一个 iFrame(托管在单独的域中)来放置在我的主网站上。我不想使用 iFrame,但在我的情况下我别无选择!我需要将 iFrame 调整为 iframe 内主体的高度。

目前使用Ben Alman jQuery postMessage plugin,这个貌似可以。但是当前的示例中有一些不必要的代码,可以通过切换来调整 iFrame 的大小...

我不需要此切换,我只需要将 iFrame 调整为正确的 iframe 内容正文高度即可。我需要 iframe 高度随着 iframe 内的身体高度变化而调整。

这是我目前发现的......

我已将它放在 iframe 内容文件中 这是在服务器上:http://myiframecontent.com/

<script src="js/jquery.ba-postmessage.js" type="text/javascript"></script>
<script type="text/javascript">

     $(function()
       // Get the parent page URL as it was passed in, for browsers that don't support
       // window.postMessage (this URL could be hard-coded).
       var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),
         link;

       // 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() 
         $.postMessage( if_height: $('body').outerHeight( true ) , parent_url, parent );
       ;

       // Now that the DOM has been set up (and the height should be set) invoke setHeight.
       setHeight();

       // And for good measure, let's listen for a toggle_content message from the parent.
       $.receiveMessage(function(e)
         if ( e.data === 'toggle_content' ) 
           link.triggerHandler( 'click' );
         
       , 'http://mywebsite.com' );
     );

</script>

我已将此放在我的网站上 这是在服务器上:http://mywebsite.com/

<script src="js/jquery.ba-postmessage.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function()

        // Keep track of the iframe height.
        var if_height,

        // Pass the parent page URL into the Iframe in a meaningful way (this URL could be
        // passed via query string or hard coded into the child page, it depends on your needs).

        src = 'http://myiframecontent.com/#' + encodeURIComponent( document.location.href ),

        // Append the Iframe into the DOM.
        iframe = $( '<iframe " src="' + src + '"   scrolling="no" frameborder="0"><\/iframe>' )
            .appendTo( '#iframe' );

        // 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 the height from the passsed data.
        var h = Number( e.data.replace( /.*if_height=(\d+)(?:&|$)/, '$1' ) );

        if ( !isNaN( h ) && h > 0 && h !== if_height ) 
        // Height has changed, update the iframe.
            iframe.height( if_height = h );
        

        // An optional origin URL (Ignored where window.postMessage is unsupported).
        , 'http://myiframecontent.com/' );

        // And for good measure, let's send a toggle_content message to the child.
        $( '<a href="#">Show / hide Iframe content<\/a>' )
            .appendTo( '#nav' )
            .click(function()
            $.postMessage( 'toggle_content', src, iframe.get(0).contentWindow );
            return false;
        );

    );
</script>

<div id="iframe" class="clear"></div>

目前上面是返回当前宽度 1060px 但没有将 iframe 的高度更改为 iframe 内 body 的高度?

而且切换按钮也被添加到我的导航 div#nav 上的网站中。当我只需要高度时。

任何关于这方面的帮助都会很棒,因为我在网上找不到任何工作示例,谢谢!

这是ba-postmessage.js 脚本。

【问题讨论】:

【参考方案1】:

由于您似乎想摆脱链接,这里有一个 iframe 内容的工作示例,该示例通过 setInterval() 定期增加。

这应该转到主网站/服务器 A:http://mywebsite.com/

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Container on domain A (http://mywebsite.com/)</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-postmessage/master/jquery.ba-postmessage.js"></script>
<script type="text/javascript">
    $(function()

        // Update this constant to match your IFrame (contents) URL (no '#' here please)
        var if_url = 'http://myiframecontent.com/';

        // Keep track of the iframe height.
        var if_height;

        // Pass the parent page URL into the Iframe in a meaningful way (this URL could be
        // passed via query string or hard coded into the child page, it depends on your needs).
        var src = if_url + '#' + encodeURIComponent( document.location.href );

        // Append the Iframe into the DOM.
        var iframe = $( '<iframe " src="' + src + '"   scrolling="no" frameborder="0"><\/iframe>' )
            .appendTo( '#iframe' );

        // 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 the height from the passsed data.
                var h = Number( e.data.replace( /.*if_height=(\d+)(?:&|$)/, '$1' ) );

                if ( !isNaN( h ) && h > 0 && h !== if_height ) 
                    // Height has changed, update the iframe.
                    iframe.height( if_height = h );
                    // Some user feedback if we want to...
                    $("#ticker").text("has been informed that IFrame contents height is now " + h + " and (re)acted accordingly.");
                
            , 
            // An optional origin URL (Ignored where window.postMessage is unsupported).
            if_url 
        );

    );
</script>
</head>
<body>
<p>Container <span id="ticker"></span></p>
<div id="iframe"></div>
<p>Container</p>
</body>
</html>

这应该转到“iframe”站点/服务器 B:http://myiframecontent.com/

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Contents on domain B (http://myiframecontent.com/)</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-postmessage/master/jquery.ba-postmessage.js"></script>
<script type="text/javascript">
$(function()
   // Get the parent page URL as it was passed in, for browsers that don't support
   // window.postMessage (this URL could be hard-coded).
   var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),
     link;

   // 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() 
     $.postMessage( if_height: $('body').outerHeight( true ) , parent_url, parent );
   ;

   // Let's increase height, and inform the parent document of new height, every 3 second
   var i = 1;
   function increaseHeight() 
       $("#iframecontents").append("<p>Increase #" + i + "</p>");
       i = i + 1;
       // Now that the DOM has been set up (and the height should be set) invoke setHeight.
       setHeight();
   ;
   var timer = window.setInterval(increaseHeight, 3000);
);
</script>
</head>
<body>
<p>iframe starts here</p>
<div id="iframecontents"></div>
<p>iframe ends here</p>
</body>
</html>

请注意,在您的实际实现中,在您的 IFrame(内容)页面中,您当然需要某种事件来挂钩并调用 setHeight()

【讨论】:

以上是关于使用 jquery.ba-postmessage 的 iframe 动态高度跨域的主要内容,如果未能解决你的问题,请参考以下文章

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份