您的位置:首页 > 其它

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

2014-05-20 14:01 197 查看
项目中需要使用iframe嵌套另外一个项目的子页面,但是要求不能有滚动条,也就是说iframe的高度得根据嵌套页面的高度自适应

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

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

代码片段:

[javascript] view
plaincopy

//这个方法解决不了子页面内链无法自适应高度的问题

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

[xhtml] view
plaincopy

<!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

[xhtml] view
plaincopy

<!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

[xhtml] view
plaincopy

<!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

[xhtml] view
plaincopy

<!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跳转可以很方便的实现应用间的同域访问)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: