背景说明:我开发了一个页面框架,里面通过Iframe嵌入第三方应用。但第三方应用有多个,页面高度不一样,而且在使用过程中还会动态变化。我外面Iframe的高度就要跟随里面的应用来变化。

 这样就要求第三方应用页面高度变化时要控制外围Iframe的高度跟随变化,但直接的js控制是行不通的,因为第三方应用和我的框架在不同域,浏览器因为安全原因会禁止应用通过js控制外面框架的DOM对象。同理,外围框架也不能控制Iframe内应用的DOM对象。

 要实现真正的跨域调用,必须通过一个代理页面来实现。原理如下:

存在3个页面,http://frame.com/frame.html:我的框架页面

             http://app.com/app.html:第三方应用的页面

             http://frame.com/agent.html:代理页面

注意,框架页面和代理页面必须是同一个域的,这样才能通过代理页面控制框架而绕过安全限制。

 这样我们就可以在app.html中获取页面的高度,然后通过 agent.html#hash的机制把高度传递给agent.html页面,最后在agent.html页面中获取高度然后调整frame.html中Iframe的高度。这就有个前提,要求你可以修改app.html,或者可以要求app.html做些修改。为了方便第三方修改,我在一个agent.js中实现了这些修改,第三方应用只要引用这个js就可以了。

agent.js代码如下:

function sethash(){

        var oldHash=0;

        var urlC = "http://frame.com/agent.html";

        var iframe=document.createElement('iframe');

        iframe.id="iframeC"

        iframe.name="iframeC";

        iframe.width=0;

        iframe.height=0;

        iframe.style.display="none";

        document.body.appendChild(iframe);

        //document.body.innerHTML+='<iframe id="iframeC" name="iframeC" src="" width="0" height="0" style="display:none;" ></iframe>';

 

        setInterval(function(){

                var bHeight = document.body.scrollHeight;

                var dHeight = document.documentElement.scrollHeight;

                var oHeight = document.body.offsetHeight;

                var hashH =Math.min(oHeight,Math.min(bHeight,dHeight));

 

                if(oldHash!=hashH){

 

                        document.getElementById("iframeC").src=urlC+"?"+Math.random()+"#"+hashH;

                }

                oldHash=hashH;

        },200);

 

}

if(window.addEventListener){

        window.addEventListener("load",sethash,false);

}else{

        window.attachEvent("onload",sethash);

}

agent.html代码如下:

<!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><title>frame agent</title></head>

 

<body>

 

<script type="text/javascript">

function  pseth() {

        var iObj = parent.parent.document.getElementById('frame_cont');

        iObjH = window.location.hash;

        //iObjH = parent.parent.frames["frame_cont"].frames["iframeC"].location.hash; 

        iObj.style.height = iObjH.split("#")[1]+"px";

}

pseth();

 

</script>

 

</body>

</html>

这里有几个需要注意的地方

1、agent.js中创建隐藏的iframe要使用DOM函数操作,不能用innerhtml,在IE等浏览器上用innerhtml会导致一些绑定的js事件失效。

2、在设置定时器重新调用agent.html时需要带随机数参数,不然有些浏览器由于缓存会不调用。

3、在app.html中调用agent.js,

<script type="text/javascript" src="http://frame.com/setHash.js"></script>