iframe 跨域自适应高度的解决方案

来源:互联网 发布:emlog博客源码下载 编辑:程序博客网 时间:2024/05/22 06:11

项目中需要使用iframe嵌套另外一个项目的子页面,但是要求不能有滚动条,也就是说iframe的高度得根据嵌套页面的高度自适应

 

由于跨域,所以父子页面显然是不能通信的

 

第一个想到的是最近才接触到的window.name方式

 

代码片段:

 

[javascript] view plaincopy
  1. //这个方法解决不了子页面内链无法自适应高度的问题  
  2. function autoHeightIFrameNavigate(iframeId,url) {  
  3.     var _frame = $('#' + iframeId);  
  4.     _frame.css('visibility''hidden');  
  5.     _frame.one('load'function(){  
  6.         $(this).one('load',function () {  
  7.             var msg = this.contentWindow.name;            //得到值 这个值就是高度了  
  8.             this.contentWindow.location = url;            //再次导向目标页面  
  9.             try {  
  10.                 var height = eval(msg);                    //得到并设置高度  
  11.                 _frame.css('height', height + 'px').css('visibility''visible');  
  12.             } catch(e) {  
  13.                 _frame.css('height''800px').css('visibility''visible');  
  14.             }  
  15.         });  
  16.         this.contentWindow.location = "about:blank";  
  17.     }).attr('src',url);  
  18. }  
  

 

修改自此处

 

原理:当子iframe页面onload后自身计算高度并写在window.name中,父页面修改iframe的src加载本地代理页后获取高度,然后设置高度,并修改iframe的src为原来的地址(相当的别扭!!)

 

而且这个方法是有缺陷的:

  1, iframe会被加载2次(其中第二次是会被浏览器cache掉的)

  2, 无法解决当iframe页包含分页后的高度自适应(有办法解决,但是更别扭)

 


 

昨天闲逛无意中发现完美解决方法,原文.

 

关键是window.top

 

原理不难:当跨域子页面B加载完成后,计算高度,并动态加载代理页C(和父页面A同域),同时将高度传递给C, C调用顶级页面(也就是A),回传参数.

 

经过简单修改,以下是demo:

 

页面A

[xhtml] view plaincopy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=gbk" />  
  5. <title>测试</title>  
  6. <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>  
  7. </head>  
  8. <body>  
  9.   <input type="button" value="B1" onclick="change(1);"/>  
  10.   <input type="button" value="B2" onclick="change(2);"/>  
  11.   <iframe id="_frame" src="#" mce_src="#" style="height:600px;" frameborder="0" marginheight="0" marginwidth="0" scrolling="no"></iframe>  
  12.   <script type="text/javascript"><!--  
  13.     function change(i) {  
  14.       $('#_frame').attr('src', 'http://mao.pconline.com.cn:8080/iframeheight/frameB'+i+'.html');  
  15.     }  
  16.     function adaptIFrameHeight(h) {  
  17.       $('#_frame').css('height', h + 'px');  
  18.     }  
  19.     
  20. // --></script>  
  21. </body>  
  22. </html>  

 

子页面B1

 

[xhtml] view plaincopy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=gbk" />  
  5. <title></title>  
  6. <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>  
  7. </head>  
  8. <body>  
  9. 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/>  
  10.   <script type="text/javascript"><!--  
  11.     $(document).ready(function(){  
  12.       var agent_iframe = document.createElement("iframe");  
  13.       agent_iframe.src = "http://mao.pclady.com.cn:8080/iframeheight/frameC.html#" + $("body").attr('scrollHeight');  
  14.       document.body.appendChild(agent_iframe);  
  15.       agent_iframe.style.display = "none";  
  16.     });  
  17.     
  18. // --></script>  
  19. </body>  
  20. </html>  
 

 

子页面B2

[xhtml] view plaincopy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=gbk" />  
  5. <title></title>  
  6. <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>  
  7. </head>  
  8. <body>  
  9. 1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>  
  10.   <script type="text/javascript"><!--  
  11.     $(document).ready(function(){  
  12.       var agent_iframe = document.createElement("iframe");  
  13.       agent_iframe.src = "http://mao.pclady.com.cn:8080/iframeheight/frameC.html#" + $("body").attr('scrollHeight');  
  14.       document.body.appendChild(agent_iframe);  
  15.       agent_iframe.style.display = "none";  
  16.     });  
  17.     
  18. // --></script>  
  19. </body>  
  20. </html>  
 

 

代理页C

[xhtml] view plaincopy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=gbk" />  
  5. <title></title>  
  6. <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>  
  7. </head>  
  8. <body>  
  9.   <script type="text/javascript"><!--  
  10.     window.top.adaptIFrameHeight(parseInt(window.location.hash.substring(1),10));  
  11.     
  12. // --></script>  
  13. </body>  
  14. </html>  
  

 

也就是说,应用A需要准备容器页(frameA)和代理页(frameC), 应用B需要在页面加载后计算高度, 然后动态加载应用A的代理页并传递高度参数.

 

(补充:其实通过现有技术通过nginx跳转可以很方便的实现应用间的同域访问)

0 0
原创粉丝点击