iframe高度动态自适应

转载 2016年08月30日 17:46:55

一、前言碎碎念

我从来对iframe就没有什么好感,对其基本上是不屑一顾。但是人在江湖,身不由己。经理发话,新功能使用iframe实现,没办法,只好折腾,两大烦人的东西,一是带遮罩的弹框提示,而是iframe高度问题。前一个烦人的问题使用其他形式的提示来规避,后一人扰人的问题确实没有什么经验,花了点时间折腾了下,基本上实现了效果,跨域没问题,兼容性也没问题,于是,写个小文备忘下,下次再使用的时候就到这儿拷贝核心代码。

口碑UED有篇大米的“再谈iframe自适应高度”一文,可以看看,虽然貌似兼容性没有个调调。此文评论有个如下的链接地址:http://css-tricks.com/examples/iFrameResize/crossdomain.php,跨域且比较兼容的iframe高度定时自动变化的demo,但是,此demo中的js像个老太太一样啰哩吧嗦,裹脚布般又臭又长,于是,对js脚本重新修身整形,把老太太变成了苗条妙龄少女。

二、原理简述

本文展示的实现方法需要父页面和框架子页面相互配合。框架页面的任务就是向父页面传递其高度值,父页面的任务就是获取这个高度,然后改变iframe的高度。这个道理不难理解,儿子想买双增高鞋,但是由于没有经济实力买不起,于是就告诉他的老爸:“老爸,我要买双40码的增高20厘米的增高鞋”,老爸收到了这个信息,就可以掏钞票给儿子买鞋让儿子增高。

关键是这个讯息如何传递。因为这个老爸是后爸(跨域),儿子心理上有障碍,说不出口。这时候,就需要媒介来帮忙传递讯息,例如儿子的偶噶桑(お母さん)。那么,在本文中,这个协助传递高度信息的媒介是什么呢?答案就是地址栏的锚点。如下图:
锚点传递iframe高度值 张鑫旭-鑫空间-鑫生活

将高度以如下锚点形式传递:

#height=372

iframe页面内部通过window.top.location属性修改父页面的地址栏地址,从而将带有高度值的地址传递过去。地址栏地址在只增加锚点的情况下是不会刷新页面的、或是产生跳转什么的。

在父页面,需要设定一个定时器,例如每200毫秒去获取iframe的高度,如果高度改变,则取修改iframe的高度。您可以会对此做法的效率有所疑问,根据大米的测试,同时开5个窗口(IE6、IE7、FF、Opera、Safari)执行这个代码,不会对CPU有什么影响,甚至调整到2ms,也没影响(基本维持在0%占用率)。所以,对于效率基本上不用担心。

三、iframe页面跳转和无跳转实例

通过window.top.location修改父页面的地址栏地址,而不刷新页面,显然是需要得知父页面的页面绝路地址的。同样可以通过window.top.location获取,一了百了。

于是,父子在地址栏和锚点媒介帮助下打情骂俏,产生交流与互动,实现高度自适应的交互。

这两个实例父页面的js代码和iframe页面中的都是一样的,所以,统一展示,如下:

首先是子页面,子页面的任务就是传递高度而已,假设现在已经得到iframe当前的页面高度是1294(单位像素,省略)。则核心部分的js代码就是:

//此处window.top.location获取主页面地址的方法有跨域权限的问题,替代方法参见下面的补充。
//或者这里直接使用死地址,即hostUrl = "http://www.host.com/",这是没有任何跨域的问题的。
var hostUrl = window.top.location.toString().split("#")[0];
if (hostUrl) {
    hostUrl += "#height=" + 1294;
    window.top.location = hostUrl;
}

补充于2010-12-08
根据evonli的建议与提醒,iframe页面的高度传递不需要上面这么多代码,直接改变hash就可以了,如下:

window.top.location.hash = "#height=" + 1294;

但是,在IE浏览器下(以及Chrome下),貌似此方法,不支持跨域的情况(会报权限错误)。看来可能还是得使用iframe的src传递父页面地址,后者是通过cookie,或者其他形式,或是是写死的页面地址等形式。

目前看来,貌似只有(window.top.location = 父页面地址 + 锚点)无兼容性问题,且支持跨域。所以,我开始理解为何crossdomain.php父页面的地址要通过iframe的src地址传递的了。但是,此方法似乎只适用于iframe页面无跳转的情况。因为发生跳转后,iframe地址就变了。

通过iframe传递父页面地址方法类似下面的代码,其中iframe指iframe的DOM对象。

var href = window.location.href, index = href.indexOf("#");
if (index !== -1) {
    href = href.slice(0, index);
}
iframe.src = iframe.src + "#" + href;

iframe子页面可以通过:

window.location.hash.slice(1);

获得父页面的地址栏的绝对地址。然后,就是改变父页面的地址:

var hostUrl = window.location.hash.slice(1);
hostUrl += "#height=" + 1294;
window.top.location = hostUrl;

//zxx:补充内容结束

下面是改变iframe的高度值, 理论上,则iframe以通过锚点附了高度值的url地址应该类似下面,http://www.google.com#height=1294,于是工作很简单,就是得到这个1294就可以了,于是有类似下面的代码:

var iframeHeight = function() {    
    var hash = window.location.hash.slice(1);
    if (hash && /height=/.test(hash)) {
        iframe.height = hash.replace("height=", "");
    }
    setTimeout(iframeHeight, 200);
};
iframeHeight();

