原创、JS实现iframe高度自适应(含跨域)解决方案
在用iframe做页面调用的时候,如果子页面高度是固定的那么可以直接在父页面个iframe写一个固定的高度,但是如果子页面高度可能发生变化,比如子页面调用的信息高度不一致或者客户行为导致高度发生变化,那么就必须要重新调整iframe的高度。
本文通过两种方式实现iframe高度自适应,包括父页面子页面域名不一样即跨域的情况,
实现步骤:
1、iframe高度变化,由子页面获取新高度;
2、通过标准的window.parent直接更改iframe的高度;
3、如果2不成功,或者跨域了,则通过h5特性进行“父子页面“通信实现高度调整。
子页面源码:
<script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="jquery.ba-resize.min.js"></script> <script type="text/javascript"> var height0 = 0; $(function(){ //可视区域高度,iframe设置的初始高度 height0 = document.documentElement.clientHeight; $("#add").click(function(){ $('body').append("<p>这是一行文字,用来撑大body</p>"); }); $("#remove").click(function(){ $('p:last').remove(); }); $('body').resize(function() { var height = $("body").outerHeight(true); if(height < height0){ //新高度小于iframe设置的初始高度 return; } try{ window.parent.document.getElementById("iframe").style.height = height+"px"; //window.parent.frames[0].style.height = height+"px"; }catch(e){ var json = JSON.stringify({"action":"iframeresize","height":height}); window.parent.postMessage(json,"*"); } }); }); //子页面接收消息 window.addEventListener('message',function(e){ if(e.source != window.parent){ return; } try{ var data = $.parseJSON(e.data); }catch(err){ console.log('消息格式错误'); return; } if(typeof data.action == 'undefined'){ console.log('消息类型错误'); return; } if(data.action == 'iframeresizeresult'){ console.log("消息来自父页面:"+data.message); } }); </script> <body> 子页面<br/> <input type="button" id="add" value='增加一行'> <input type="button" id="remove" value='删除一行'> </body>
此处调用了一个jq的resize插件(文章尾部有下载链接),用于捕捉页面尺寸改变事件。这里做了一个限制,即子页面高度小于iframe设置的初始高度时不更改iframe高度。
父页面实现:
<script type="text/javascript" src="jquery.min.js"></script> <style type="text/css"> iframe{ border:1px solid #cccccc; transition: all ease .2s; -moz-transition: all ease .2s; -webkit-transition: all ease .2s;} </style> <body> <p>父页面</p> <iframe id="iframe" style="width:600px;height:100px;" scrolling="no" src="http://www.facai.com:111/iframeresize/2.html"></iframe> <script type="text/javascript"> window.addEventListener('message', function (e) { if(e.source != window.frames[0]){ console.log('非子窗体发送'); return; }; try{ var data = $.parseJSON(e.data); }catch(err){ console.log('消息格式错误'); return; } if(typeof data.action == 'undefined'){ console.log('消息类型错误'); return; } if(data.action == 'iframeresize'){ console.log('新高度:'+data.height); $("#iframe").css('height',data.height+'px'); var msg = JSON.stringify({'action':'iframeresizeresult','message':'iframe高度设置成功'}); window.frames[0].postMessage(msg,'*'); } }) </script> </body>
此处用了跨域的环境即iframe调用地址域名跟父页面域名不一样。
然后用上了action动作分类方便其他接口扩展。