这个可能是一个老生常谈的问题了,搜索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
本文介绍了几种iframe跨域通信的方法,包括使用document.domain、window.name、location.hash和postMessage等技术实现不同域间的通信。
5676






