如何设置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 相关文章推荐
FireFox中textNode分片的问题
Apr 10 Javascript
jQuery右键菜单contextMenu使用实例
Sep 28 Javascript
分页栏的web标准实现
Nov 01 Javascript
jquery实现保存已选用户
Jul 21 Javascript
js闭包所用的场合以及优缺点分析
Jun 22 Javascript
js图片翻书效果代码分享
Aug 20 Javascript
JavaScript实现页面跳转的方式汇总
May 16 Javascript
Cookies 和 Session的详解及区别
Apr 21 Javascript
vue点击input弹出带搜索键盘并监听该元素的方法
Aug 25 Javascript
BootstrapValidator实现表单验证功能
Nov 08 Javascript
Ant Design Pro 下实现文件下载的实现代码
Dec 03 Javascript
JS实现公告上线滚动效果
Jan 10 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
用PHP调用Oracle存储过程的方法
2008/09/12 PHP
Blitz templates 最快的PHP模板引擎
2010/04/06 PHP
PHP的cURL库简介及使用示例
2015/02/06 PHP
详解Laravel设置多态关系模型别名的方式
2019/10/17 PHP
精通Javascript系列之数据类型 字符串
2011/06/08 Javascript
JavaScript 参数中的数组展开 [译]
2012/09/21 Javascript
关于Jquery操作Cookie取值错误的解决方法
2013/08/26 Javascript
JSuggest自动匹配下拉框使用方法(示例代码)
2013/12/27 Javascript
$(document).ready(function() {})不执行初始化脚本
2014/06/19 Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
2014/06/24 Javascript
Js 正则表达式知识汇总
2014/12/02 Javascript
jQuery实现复选框成对选择及对应取消的方法
2015/03/03 Javascript
js+CSS实现模拟华丽的select控件下拉菜单效果
2015/09/01 Javascript
jquery.cookie.js用法实例详解
2015/12/25 Javascript
jQuery自定义元素右键点击事件(实现案例)
2017/04/28 jQuery
VUE 更好的 ajax 上传处理 axios.js实现代码
2017/05/10 Javascript
vue-cli项目中怎么使用mock数据
2017/09/27 Javascript
[04:13]2018国际邀请赛典藏宝瓶Ⅱ饰品一览
2018/07/21 DOTA
C#返回当前系统所有可用驱动器符号的方法
2015/04/18 Python
Python的Django框架下管理站点的基本方法
2015/07/17 Python
python实现斐波那契数列的方法示例
2017/01/12 Python
Python读写/追加excel文件Demo分享
2018/05/03 Python
Python Numpy数组扩展repeat和tile使用实例解析
2019/12/09 Python
Python合并2个字典成1个新字典的方法(9种)
2019/12/19 Python
flask 实现上传图片并缩放作为头像的例子
2020/01/09 Python
python使用dlib进行人脸检测和关键点的示例
2020/12/05 Python
css3实现一款模仿iphone样式的注册表单
2013/03/20 HTML / CSS
HTML5 Web存储方式的localStorage和sessionStorage进行数据本地存储案例应用
2012/12/09 HTML / CSS
AJAX应用和传统Web应用有什么不同
2013/08/24 面试题
五年后的职业生涯规划
2014/03/04 职场文书
技术比武方案
2014/05/19 职场文书
详解thinkphp的Auth类认证
2021/05/28 PHP
使用Djongo模块在Django中使用MongoDB数据库
2021/06/20 Python
36个正则表达式(开发效率提高80%)
2021/11/17 Javascript
Python Pygame实战在打砖块游戏的实现
2022/03/17 Python
详解Python中的for循环
2022/04/30 Python