调整跨域 iframe 高度的大小 [重复]

Posted

技术标签:

【中文标题】调整跨域 iframe 高度的大小 [重复]【英文标题】:Resize Cross Domain Iframe Height [duplicate] 【发布时间】:2014-03-31 22:58:10 【问题描述】:

我正在尝试将 iframe 高度参数更改为 iframe 中正在加载的页面的相同像素。在 iframe 中加载的页面来自另一个域。

不同的页面会加载到 iframe 中,导致 iframe 内容的高度发生变化,所以我需要抓取 iframe 内容高度并将其应用于 iframe 高度参数。

这是我在谈论的一个例子:http://jsfiddle.net/R7Yz9/3/

<div class="site"><a href="http://amazon.com/" target="_top">Amazon </a></div>
<div class="site"><a href="http://cnn.com/" target="_top">Cnn </a></div>
<div class="site"><a href="http://wikipedia.org/" target="_top">Wikipedia </a></div>
<iframe id="source" src="http://amazon.com/" frameborder="0" scrolling="no"  ></iframe>

.

$(document).ready(function() 
    var iframe = $( "#source" );
    $( "a[target=_top]" ).click( function()
        iframe.attr( "src", this.href );
        return false;
    ); 
);

【问题讨论】:

你能告诉我你能把任何代码放在容器页面还是你想把任何第三方页面放在你的 iframe src ..?? PellePenna:我希望在 php 或 jquery 中执行此操作 YashPatel:我希望能够将任何第三方页面放入 iframe 【参考方案1】:

只有在您有权在两个域上实现 JS 的情况下才可能执行此跨域。如果你有这个,那么这里有一个小库,可以解决将 iFrame 调整为包含的内容的所有问题。

https://github.com/davidjbradshaw/iframe-resizer

它通过使用 post-message API 处理跨域问题,并以几种不同的方式检测 iFrame 内容的变化。

适用于所有现代浏览器和 IE8 以上。

【讨论】:

@budamivardi 它确实可以跨域工作,您只需要将第二个脚本放在远程域上。 我认为这有点欺骗性。大多数人(包括 OP)都在询问他们无法将脚本放入代码中的网站,例如亚马逊、CNN 等。是的,如果您可以访问所有代码,但故意说它是跨域的,那么这个插件可能会起作用。 我投了反对票,因为这个解决方案不是一个完整的“跨域”解决方案。请添加其他信息,说明它仅适用于“跨域”案例,前提是您可以访问两个域,正如@o_O 所说,这是我们大多数人都试图解决的情况。 @DimitarSpasovski 如果您尝试在不受您控制的站点上执行此操作,则它们在浏览器中没有解决方案。您唯一的选择是要求其他网站为您托管此 JS。【参考方案2】:

我用于在页面上嵌入适合的单个 iframe 的最小跨域集。

在嵌入页面(包含 iframe)上:

<iframe frameborder="0" id="sizetracker" src="http://www.hurtta.com/Services/SizeTracker/DE" ></iframe>
<script type="text/javascript">
  // Create browser compatible event handler.
  var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
  var eventer = window[eventMethod];
  var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
  // Listen for a message from the iframe.
  eventer(messageEvent, function(e) 
    if (isNaN(e.data)) return;

    // replace #sizetracker with what ever what ever iframe id you need
    document.getElementById('sizetracker').style.height = e.data + 'px';

  , false);
</script>

在嵌入页面(iframe)上:

<script type="text/javascript">
function sendHeight()

    if(parent.postMessage)
    
        // replace #wrapper with element that contains 
        // actual page content
        var height= document.getElementById('wrapper').offsetHeight;
        parent.postMessage(height, '*');
    


// Create browser compatible event handler.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen for a message from the iframe.
eventer(messageEvent, function(e) 

    if (isNaN(e.data)) return;

    sendHeight();

, 
false);
</script>

【讨论】:

终于,一个可行的答案!这就像我尝试过的第五个。 这不适用于 iframe 中您无法访问代码的页面。但是,如果您同时控制父页面和嵌入页面,这是一个很好的解决方案。【参考方案3】:

