原创、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调用地址域名跟父页面域名不一样。

1.JPG

2.JPG

然后用上了action动作分类方便其他接口扩展。

jquery.ba-resize.min.zip