仅在Chrome中调整iframe问题的大小

时间:2012-02-27 11:38:19

标签: javascript html css google-chrome javascript-framework

好的,到此为止。 Stack Overflow处女,但希望你们能帮助我。

我一直在根据内容调整iframe的高度。内容因用户在一系列表单中的进展而有所不同,这意味着每次提交都会产生一种新形式,其中有3种形式。

iframe加载时会调用以下代码,

function checkHeight() {
    var frame=document.getElementById('frame');
    var doc=frame.contentWindow.document;
    var data=doc.getElementById('data');
    alert(data);
    var data_height=data.offsetHeight;
    if(data_height) {
        frame.style.height=data_height + 'px';
        alert('height has been set');
    }
}

这对于Mac和PC版本的Mozilla,IE和Safari都运行良好,但我遇到了一个关于chrome的大问题。它不会在框架内返回文档。这是权限错误还是什么?!

我也尝试过contentDocument,但无济于事。

所有文档都驻留在我的服务器上,并且都位于同一个文件夹中。

提前致谢。

3 个答案:

答案 0 :(得分:1)

编辑:

我已经重新阅读了你的问题 - 只是计算iframe文档中的高度并调用父调整大小函数会更简单,因为它们位于同一个安全沙箱中(即在同一个域中)?

原件:

由于iframe是从不同的域嵌入(无法访问iframe..document)时发生了类似的事情,我推测这种方法可行:

  1. 首先:计算文档本身(即iframe内部)的文档高度。
  2. 使用旧浏览器的window.postMessage / hash轮询将值传递给父级。有a neat library可以为您提供兼容性。
  3. 接收父级中的值并相应地调整iframe大小。
  4. 同样,这可能有些过分,但考虑到解决方案已经过测试,可以完全按照之间的不同安全沙箱进行操作,如果是iframe,这也应该是更简单的情况是在同一个域。

    话虽这么说,如果他们在同一个域上(而不是小部件/不可混淆的第三方内容),真的需要一个iframe吗?听起来只是设置jQuery来发出ajax请求并用新数据填充容器。

答案 1 :(得分:1)

这似乎是一个相当直接的问题,所以我不确定为什么会有这么奇怪的答案,所以也许我完全错过了这个问题,但这里有我的解决方案,一个是x-domain而另一个是&n& #39; t(注意:开放/写入/关闭,只是为了模拟服务器交互,使其更加明显......)

第一个x-domain风格:

// METHOD #1: postMessage() x-domain (chrome, ff, ie8+, safari, etc)
var d = document,
    iframe = d.createElement('iframe');
iframe.height = 0;
d.getElementsByTagName('body')[0].appendChild(iframe);

window.onmessage = function(msg) { 
  iframe.height = parseInt(msg.data, 10);
};

var fd = iframe.contentDocument || iframe.contentWindow.document;
fd.open();
fd.write('<!DOCTYPE ht' + 'ml><ht' + 'ml><he' + 
         'ad><scri' + 'pt>' +
         'window.onload = function(){' +

         'var db = document.body,' +
         'de = document.documentElement;' +

         'window.parent.postMessage(' + 
           'Math.max(db.scrollHeight, de.scrollHeight, db.offsetHeight, de.offsetHeight, db.clientHeight, de.clientHeight),' +
           '"*"' +
         ');' +

         '};</scr' + 'ipt></he' + 'ad><bo' + 
         'dy style="background:#afa"><div style="border:s' +
         'olid 1px black;padding:50px;line-height:50px">method #1: x-domain<b' +
         'r />test<br />test</div></bo' + 'dy></ht' + 
         'ml>');
fd.close();

下一个更兼容的相同域版本:

// METHOD #2: manually same-domain (all browsers? [with tweaks] )

var iframe2 = d.createElement('iframe');

iframe2.height = 0;

iframe2.onload = function() {
  var xfd = iframe2.contentDocument || iframe2.contentWindow.document,
      db = xfd.body,
      de = xfd.documentElement;

  iframe2.height = Math.max(db.scrollHeight, de.scrollHeight, db.offsetHeight, de.offsetHeight, db.clientHeight, de.clientHeight);

};

d.getElementsByTagName('body')[0].appendChild(iframe2);

fd = iframe2.contentDocument || iframe2.contentWindow.document;
fd.open();
fd.write('<!DOCTYPE ht' + 'ml><ht' + 'ml><he' + 
         'ad></he' + 'ad><bo' + 
         'dy style="background:#aaf"><div style="padding:50px;line-height:50px;border:s' +
         'olid 1px black;">method #2: same domain<b' +
         'r />test2<br />test2</div></bo' + 'dy></ht' + 
         'ml>');
fd.close();

你可以在这里看到它:http://jsbin.com/ifevad

我希望这有助于确认

答案 2 :(得分:0)

这个相同的示例适用于我,在Chrome 17中,在Windows上,使用给定的html文件:

的index.html:

<html>
<head>
</head>
<body>
<iframe src="index2.html" id="test">
</iframe>
</body>
</html>

index2.html

<html>
<head>
</head>

<body>
<div id="test_div">
    Ohai
</div>
</body>
</html>

然后我在chrome开发者窗口中使用了它:

i = document.getElementById('test')
doc = i.contentWindow.document
data=doc.getElementById('test_div');
i.style.height = data.offsetHeight + 'px'

唯一的问题是它直接打开.html文件时无效 - 我必须启动一个Web服务器。 我用过它(这是默认的Python服务器):

server.py

import SimpleHTTPServer
import SocketServer

PORT = 8080

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()