您还需要访问您将要进行 iframe 的网站。我在这里找到了最好的解决方案:https://gist.github.com/MateuszFlisikowski/91ff99551dcd90971377

yourotherdomain.html

<script type='text/javascript' src="js/jquery.min.js"></script>
<script type='text/javascript'>
  // Size the parent iFrame
  function iframeResize() 
    var height = $('body').outerHeight(); // IMPORTANT: If body's height is set to 100% with CSS this will not work.
    parent.postMessage("resize::"+height,"*");
  

  $(document).ready(function() 
    // Resize iframe
    setInterval(iframeResize, 1000);
  );
</script>

使用 iframe 的网站

<iframe src='example.html' id='edh-iframe'></iframe>
<script type='text/javascript'>
  // Listen for messages sent from the iFrame
  var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
  var eventer = window[eventMethod];
  var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

  eventer(messageEvent,function(e) 
    // If the message is a resize frame request
    if (e.data.indexOf('resize::') != -1) 
      var height = e.data.replace('resize::', '');
      document.getElementById('edh-iframe').style.height = height+'px';
    
   ,false);
</script>

【讨论】:

【参考方案4】:

在 javascript 中没有找到跨域 iframe 高度的选项,但您可以在一些服务器端编程的帮助下完成类似的操作。我在这个例子中使用了 PHP

<code>
    <?php
$output = file_get_contents('http://yourdomain.com');
?>
<div id='iframediv'>
    <?php echo $output; ?>
</div>

<iframe style='display:none' id='iframe' src="http://yourdomain.com"  margin  margin align="top" scrolling="auto" frameborder="0" hspace="0" vspace="0"> </iframe>

<script>
if(window.attachEvent) 
    window.attachEvent('onload', iframeResizer);
 else 
    if(window.onload) 
        var curronload = window.onload;
        var newonload = function(evt) 
            curronload(evt);
            iframeResizer(evt);
        ;
        window.onload = newonload;
     else 
        window.onload = iframeResizer;
    

   function iframeResizer()
        var result = document.getElementById("iframediv").offsetHeight;

        document.getElementById("iframe").style.height = result;
        document.getElementById("iframediv").style.display = 'none';
        document.getElementById("iframe").style.display = 'inline';
    
</script>
</code>

【讨论】:

【参考方案5】:

如果您有权操作正在加载的网站的代码,则以下内容应提供一种全面的方法来在框架内容的高度发生变化时更新iframe 容器的高度。

将以下代码添加到您正在加载的页面中(可能在标题中)。每当更新 DOM(如果您是延迟加载)或调整窗口大小(当用户修改浏览器时)时,此代码都会发送一条包含 HTML 容器高度的消息。

window.addEventListener("load", function()
    if(window.self === window.top) return; // if w.self === w.top, we are not in an iframe 
    send_height_to_parent_function = function()
        var height = document.getElementsByTagName("html")[0].clientHeight;
        //console.log("Sending height as " + height + "px");
        parent.postMessage("height" : height , "*");
    
    // send message to parent about height updates
    send_height_to_parent_function(); //whenever the page is loaded
    window.addEventListener("resize", send_height_to_parent_function); // whenever the page is resized
    var observer = new MutationObserver(send_height_to_parent_function);           // whenever DOM changes PT1
    var config =  attributes: true, childList: true, characterData: true, subtree:true; // PT2
    observer.observe(window.document, config);                                            // PT3 
);

将以下代码添加到存储 iframe 的页面。这将更新 iframe 的高度,因为消息来自 iframe 加载的页面。

<script>
window.addEventListener("message", function(e)
    var this_frame = document.getElementById("healthy_behavior_iframe");
    if (this_frame.contentWindow === e.source) 
        this_frame.height = e.data.height + "px";
        this_frame.style.height = e.data.height + "px";
    
)
</script>

【讨论】:

以上是关于调整跨域 iframe 高度的大小 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

将 iframe 内容高度设置为动态自动调整大小

跨域动态设置 iframe 高度

无法在 iframe 中调整大小 [重复]

禁用 iframe 自动调整大小

你如何给iframe 100%高度[重复]

你如何给iframe 100%高度[重复]