如何设置iframe高度自适应在跨域情况下的可用方法


Posted in Javascript onSeptember 06, 2013

在页面上使用iframe来动态加载页面内容是网页开发中比较常见的方法。在父页面中给定一个不带滚动条的iframe,然后对属性src指定一个可加载的页面,这样当父页面被访问的时候,子页面可以被自动加载。iframe的高度需要根据子页面的实际高度来进行调整。如果iframe的高度小于子页面的实际高度,超出的部分无法显示;相反,如果iframe的高度过高,则页面上会出现大量的空白区域。我们可以通过属性或者CSS来设置iframe的高度,当不确定子页面内容的高度时,也可以通过脚本来进行动态指定。但是如果子页面不在同一域中怎么办?这时候脚本没有办法获取到子页面的高度,存在JavaScript跨域的问题!

如题所述,本文在介绍可用方法的同时,也向大家询问除下文列出来的方法之外是否还有其它方法可寻?

通过属性或CSS来设置iframe的高度这里就不再具体介绍了。首先来看看如何通过脚本进行设置。

function ChangeFrameHeight(id) { 
var count = 1; (function() { 
var frm = document.getElementById(id); 
var subWeb = document.frames ? document.frames[id].document : frm.contentDocument; 
if (subWeb != null) { 
var height = Math.max(subWeb.body.scrollHeight, subWeb.documentElement.scrollHeight); 
frm.height = height; 
} 
if (count < 3) { 
count = count + 1; 
window.setTimeout(arguments.callee, 2000); 
} 
})(); 
}

假设iframe子页面和父页面都在同一域内,通过该脚本可以对给定id的iframe高度进行动态调整。为了防止父页面在子页面之前加载完成,该函数会每隔2秒重新执行一次,一共执行3次。极端情况下子页面的加载速度会慢于父页面,可适当对执行次数和时间做调整。
<iframe frameborder="0" width="450" marginheight="0" marginwidth="0" scrolling="no" id="frm1" name="frm1" src="abc.html" onload="ChangeFrameHeight('frm1')"></iframe>

如果遇到子页面跨域的问题,可通过HTML5的postMessage来实现,但前提是子页面需要主动向父页面发送信息。下面是子页面部分:
<!DOCTYPE html> 
<head> 
</head> 
<body onload="parent.postMessage(document.body.scrollHeight, 'http://target.domain.com');"> 
<h3>Got post?</h3> 
<p>Lots of stuff here which will be inside the iframe.</p> 
</body> 
</html>

在父页面中获取到子页面传递过来的信息,然后对iframe的高度进行调整。
<script type="text/javascript"> 
function resizeCrossDomainIframe(id, other_domain) { 
var iframe = document.getElementById(id); 
window.addEventListener('message', function(event) { 
if (event.origin !== other_domain) return; // only accept messages from the specified domain 
if (isNaN(event.data)) return; // only accept something which can be parsed as a number 
var height = parseInt(event.data) + 32; // add some extra height to avoid scrollbar 
iframe.height = height + "px"; 
}, false); 
} 
</script> <iframe src='abc.html' id="frm1" onload="resizeCrossDomainIframe('frm1', 'http://example.com');"> 
</iframe>

有关如何使用HTML5的postMessage()方法可以查看这篇文章http://dev.w3.org/html5/postmsg/#web-messaging

但是在大多数情况下,iframe中所引用的子页面除了和父页面不在同一域之外,我们可能根本无法对子页面进行任何操作,或者说子页面根本没有提供Corss-document messaging功能。在这种情况下,通过postMessage()方法也无法获取到子页面的任何信息。由于无法和子页面进行任何交互,也就没有办法得知子页面的document对象,从未无法根据子页面的实际高度来调整父页面iframe的height属性了。

目前没有其它实际有效的方法来处理上面遇到的问题。默认情况下可以给iframe指定一个比较大的高度,这样假设所引用的子页面内容不会超出范围,除了在页面上会留下部分空白区域外,内容显示基本不会有问题。

