如何设置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 相关文章推荐
javascript中强制执行toString()具体实现
Apr 27 Javascript
node.js Web应用框架Express入门指南
May 28 Javascript
Jquery节点遍历next与nextAll方法使用示例
Jul 22 Javascript
js仿支付宝填写支付密码效果实现多方框输入密码
Mar 09 Javascript
jQuery实现的多滑动门,多选项卡效果代码
Mar 28 Javascript
在React中如何优雅的处理事件响应详解
Jul 24 Javascript
easyui datagrid 表格中操作栏 按钮图标不显示的解决方法
Jul 27 Javascript
vue使用codemirror的两种用法
Aug 27 Javascript
layui点击弹框页面 表单请求的方法
Sep 21 Javascript
vue props对象validator自定义函数实例
Nov 13 Javascript
Vue路由守卫及页面登录权限控制的设置方法(两种)
Mar 31 Javascript
vue element实现表格合并行数据
Nov 30 Vue.js
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
成本8450万,票房仅2亿,口碑两极分化,又一部DC电影扑街了
2020/04/09 欧美动漫
使用PHPMyAdmin修复论坛数据库的图文方法
2012/01/09 PHP
smarty自定义函数htmlcheckboxes用法实例
2015/01/22 PHP
PHP下SSL加密解密、验证、签名方法(很简单)
2020/06/28 PHP
jquery的ajaxSubmit()异步上传图片并保存表单数据演示代码
2013/06/04 Javascript
AngularJS入门知识之MVW类框架的编程思想探讨
2014/12/08 Javascript
JavaScript获取页面中超链接数量的方法
2015/11/09 Javascript
AngularJS Module方法详解
2015/12/08 Javascript
详解nodejs通过代理(proxy)发送http请求(request)
2017/09/22 NodeJs
AngularJs用户登录问题处理(交互及验证、阻止FQ处理)
2017/10/26 Javascript
react学习笔记之state以及setState的使用
2017/12/07 Javascript
JS正则表达式常见用法实例详解
2018/06/19 Javascript
vue3.0 CLI - 2.1 -  component 组件入门教程
2018/09/14 Javascript
vue父组件给子组件的组件传值provide inject的方法
2019/10/23 Javascript
JavaScript进制转换实现方法解析
2020/01/18 Javascript
[01:07:19]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第一场
2018/04/06 DOTA
举例讲解Python设计模式编程的代理模式与抽象工厂模式
2016/01/16 Python
Django接受前端数据的几种方法总结
2016/11/04 Python
python中解析json格式文件的方法示例
2017/05/03 Python
Python探索之实现一个简单的HTTP服务器
2017/10/28 Python
JS设计模式之责任链模式实例详解
2018/02/03 Python
pandas 使用apply同时处理两列数据的方法
2018/04/20 Python
python中对数据进行各种排序的方法
2019/07/02 Python
python matplotlib折线图样式实现过程
2019/11/04 Python
Python笔记之代理模式
2019/11/20 Python
pytorch动态网络以及权重共享实例
2020/01/06 Python
python实现串口通信的示例代码
2020/02/10 Python
Python正则re模块使用步骤及原理解析
2020/08/18 Python
HTML5中的postMessage API基本使用教程
2016/05/20 HTML / CSS
韩国知名的家庭购物网站:CJmall
2016/08/01 全球购物
英国顶级足球鞋的领先零售商:Lovell Soccer
2019/08/27 全球购物
难忘的一课教学反思
2014/04/30 职场文书
校园文明倡议书
2014/05/16 职场文书
乔布斯斯坦福大学演讲稿
2014/05/23 职场文书
淮海战役观后感
2015/06/11 职场文书
Vue中foreach数组与js中遍历数组的写法说明
2021/06/05 Vue.js