最后就有类似下面的效果,默认iframe高度120:
iframe默认高度 张鑫旭-鑫空间-鑫生活

点击iframe页面中的“显示图片”按钮后,很快的,iframe高度自动跟随增加,如下图所示:
iframe高度增加后 张鑫旭-鑫空间-鑫生活

四、开心网的做法

开心网第三方开发的组件也是以iframe框架的形式嵌入的。其高度自适应实现原理大致如下。

内嵌的iframe动态生成一个以开心网提供的页面地址的高宽为0且隐藏的iframe,此iframe页面地址与开心网主页面是同域的,于是,其中iframe页面内部的脚本就可以对主页面进行操作了(动态改变第三方iframe的高度)。
开心网iframe高度原理 张鑫旭-鑫空间-鑫生活

var t = document.createElement("div");
t.innerHTML = '<iframe style="display:none;" src="http://www.kaixin001.com/interface/domain_proxy.php? para=1294&type=3'" scrolling="no" height="0" width="0"></iframe>';
document.body.appendChild(t.firstChild);

五、结语

本着简单示范的目的,文中展示的代码算是相对比较简洁的。但是,实际使用的时候,要考虑一些细节,或是性能上的调整。例如,缓存当前高度,只有高度改变才去修改iframe的高度(这个实例中并没有体现)。

总的来说应该是相当易懂的。window.top.location为中介,iframe把高度亦锚点的形式告知父页面,父页面通过此高度修改iframe的高度值。寥寥十几行js代码,没有什么复杂逻辑和处理,一些简单的字符串处理。

最后,对iframe基本上没有什么研究,所以文中可能有表述不准确的地方,或是实现方法上有潜在问题,欢迎大家指正,不甚感谢。就这些。

真正的iframe 自适应高度,动态高度 js

百度搜索出来一大堆文章,我看了下没有一个合意的,什么叫动态?就是iframe加载的时候高度慢慢变啊,用户看到了才知道你的内容慢慢加载啊。网上说的都是在onload里设置高度,可是onload是加载完毕...
  • lanmanck
  • lanmanck
  • 2015年06月16日 19:10
  • 61461

关于iframe自适应高度的方法总结

不带边框的iframe因为能和网页无缝的结合从而不刷新页面的情况下更新页面的部分数据成为可能,可是 iframe的大小却不像层那样可以“伸缩自如”,所以带来了使用上的麻烦,给iframe设置高度的时候...
  • hj7jay
  • hj7jay
  • 2016年06月15日 00:08
  • 2839

真正的让iframe自适应高度 兼容多种浏览器随着窗口大小改变

今天有朋友问到我关于“iframe自适应高度”的问题,原本以为是很简单的问题,没想到折腾了20分钟才搞定。期间遇到几个问题,要么是高度自适应了,但是当窗口改变时会出现滚动条。也就是当窗口放大时ifra...
  • alex8046
  • alex8046
  • 2016年05月19日 18:37
  • 139349

原创,真正解决iframe高度自适应的问题.兼容各浏览器

在Google输入关键字"iframe自适应高度"之后你会发现有"找到约 153,000 条结果",我大概的看了一下,发现基本上就那两三篇文章被转载来转载去.真正解决问题的没有.那我今天就不和他们同流...
  • sibang
  • sibang
  • 2014年08月21日 16:48
  • 1297

iframe 高度设置、iframe 自适应高度方法总结

所谓iframe自适应高度,就是,基于界面美观和交互的考虑,隐藏了iframe的border和scrollbar,让人看不出它是个iframe。如果iframe始终调用同一个固定高度的页面,我们直接写...
  • alex8046
  • alex8046
  • 2016年05月19日 18:30
  • 5019

跨域iframe高度自适应的多种方法

当 A页面中嵌入一个新页面B时,我们常常会使用 iframe来实现。当 A页面和 B页面在不同的域名下时,A页面就不能使用 Javascript 访问到的 B页面的高度,那么该如何解决这类问题呢?直接...
  • aaronpan21
  • aaronpan21
  • 2016年04月25日 21:42
  • 4056

html iframe自适应高度的多种方法方法小结

对于自适应高度的代码有很多,可效率什么的考虑进来好代码就不多见了,不过思路倒是差不多的...
  • qilixiang012
  • qilixiang012
  • 2014年07月21日 16:48
  • 1433

iframe高度自适应及隐藏滚动条

在工作中,我们可能会遇到自己公司和其他的公司达成合作关系,从而共同开发某个项目。而这时候,我们可能就需要在自己的网站上嵌入别人做好的页面。而这种情况下,我们一般都会选择去使用iframe达到我们的目的...
  • qq_33401924
  • qq_33401924
  • 2016年12月22日 09:56
  • 845

iframe高度自适应、载入完成事件

高度自适应 ------------------------------------------------- 方法一: 经典代码 iFrame 自适应高度,在IE6/IE7/IE8...
  • rdhj5566
  • rdhj5566
  • 2014年07月31日 09:19
  • 1183

关于iframe在chrome自适应高度兼容性问题

首先了解两个概念,contentWindow和contentDecument,可以在子级iframe设置父级和孙级iframe高度。contentWindow兼容各个浏览器,可取得子窗口的window...
  • u014802309
  • u014802309
  • 2015年08月27日 16:10
  • 3090
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iframe高度动态自适应
举报原因:
原因补充:

(最多只允许输入30个字)