loading...

Iframe高度自适应(兼容IE/Firefox、同域/跨域)

发布时间:January 20, 2009 分类:CSS

PHP下载CSS文件中的图片

Dubai, I am comming

在实际的项目进行中,很多地方可能由于历史原因不得不去使用iframe,包括目前正火热的应用开发也是如此。

随之而来的就是在实际使用iframe中,会遇到iframe高度的问题,由于被嵌套的页面长度不固定而显示出来的滚动条,不仅影响美观,还会对用户操作带来不便。于是自动调整iframe的高度就成为本文的重点。

采用JavaScript来控制iframe元素的高度是iframe高度自适应的关键,同时由于JavaScript对不同域名下权限的控制,引发出同域、跨域两种情况。

同域时Iframe高度自适应
下面的代码兼容IE/Firefox浏览器,控制id为“iframeid”的iframe的高度,通过JavaScript取得被嵌套页面最终高度,然后在主页面进行设置来实现。

代码如下,可复制。另外,请注意此解决方案仅供同域名下使用。

<script type="text/javascript">
function SetCwinHeight(){
var iframeid=document.getElementById("iframeid"); //iframe id
if (document.getElementById){
if (iframeid && !window.opera){
if (iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight){
iframeid.height = iframeid.contentDocument.body.offsetHeight;
}else if(iframeid.Document && iframeid.Document.body.scrollHeight){
iframeid.height = iframeid.Document.body.scrollHeight;
}
}
}
}
</script>
<iframe width="100%" id="iframeid" onload="Javascript:SetCwinHeight()" height="1" frameborder="0" src="kimi.php"></iframe>

跨域时Iframe高度自适应
在主页面和被嵌套的iframe为不同域名的时候,就稍微麻烦一些,需要避开JavaScript的跨域限制。

