序言
在网站开发过程中,iframe不怎么被推荐使用,有点类似Table的命运,但我个人认为有些地方使用iframe还是挺方便的,比如局部刷新和灵活控制响应结果的显示位置(我不喜欢整页整页地刷新)。也许存在其他的东西能够完美地替代iframe的这些功能,我也很乐意了解,可根据目前浅薄的见识,还不知道哪个可以(T_T),所以先把iframe搞清楚吧~
正文
使用iframe的时候,iframe高度能适应其嵌入的页面长度是非常必要的,因为很多时候被潜入的结果页面是动态生成的,预先根本不知道它会有多长,且被嵌入的页面内部可能另外又有一个iframe。本文先考虑单层iframe的情况,再解决多层嵌套iframe的高度更新问题。
一 单层iframe高度自适应
如果只涉及一层iframe,则可以在主页面的body标签的onLoad事件中添加一个调整iframe高度的js函数,使得页面加载完成时(此时嵌入页面也加载完成了)刷新iframe的高度为被嵌入页面内容的高度,也可以在iframe的onLoad事件中添加调整高度的函数。例如这个函数为setIfrmHeight(iframeID),其内容如下,
function setIfrmHeight(id)
{ /*实现iframe自适应内容高度,适用于ie和ff*/
var iframe = window.document.getElementById(id);
if (document.getElementById)
//如果document对象存在getElementById方法,几乎所有的浏览器都支持
{
if (iframe && !window.opera) //如果浏览器不是opera
{
if (iframe.contentDocument && frame.contentDocument.body.offsetHeight)
iframe.height = iframe.contentDocument.body.offsetHeight;
else if (iframe.Document && iframe.Document.body.scrollHeight)
iframe.height = iframe.Document.body.scrollHeight;
}
}
}
假设index.jsp中有一个iframe,其id为'FloatWd',上述的高度设置函数在文件chloe.js中,则只需要index.jsp的头部添上<SCRIPT type=text/javascript src="chloe.js"></SCRIPT>以引入js函数,接着在<body>中或者<iframe>中加上一句onLoad="SetIfrmHeight('FloatWd');"即可。之后无论index.jsp的iframe中载入哪个页面,iframe的高度都会自动适应其内容的高度,实现index框架与嵌入页面的无缝连接。在<body>中加入和在<iframe>中加入的区别是 :<body>中的onLoad事件只有在页面载入完毕时才触发 ,之后动态更改其中iframe的内容则不会触发; 而<iframe>中的onLoad事件在每次更改此iframe的src后都会触发, 即重新载入子页面后触发。所以如果页面载入完毕后,如果可能动态改变iframe的内容,希望改变时iframe高度也能够自适应,则需要在<iframe>的onLoad事件中添加高度调整函数。
二 多层iframe高度自适应
对于嵌套多层iframe的情况,采用前面的方法就不行了。假设index.jsp中通过iframe 'FloadWd'嵌入了页面main.jsp,而main.jsp中又有一个iframe 'SubFloadWd',嵌入了页面subpage.jsp,且main.jsp中会独立地更改SubFloadWd中的页面,此时就不能简单采用父页面调用高度调整函数的方法了,要逆向地在最底层的页面中调用函数调整父页面和父父页面中的iframe高度,因为main.jsp更新其iframe中的内容时,父页面index.jsp并没有触发载入事件,从而不会调用函数调整'FloadWd'的高度。
此时需要有两个调整父页面iframe和父父页面iframe高度的函数,供subpage.jsp以及其他子页面在onLoad事件中调用,这两个函数跟前面的基本类似,只是获取的id是父页面中的内容。
function SetParentIfrmHeight(id)
{
var pIframe = window.parent.document.getElementById(id);
if (document.getElementById)
{
if (pIframe && !window.opera)
{
if(pIframe.contentDocument && pIframe.contentDocument.body.offsetHeight)
pIframe.height = pIframe.contentDocument.body.offsetHeight;
else if(pIframe.Document && pIframe.Document.body.scrollHeight)
pIframe.height = pIframe.Document.body.scrollHeight;
}
}
}
function SetPParentIframeHeight(id)
{
var ppIframe = window.parent.parent.document.getElementById(id);
if (document.getElementById)
{
if (ppIframe && !window.opera)
{
if(ppIframe.contentDocument && ppIframe.contentDocument.body.offsetHeight)
ppIframe.height = ppIframe.contentDocument.body.offsetHeight;
else if(ppIframe.Document && ppIframe.Document.body.scrollHeight)
ppIframe.height = ppIframe.Document.body.scrollHeight;
}
}
}
之后在subpage.jsp中的<body>中加上onLoad="SetParentIfrmHeight('subFloatWd');SetPParentIframeHeight('FloatWd');"即可,当然引用包含上面两个函数js文件是必须的。
对于三层、四层等多层嵌套,类似的添加调整上级页面中iframe的高度的函数,如果有三层iframe,则要有三种高度调整函数,四层则有四种高度调整函数,各个函数除了第一行提取iframe对象不同外,其他部分基本相同。
总结
其实对于单层的iframe的情况,逆向调整父页面中iframe的高度也是可行的,其思路也比较合理:当页面载入完成后调整包含自己的iframe的高度。当只有一个父页面,有很多个子页面时,逆向方法需要每个子页面都在onLoad事件中添加调整函数,比较繁琐,而正向调整本方法只用在一个父页面中添加一次调整函数就可以了。对于多层iframe的情况,正向处理只有在主页面载入时起作用,不能在主页面载入后继续灵活及时地调整iframe高度。根据应用的实际需要,可以采用不同的思路。
篇外
这里补充一下使用iframe的其他方面:
(1) 让form提交后的结果页面显示在本页面的iframe区域内
<form id="formID" name="formName" action="result.jsp" method="post" target="targetIframeName">
(2) 隐藏iframe
<iframe name="hiddenFrame" id="hiddenFrame" width="0" height="0" frameborder="0" style="display:none"></iframe>
可以在Servlet处理完毕后给出js提示信息,此提示信息的目标通过(1)设置为当前页面的隐藏iframe中,这样既能自然得看到提示,也可以防止页面跳转。