那是否还存在其它比较有效的解决方法呢?期待!

Javascript 相关文章推荐
一段实时更新的时间代码
Jul 07 Javascript
jQuery lazyload 的重复加载错误以及修复方法
Nov 19 Javascript
JS中confirm,alert,prompt函数区别分析
Jan 17 Javascript
JavaScript去除空格的三种方法(正则/传参函数/trim)
Feb 06 Javascript
js显示当前日期时间和星期几
Oct 22 Javascript
jQuery事件绑定用法详解(附bind和live的区别)
Jan 19 Javascript
JS Attribute属性操作详解
May 19 Javascript
JS实现焦点图轮播效果的方法详解
Dec 19 Javascript
node.js与C语言 实现遍历文件夹下最大的文件,并输出路径,大小
Jan 20 Javascript
微信小程序实现一个简单swiper代码实例
Dec 30 Javascript
原生JS实现留言板
Mar 26 Javascript
Vue实现购物车基本功能
Nov 08 Javascript
JQuery对id中含有特殊字符的转义处理示例
Sep 06 #Javascript
关于jQuery中.attr()和.prop()的问题探讨
Sep 06 #Javascript
正负小数点后两位浮点数实现原理及代码
Sep 06 #Javascript
jQuery实现列表自动循环滚动鼠标悬停时停止滚动
Sep 06 #Javascript
jquery实现metro效果示例代码
Sep 06 #Javascript
JS去除数组重复值的五种不同方法
Sep 06 #Javascript
JavaScript判断密码强度(自写代码)
Sep 06 #Javascript
You might like
杏林同学录(六)
2006/10/09 PHP
php使用mysqli向数据库添加数据的方法
2015/03/20 PHP
php中session定期自动清理的方法
2015/11/12 PHP
PHP使用SOAP调用API操作示例
2018/12/25 PHP
jquery select操作的日期联动实现代码
2009/12/06 Javascript
vs2003 js文件编码问题的解决方法
2010/03/20 Javascript
js弹出层包含flash 不能关闭隐藏的2种处理方法
2013/06/17 Javascript
JavaScript学习笔记之JS对象
2015/01/22 Javascript
javascript制作2048游戏
2015/03/30 Javascript
Javascript中神奇的this
2016/01/20 Javascript
Bootstrap 模态框(Modal)插件代码解析
2016/12/21 Javascript
浅谈ECMAScript6新特性之let、const
2017/08/02 Javascript
详解从0开始搭建微信小程序(前后端)的全过程
2019/04/15 Javascript
js 计算月/周的第一天和最后一天代码
2020/02/01 Javascript
《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解
2020/04/08 Javascript
Vue开发中常见的套路和技巧总结
2020/11/24 Vue.js
[01:04:48]VGJ.S vs TNC Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[47:10]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第二场 12.16
2020/12/18 DOTA
python自动发邮件总结及实例说明【推荐】
2019/05/31 Python
对python 中re.sub,replace(),strip()的区别详解
2019/07/22 Python
python实现单张图像拼接与批量图片拼接
2020/03/23 Python
Python使用graphviz画流程图过程解析
2020/03/31 Python
Python selenium爬虫实现定时任务过程解析
2020/06/08 Python
Python DES加密实现原理及实例解析
2020/07/17 Python
Python如何使用ConfigParser读取配置文件
2020/11/12 Python
小区门卫工作职责
2013/12/14 职场文书
高中班长自我鉴定
2013/12/20 职场文书
20年同学聚会邀请函
2014/02/04 职场文书
国际金融专业自荐信
2014/07/05 职场文书
国际贸易毕业生求职信
2014/07/20 职场文书
党代会心得体会
2014/09/04 职场文书
关于成绩下滑的自我检讨书
2014/09/20 职场文书
三八红旗手主要事迹材料
2015/11/04 职场文书
小程序实现文字循环滚动动画
2021/06/14 Javascript
golang的文件创建及读写操作
2022/04/14 Golang
Apache SeaTunnel实现 非CDC数据抽取
2022/05/20 Servers