原理:现有iframe主页面main.html、被iframe嵌套页面iframe.html、iframe中介页面agent.html三个,通过main.html(域名为http://www.ccvita.com)嵌套iframe.html(域名为:http://www.phpq.net),当用户浏览时执行iframe.html中的JavaScript代码设置iframeC的scr地址中加入iframe页面的高度,agent.html(域名为:http://www.ccvita.com)取得传递的高度,通过JavaScript设置main.html中iframe的高度。最终实现预期的目标。

演示地址:http://www.ccvita.com/usr/uploads/demo/iframe/main.html
代码下载:http://www.ccvita.com/usr/uploads/demo/iframe/iframe.zip

iframe主页面main.html

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>iframe主页面</title></head>
<body>
<div style="border:1px solid #ccc;padding:10px;"><iframe id="frame_content" name="frame_content" src="iframe.html" width="100%" height="0" scrolling="no" frameborder="0"></iframe></div><br />尾部<br /></body>
</html>

iframe嵌套页面iframe.html

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>被iframe嵌套页面</title></head>
<body>
文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><iframe id="iframeC" name="iframeC" src="" width="0" height="0" style="display:none;" ></iframe>
<script type="text/javascript">
function sethash(){
hashH = document.documentElement.scrollHeight;
urlC = "agent.html";
document.getElementById("iframeC").src=urlC+"#"+hashH;
}
window.onload=sethash;
</script>
</body>
</html>

iframe中介页面agent.html

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>iframe中介页面</title></head>
<body>
<script>
function pseth() {
var iObj = parent.parent.document.getElementById('frame_content');
iObjH = parent.parent.frames["frame_content"].frames["iframeC"].location.hash;
iObj.style.height = iObjH.split("#")[1]+"px";
}
pseth();
</script>
</body>
</html>



UPDATE:长期以来一直有网友说方案不能跨域,今天我重新又测试了下,确定在IE6、IE7、IE8、IE9、Firefox全系列、Chrome全系列均可以成功跨域控制高度。请注意以下要点
  • 第一,修改main.html文件中iframe的src地址为需要跨域的域名(比如ccvita.sinaapp.com)
  • 第二,修改iframe.html文件中的urlC值为源域名(比如www.ccvita.com)这点最重要

Tags: 跨域, iframe


已有 97 条评论 »

  1. FeiMuyu FeiMuyu

    跨域的那个你没测试吧

    1. kimi kimi

      @FeiMuyu,已经在项目中使用了啊,莫非我写错了,等我从迪拜回去了,再仔细测试下。

  2. aimee aimee

    最近一直在找这个,但都不能跨域,偶然在你这发现啦,那个高兴呀,突然看到这个"等我从迪拜回去了,再仔细测试下"有点失落,我先自己测测吧。

    1. kimi kimi

      @aimee, 我测试过了,是可以用的,你可以下载http://www.ccvita.com/usr/uploads/demo/iframe/iframe.zip测试。

  3. aimee aimee

    嗯,昨天测试用了,好像FF下不兼容,不会自动收缩

    1. kimi kimi

      @aimee, 我测试过了,可以啊~~

  4. aimee aimee

    我好好用了下,跨域还是有问题,在同一个域中,不加高度参数可以,但在不同域中不加高度参数会给出一个默认的不符合要求的高度,如果加高度参数什么都显示不出来,可能是那个获取高度的agent没取到

  5. ynu ynu

    这是跨域的吗?

    1. kimi kimi

      @ynu, 是的,是跨域的

      1. @tvriawnui @tvriawnui

        @kimi, 不行,跨域名就不行。

  6. lingfei lingfei

    不可跨域名

    1. kimi kimi

      @lingfei, 在测试的时候,请将其中被iframe的页面放在其他域名下测试即可。

  7. 蹄子 蹄子

    经测试并不跨域,有一种跨域的方法是通过访问剪切板的方式,这都不完美。

  8. ganqiang ganqiang

    经过我的测试,楼主的方法的确是可以跨域的,但是不支持IE6呢,IE6下,仍然是不能访问的。郁闷ing,这个方法还是不完美的哦~~期待解决方法

  9. yll1125 yll1125

    我试过了,ie6下报错,ie8下可以,ie6下有解决办法么

  10. yefs yefs

    跨域这个好像是不行

  11. fshoy fshoy

    代码里,kimi可能路径表示不全

    main.html 与 agent.html 是必须同一个域里
    而iframe.html在另一个域

    我在IE6里通过~~~ 感谢kimi,这个令我头疼了很久

    1. kimi kimi

      @fshoy, 正解

      1. ss ss

        在IE6下没有权限怎么回事?

  12. tzb tzb

    很感谢,不介意转载记录下吧

  13. tzb tzb

    经测试 跨域 在IE6,IE7下均可行
    但FF3.5下有个小
    BUG:当上一个页面过长时,高度无法收回
    解决办法:浏览器为FF时将scrollHeight换为offsetHeight

    1. kuma kuma

      @tzb, 请问一下,你在IE6下测试时没有遇到权限问题吗?

      1. tzb tzb

        @kuma, 没有权限问题
        A页面有跨域的框架B, B下有跨回域A的C, C与A同域
        那么C就有权限操作A下的DOM了

      2. pigflyfly pigflyfly

        当上一个页面过长时,高度无法收回
        解决办法:浏览器为FF时将scrollHeight换为offsetHeight怎么做啊?具体。谢谢急着等答案

  14. ss ss

    跨域的确实不行,ie6

  15. papaya papaya

    如果说。嵌套页面iframe.html这个页面我没有修改的权限。
    现在公司要搞个访问别人链接的,我们目标页面的来源基本都是新浪,嘀咕,这种地方。
    是不是无解=_=!!

    1. kimi kimi

      @papaya, 这样的话,你可以参考比如人人网的分享页面,或者UCH的分享是如何做的

    2. 工

      @papaya, 同样的问题,这个方法实现不了。

  16. agent agent

    请问,agent.html是做什么用的。
    我没看出它要怎么用?在哪儿调用?
    能否说的详细一点,谢了。。。

  17. yang189 yang189

    有兴趣的朋友可以研究下这个站:http://www.freedns.ws/en/
    无刷新网页读取信息!我把代码复制过来始终不能显示!!达不到原站的那效果!!
    也不知道是怎么一回事?那位知道给个答案吧…………

  18. 朱宇晨 朱宇晨

    被iframe的页面不能自己添加代码怎么办啊!

    1. shiny shiny

      我是来围观的

      1. shiny shiny

        还能更挤一点吗

        1. shiny shiny

          我再挤!

          1. shiny shiny

            挤死我了

            1. Journey Journey

              @shiny, 挤挤更健康

    2. soley soley

      @朱宇晨, 我再来凑凑热闹

      1. kin kin

        到底能不能实现跨域啊,再挤一下 。。

        1. eer eer

          汗死

          1. hahahaha hahahaha

            @eer, 好热啊

            1. 把我包住了 把我包住了

              把我包住了

            2. IM鑫爷 IM鑫爷

              JJ挤疼了。

            3. jj jj

              @IM鑫爷, 汗

            4. ice ice

              @jj, 兄弟们我来了

            5. qzp qzp

              @ice, 来晚了

  19. zys1234 zys1234

    ie6怎么解决呢,期待中。。。

  20. tommy tommy

    为什么我的在FF下无效?我的FF版本为:3.6.7。
    还有在谷歌下也无效。

  21. asdf asdf

    不操作子页面
    不能实现……

  22. 模板之家 模板之家

    今天找了一下午,终于找到了哈,谢谢楼主!

  23. 工

    还是没有用,被嵌入的页面是不能改的,是别人的网站。这个方法根本实现不了。

  24. 小哥 小哥

    NB跨域成功。

  25. kuma kuma

    用了一下,加了个判断,IE下用scrollHeight,FIREFOX下用offsetHeight,IE7,8和FIREFOX都没问题。但是IE6下一直提示没有权限,请问有什么解决方法吗?谢谢。

  26. andy andy

    FF不能使用~

  27. arlee arlee

    谢谢楼主

  28. div+css div+css

    很好的教程分享,谢谢。
    http://www.divcss6.com/

  29. jacky jacky

    很不错的教程,我测试了一下,没有问题,例子
    www.glyjw.com

  30. wangdavid wangdavid

    想问一下,就是如何加入判断,还有就是我这是IE8不能收回,而IE6和firefox安装上面说的可以实现,但是就是在ie8上不能。想请教一下,该如何改?急。先谢谢了!

  31. Gravatarer Gravatarer

    顶了,刚好用上

  32. 落落 落落

    && !window.opera,不知道楼主为什么在判断的时候加上前面的那部分,这样在opera中是不行的,如果去掉的话就可以了。不知道去掉以后是不是有其他的问题?

  33. lhyzhen lhyzhen

    你确定你测试了

  34. lhyzhen lhyzhen

    特提斯

  35. 爱你 爱你

    我的ie8不行

  36. zrben zrben

    试了跨不过去!IE的版本都通不过。FF就不试了

  37. leon leon

    楼主好人,小弟测试跨域失败啊,地址:
    http://blog.jnecw.com/mail/main.html

  38. leon leon

    跨过去了!原来是要在sethash()函数中的urlC添加域名!

  39. KissCss KissCss

    没有跨域,不跨域实现是没有难点的。

    1. kimi kimi

      更新了下文章,请看文章最后部分。

  40. Kubo Kubo

    测试了一下,还行。但是也有问题,似乎网页地址必须为IP地址时才能完整显示,如写域名就没反应。请问如何解决?谢谢!

    1. kimi kimi

      请看文章最后部分,特别强调注意的地方。

  41. dddddd dddddd

    哥们,你都能在frame_content框架中的iframe.html中写内容了,那还不能干什么?比如你的网站里的iframe里放一个人家www.163.com的网页,你也能在人家的网页里再加一个iframeC 和那段脚本?

    最好的方法,就是使用服务器端xmlhttprequest,在服务器端取得你要跨域访问的网页的内容,然后在输出到你的网页里,不过这又一个跨域访问的网页里的相对地址无效的麻烦。

    所以最好的解决方案是,在你自己的域名下建立一个agent.jsp等动态网页,在服务器端代理访问你的框架内的页面,你自己的网页的iframe的网址,写你自己这个agent.jsp的地址,同时把真正想访问的页面作为参数传递给agent.jsp,服务器端agent.jsp使用xmlhttprequest或者任何一个其他webclient取得你跨域访问的页面后,在这个页面的html里添加标志,改变这个页面的默认地址从你的域名到你跨域访问的域名。。。

    这个方案完全可以访问www.163.com这样的根本拿不到的网页的内容、。

  42. azure azure

    http和https跨域是实现不了的 已经实验证实 请博主注明

  43. yeti yeti

    博主的方法是能够兼容ie6的,说不能的网友请注意了:
    IETester下的ie6是不行的!真正的ie6是可以的~

    1. kimi kimi

      IETester确实没试过,感谢注明

  44. ed2kers ed2kers

    chrome 17.0.942.0 下不能用。(#‵′)凸

  45. tester23 tester23

    chrome 17.0.963.65 不能用。
    还有一点就是frame内页的body设置了overflow也是不能自适宜的

  46. yooly yooly

    经测试chrome 18.0.1025.151 m 同域不能用 ,有什么解决方法吗?

  47. yooly yooly

    知道了,chrome在服务器是可以的,本地不行

  48. 看看看客01 看看看客01

    什么垃/\圾代码 ..............

  49. cyousyun cyousyun

    ie6下跨域不行。“没有权限”弹框,火狐下ok。

  50. cyousyun cyousyun

    第一,修改main.html文件中iframe的src地址为需要跨域的域名(比如ccvita.sinaapp.com)
    第二,修改iframe.html文件中的urlC值为源域名(比如www.ccvita.com)这点最重要
    这两点什么意思?不明白哥们之乎者也,可以详细准确点么?

  51. cyousyun cyousyun

    解决iE6弹框“没有权限”,问题
    function pseth() {
    var iObj =top.document.getElementById('frame_content');
    iObjH = window.location.hash;
    iObj.style.height = iObjH.split("#")[1]+"px";
    }
    pseth();

  52. joan joan

    你好,我试了你的方法 。。。 在ie firefox 里面都在function pseth() {var iObj = parent.parent.document.getElementById('frame_content');这句这里没有权限访问 我不知道我调用的方式是否正确, 麻烦帮我看下:
    编码环境 mvc3
    主页面: 就放了一 iframe 在一个域
    子页面: 加有
    页面加载完后执行function sethash(){
    hashH = document.documentElement.scrollHeight;
    urlC = "http://192.168.19.28:9001/Home/Agent"; //我这里是写死的与主页面同一域
    document.getElementById("iframeC").src=urlC+"#"+hashH;
    }
    中间页面: 在主页面同一域下
    function pseth() {
    var iObj = parent.parent.document.getElementById('frame_content');
    iObjH = parent.parent.frames["frame_content"].frames["iframeC"].location.hash;
    iObj.style.height = iObjH.split("#")[1] + "px";
    }
    $(function () {
    pseth();
    });
    请问是不是哪里写的不正确 报没有权限访问的错误, 我想是主页面调用了子页面,然后从子页面又调回去的时候,出现的权限问题,如果我这句urlC = "http://192.168.19.28:9001/Home/Agent"; 不写域名的话 就会是子页面的域,请帮忙看看。。 谢谢!!

  53. joan joan

    我的邮箱:qiongyanfu@hotmail.com 有什么问题可以发我邮箱,谢谢

  54. LEO LEO

    下载的ZIP包里iframe.html里window.onload=sethash,sethash少了个s

  55. 轻风落叶 轻风落叶

    如果需要多个不同域名下的页面引用iframe的源文件,urlC那里的地址要怎么指定呀

  56. conan conan

    测试了.在IE6和IE8下面不可以的原因是 iframe.html里面的js代码 document.documentElement.scrollHeight 这句的问题.我换了一个jquery的$(document).height()就可以了.

  57. qnnp qnnp

    哈哈没有做不到的只有想不到的!!
    收藏了!

  58. Joker Joker

    获取页面hash的时候用window.location.hash,而不是parent.parent.frames["frame_content"].frames["iframeC"].location.hash来取。否则ie6会报没有权限的错误

  59. Drunk Drunk

    思路不错,楼主很有想法!感谢分享!

  60. 包子 包子

    后两句话仔细掂量一下
    然后打开找码在main.html的src加入需要跨域的域名
    再打开iframe.html把urlc这个变量改自己源域名的字符串
    OK成功
    然后加入博主上面的自适应代码
    OK
    这样就成功了,
    可能 有些人没有上面的自适应,看不到效果吧。

  61. xing xing

    IE6,IE8 跨域是失败的!
    FF,Chrome是可以的。

  62. 甄码农 甄码农

    你这个跨域的方案意味着被嵌套的页面是可控制的,但是这有点不现实呀。

  63. aa aa

    推荐个文章,解决iframe自适应高度并决jquery ajax获取数据后高度自适应问题
    http://www.suchso.com/projecteactual/jquery-ajax-iframe-resetiframeheight.html

  64. PHPerxuqin PHPerxuqin

    首先感谢博主的分享精神!今天本人将此办法用在实际项目中发现:第一:不适用ie6;第二:如果被iframe页面有Tab选项卡,其中一个选项卡中的内容过长,切换其它选项卡后,页面高度不能收回。期待博主改进,造福PHPer。

  65. junqis.net junqis.net

    怎么要在B站加代码的...............本来就是想把人家的网站调用过来!不可能叫人家在他网站加个代码让我调用的吧?www.junqis.net....

  66. OurELife OurELife

    博主,我想请教一下,我现在iframe调用的是别人的页面,我想高度自适应,我该怎么做?
    希望回复下,并通知我一下

  67. a a

    aaa

添加新评论 »

captcha
请输入验证码