这个可能是一个老生常谈的问题了,搜索google和百度应该也是文章大把大把的;处理方式也大同小异,今天又有哥们问这个问题,所以还是将自己的处理方式写出来。
最早遇到这个问题是07年在Yahoo的时候,当时SNS盛行,Yahoo也决定做SNS,其中就有应用是iframe模式的,但是iframe的页面在对方服务器上,使用的也是别人的域名,Yahoo也不可能给对方提供二级或三级域名;那就遇到一个问题,怎样去调整iframe的高度,让他做到自适应;大家都知道JS为了安全,是不能跨域执行的,所以只能通过其他方式实现;感谢克军同学当时给的建议。
下面具体说说怎么实现吧。
首先因为iframe是跨域的,所以不能直接用JS来控制,只能通过一个中间键,我们这里选择在iframe的页面(页面B)中再iframe一个父页面(页面A)同域的页面(页面C);这样页面C就能和页面A进行无障碍的通讯了;因为页面B iframe 页面C,所以页面B可以改写页面C的href值;到这里大家应该看明白啥意思了,来张图说明下:
A页面中的内容
A页面主要就是接收C页面传过来的内容并且去完成相应的操作。可能有人会说直接C页面来操作不就可以了?但是那样处理不太好,因为可能A页面中还有很多其他的公共方法,比如美化过的Alert等,所以如果能做一个公共的方法来接收C页面传过来的值会更加方便之后的框架调整,而且也不建议总是去修改页面C。
<iframe id="ifr" src="iframe_b.html" height="200" width="400"></iframe> <script type="text/javascript"> var ifr_el = document.getElementById("ifr"); function getIfrData(data){ ifr_el.style.height = data+"px"; } </script>
B页面中的内容
B页面的主要内容当然是怎么把值传递给C页面,前面说了是将值传递到C页面的href中,所以只要修改iframe的src就可以,因为不用刷新C页面,所以可以用过hash的方式传递给C页面
<div id="box"> <button id="btn_auto" type="button">Height Auto: off</button> <button id="btn_plus10" type="button">Height +10px</button> <button id="btn_minus10" type="button">Height -10px</button> </div> <iframe id="ifr" src="iframe_c.html" width="0" height="0"></iframe> <script type="text/javascript"> var box_el = document.getElementById("box"), btn_auto_el = document.getElementById("btn_auto"), btn_plus10_el = document.getElementById("btn_plus10"), btn_minus10_el = document.getElementById("btn_minus10"), ifr_el = document.getElementById("ifr"); var isAuto = false, oldHeight = 0, ifrSrc = ifr_el.src.split("#")[0]; btn_auto_el.onclick = function(){ if(!isAuto){ isAuto = true; btn_auto_el.innerHTML = "Height Auto: on"; }else{ isAuto = false; btn_auto_el.innerHTML = "Height Auto: off"; } } btn_plus10_el.onclick = function(){ var height = box_el.offsetHeight; box_el.style.height = (10+height)+"px"; } btn_minus10_el.onclick = function(){ var height = box_el.offsetHeight; box_el.style.height = (height-10)+"px"; } setInterval(function(){ if(isAuto){ var height = document.body.scrollHeight; height += 20; if(oldHeight != height){ oldHeight = height; ifr_el.src = ifrSrc+"#"+oldHeight; } } }, 200); </script>
C页面中的内容
C页面的唯一功能就是接收B页面通过href传进来的值并且传递给A页面,可到B页面传来的值可以通过一个定时器不停去查看location.href是否被改变,但是这样感觉效率很低,还有个方式就是在新的浏览器中通过onhashchange事件(IE8+,Chrome5.0+,Firefox3.6+,Safari5.0+,Opera10.6+)来监听href的改变。
<script type="text/javascript"> var oldHeight = 0; setInterval(function(){ var height = location.href.split("#")[1]; if(height && oldHeight != height){ oldHeight = height; if(window.parent.parent.getIfrData){ window.parent.parent.getIfrData(oldHeight); } } }, 200); </script>
高度应用只是iframe跨域传值中最简单也是最常见应用,其实能扩展出很多其他的需求,之前在Yahoo的项目中就将iframe中的弹出框操作也传递到了外面,以保证样式的统一和页面的全遮盖。
最后举个“栗子”,演示请看http://www.honglei.net/demo/iframe_a.html