项目中需要使用iframe嵌套另外一个项目的子页面,但是要求不能有滚动条,也就是说iframe的高度得根据嵌套页面的高度自适应
由于跨域,所以父子页面显然是不能通信的
第一个想到的是最近才接触到的window.name方式
代码片段:
- //这个方法解决不了子页面内链无法自适应高度的问题
- function autoHeightIFrameNavigate(iframeId,url) {
- var _frame = $('#' + iframeId);
- _frame.css('visibility', 'hidden');
- _frame.one('load', function(){
- $(this).one('load',function () {
- var msg = this.contentWindow.name; //得到值 这个值就是高度了
- this.contentWindow.location = url; //再次导向目标页面
- try {
- var height = eval(msg); //得到并设置高度
- _frame.css('height', height + 'px').css('visibility', 'visible');
- } catch(e) {
- _frame.css('height', '800px').css('visibility', 'visible');
- }
- });
- this.contentWindow.location = "about:blank";
- }).attr('src',url);
- }
修改自此处
原理:当子iframe页面onload后自身计算高度并写在window.name中,父页面修改iframe的src加载本地代理页后获取高度,然后设置高度,并修改iframe的src为原来的地址(相当的别扭!!)
而且这个方法是有缺陷的:
1, iframe会被加载2次(其中第二次是会被浏览器cache掉的)
2, 无法解决当iframe页包含分页后的高度自适应(有办法解决,但是更别扭)
昨天闲逛无意中发现完美解决方法,原文.
关键是window.top
原理不难:当跨域子页面B加载完成后,计算高度,并动态加载代理页C(和父页面A同域),同时将高度传递给C, C调用顶级页面(也就是A),回传参数.
经过简单修改,以下是demo:
页面A
- <!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>
- <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
- <title>测试</title>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
- </head>
- <body>
- <input type="button" value="B1" onclick="change(1);"/>
- <input type="button" value="B2" onclick="change(2);"/>
- <iframe id="_frame" src="#" mce_src="#" style="height:600px;" frameborder="0" marginheight="0" marginwidth="0" scrolling="no"></iframe>
- <script type="text/javascript"><!--
- function change(i) {
- $('#_frame').attr('src', 'http://mao.pconline.com.cn:8080/iframeheight/frameB'+i+'.html');
- }
- function adaptIFrameHeight(h) {
- $('#_frame').css('height', h + 'px');
- }
- // --></script>
- </body>
- </html>
子页面B1
- <!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>
- <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
- <title></title>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
- </head>
- <body>
- 1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
- <script type="text/javascript"><!--
- $(document).ready(function(){
- var agent_iframe = document.createElement("iframe");
- agent_iframe.src = "http://mao.pclady.com.cn:8080/iframeheight/frameC.html#" + $("body").attr('scrollHeight');
- document.body.appendChild(agent_iframe);
- agent_iframe.style.display = "none";
- });
- // --></script>
- </body>
- </html>
子页面B2
- <!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>
- <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
- <title></title>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
- </head>
- <body>
- 1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
- <script type="text/javascript"><!--
- $(document).ready(function(){
- var agent_iframe = document.createElement("iframe");
- agent_iframe.src = "http://mao.pclady.com.cn:8080/iframeheight/frameC.html#" + $("body").attr('scrollHeight');
- document.body.appendChild(agent_iframe);
- agent_iframe.style.display = "none";
- });
- // --></script>
- </body>
- </html>
代理页C
- <!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>
- <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
- <title></title>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
- </head>
- <body>
- <script type="text/javascript"><!--
- window.top.adaptIFrameHeight(parseInt(window.location.hash.substring(1),10));
- // --></script>
- </body>
- </html>
也就是说,应用A需要准备容器页(frameA)和代理页(frameC), 应用B需要在页面加载后计算高度, 然后动态加载应用A的代理页并传递高度参数.
(补充:其实通过现有技术通过nginx跳转可以很方便的实现应用间的同域访问)