为什么是三谈
为什么是三谈呢?一是因为这真的是一个被说烂的话题,二是因为太师傅在n年前就写过这篇再谈iframe自适应高度。之所以再提该问题,是因为之前项目中确实遇到了这个问题的方方面面,有必要总结一下。希望对各位有帮助,有错误请指正。
同域、子页面高度不会动态增加
这种情况最简单,直接通过脚本获取字页面实际高度,修改iframe元素高度即可。但有二点必须注意:
如果页面内有绝对定位或者没有清浮动的元素,情况有些复杂,不同浏览器处理结果不同,甚至包括Webkit内核的浏览器,具体请看这个Demo。所以你要么进行浏览器检测,要么用Math.max计算一个最大值,要么你想别的方法。
iframe所包含页面可能非常大,需要很长的加载时间,为此直接计算高度的时候,很可能页面还没下载完,高度计算就会有问题。所以最好在iframe的onload事件中计算高度。这里还要注意的是,IE下必须使用微软事件模型obj.attachEvent来绑定onload事件。而别的浏览器直接obj.onload = function(){}也可以。
(function(){
var frame = document.getElementById("frame_content_parent"),
setIframeHeight = function(){
var frameContent = frame.contentWindow.document,
frameHeight = Math.max(frameContent.body.scrollHeight,
frameContent.documentElement.scrollHeight);
frame.height = frameHeight;
};
if(frame.addEventListener){
frame.addEventListener("load",setIframeHeight,false);
}else{
frame.attachEvent("onload",setIframeHeight);
}
})();
同域、子页面高度会动态增加
原理与第一种情况一样,多一个计时器,一直检测字页面高度,当子页面高度和iframe的高度不一致时,重新设置iframe的高度。这边也可以加一个try在js出错时,加一个足够的高度。
(function(){
var _reSetIframe = function(){
var frame = document.getElementById("frame_content_parent")
try {
var frameContent = frame.contentWindow.document,
bodyHeight = Math.max(frameContent.body.scrollHeight,
frameContent.documentElement.scrollHeight);
if (bodyHeight != frame.height){
frame.height = bodyHeight;
}
}
catch(ex) {
frame.height = 1800;
}
}
if(frame.addEventListener){
frame.addEventListener("load",function(){setInterval(_reSetIframe,200);},false);
}else{
frame.attachEvent("onload",function(){setInterval(_reSetIframe,200);});
}
})();
同域、子页面高度会动态增加、脚本可能完全失效
第二个例子中,考虑到了脚本出错的情况,但是万一脚本根本不执行了呢,那iframe中的内容就会因为iframe的高度不够而显示不了。为此我们通常事先设置一个足够的高度,为了前端控制方便,我觉得写在CSS文件中比较合适,需要修改时只改CSS就行了。这里我设置了selector{ height:1800px; }。需要注意的是,写在样式表里的样式,不能直接用node.style[property]来取,对于微软模型,要用node.currentStyle[property](题外话:悲剧的IE模型不支持CSS伪类),对于W3C模型,要用window.getComputedStyle(node,null)[property]来取。我这里图方便直接用了YUI。
这里又有一个问题,设置iframe的高度大于其包含页面的高度时,各个浏览器的处理不一样。例如在Firefox下,必须计算body元素的高度,而html元素的高度等于iframe的高度,然而当恰巧这个页面又有绝对定位、未清浮动元素时,又不能通过body元素来取,显然第一种方法缺点更小一些。具体请看这个Demo。
从上面这个Demo可以看到,除IE浏览器外,别的浏览器计算出来的都是iframe的高度,即CSS里设置的#frame_content_parent{ height:1800px; }。而IE计算出来的是iframe所引用页面的实际高度。
#frame_content_parent{ height:1800px; }
(function(){
var $ = YAHOO.util.Dom,
frame = $.get("frame_content_parent");
function reSetIframe(){
var frameContent = frame.contentWindow.document,
bodyHeight = Math.max(frameContent.documentElement.scrollHeight,
frameContent.body.scrollHeight);
if (bodyHeight != $.getStyle(frame, "height")){
$.setStyle(frame, "height", bodyHeight + "px");
}
}
if(frame){
$.setStyle(frame,"height","auto");
setInterval(reSetIframe,300);
}
})();
跨域
这里提供一个Iframe代理的方法,简单地说一下原理。假设有3个页面,分别是主页面A.html,字页面B.html,代理页面C.html。其中A与B是跨域的,而A和C是同域的。它们的关系:A包含B,B包含C。很显然A和B,以及B和C,因为跨域不能相互通信,而A和C同域,可以相互通信。为此我们就想到让C页面告诉A页面,B页面到底有多少高。因为B和C也是跨域的不能相互通信,所以想在C页面中,直接window.parent.document.body.scrollHeight这样是行不通的,所以我们只能让B页面自己计算自身的高度,然后通过某种方法告诉C页面,再由C页面告诉A页面。这里的一个方法就是在B页面生成一个Iframe节点,然后设置它的src属性,在这个地址上附加一个参数,即B页面计算出来的高度,然后C页面就可以通过window.location获取这个地址栏中的地址,提取出高度值,通过window.top找到A页面,设置A页面的Iframe的高度。基本的原理就是这样,看代码吧:
DEMO
//B页面脚本
//任务:计算其实际高度,然后生成一个iframe节点,将高度作为代理页面C的地址的一部分赋值给Src属性
(function(){
var agent_iframe = document.createElement("iframe"),
b_height =
Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/"+
"agent_iframe_once.html#" + b_height;
document.body.appendChild(agent_iframe);
agent_iframe.style.display = "none";
})();
//C页面脚本
//任务:获取请求地址中的高度值,将其赋值给A页面的Iframe的高度
window.top.document.getElementById("frame_content_parent").height =
parseInt(window.location.hash.substring(1),10);
跨域、字页面高度动态变化
这里结合了第2、第4两种方法,我的想法是在B页面通过一个计时器,不停计算B页面的高度,一但变化,马上修改iframe标签的src属性,而C页面也有计时器不断监听src的变化,改变Aiframe标签的高度。需要注意的是仅仅修改src属性后面的锚点值(如“#1234”),页面并不会刷新,不会重新请求,这也是在C页面增加计时器的原因。
DEMO
//B页面脚本
(function(){
var getHeight = function(){
return Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
};
var preHeight = getHeight(),
agent_iframe;
var createIframe = function(height){
agent_iframe = document.createElement("iframe");
agent_iframe.style.height = "0";
agent_iframe.style.width = "0";
agent_iframe.style.border = "none";
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/"+
"agent_iframe.html#" + height;
document.body.appendChild(agent_iframe);
}
createIframe(preHeight);
var checkHeight = function(){
var currentHeight = getHeight();
if(currentHeight != preHeight){
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/"+
"agent_iframe.html#" + currentHeight;
preHeight = currentHeight;
}
setTimeout(checkHeight,500);
}
setTimeout(checkHeight,500);
})();
//C页面脚本
(function(){
var preHeight = parseInt(window.location.hash.substring(1),10),
ifrmae = window.top.document.getElementById("frame_content_parent");
ifrmae.height = preHeight;
setInterval(function(){
var newHeight = parseInt(window.location.hash.substring(1),10);
if (newHeight !== preHeight){
ifrmae.height = newHeight;
preHeight = newHeight;
}
},500);
})();
这里还有另一种方案,就是让iframe每一次都重新请求,这样C页面就不需要计时器了,但是如果2次计算高度重
复的话,就会导致src属性的值相同,这样浏览器就很可能不重新请求该页面了,那么C页面中的脚本也就不运行了。要修复这个问题很简单,只要在每次计算出来的src属性上增加一个随机数的参数就行了。比如http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html?temp=123123423712937#1563
//B页面关键脚本
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/"+
"agent_iframe.html?a=" + Math.random() + "#" + currentHeight;
//C页面脚本
window.top.document.getElementById("frame_content_parent").height =
parseInt(window.location.hash.substring(1),10);
相关推荐
"再谈iframe自适应高度"这个主题,关注的是如何使iframe的内容区域根据所加载页面的高度自动调整,以避免滚动条出现或者内容被截断的问题。在网页设计中,尤其是在构建响应式布局时,这是一个非常关键的优化点。 1....
然而,`<iframe>`的高度自适应问题常常困扰着开发者,尤其是当`<iframe>`内部的内容动态加载或者变化时,如何让`<iframe>`自动调整其高度以适应内容,而不会导致滚动条溢出或内容被截断,成为了一个常见需求。...
标题提到的“iframe自动适应高度(完美自适应高度嵌套代码)”提供了一个解决方案,它能够确保`iframe`在各种主流浏览器中都能正确地自适应内容高度,包括360浏览器、IE6-9、遨游、火狐以及搜狗浏览器。 在传统的`...
【标题】:“iframe自适应高度.rar”涉及到的关键知识点主要集中在如何使用JavaScript来处理网页中iframe元素的高度自适应问题。在Web开发中,iframe(Inline Frame)是一种内联框架,常用于在同一个HTML文档中嵌入...
多层嵌套iframe 自适应高度的解决方法
### iframe自适应高度(兼容多种浏览器) 在网页开发过程中,`iframe`是一种常用的元素,用于在当前页面中嵌入另一个HTML文档。然而,默认情况下,`iframe`的高度是固定的,这可能会导致内容显示不完全或者出现不必要...
这个库允许的高度与同跨域iframe来适应他们所包含的内容的宽度自动调整大小。它最常见的问题与使用iframes提供一系列的功能,其中包括: 高度和宽度大小的iframe内容大小。 作品以多个嵌套的iframe。 跨域iframe域...
#### 三、自适应高度示例 下面是一个简单的示例,演示如何通过JavaScript来动态调整`iframe`的高度: ```html <iframe name="myframe" src="myframe....
为了解决这个问题,我们需要让`iframe`能够自适应其内容的高度。本文将详细讲解如何使用JavaScript实现`iframe`自适应高度的解决方案,确保在各种主流浏览器中都能正常工作。 首先,理解`iframe`的基本结构和属性是...
iFrame 自适应高度(兼容所有主浏览器) iFrame 自适应高度是前端开发中常见的问题,很多开发者在搜索引擎中搜索相关解决方案,但大多数文章只能解决静态高度的问题,而忽视了 JS 操作 DOM 之后的动态同步问题。...
总之,“jquery对iframe自适应高度插件”是解决`iframe`高度自适应问题的一个强大工具,它的易用性和效率使得它成为开发者处理`iframe`高度问题的首选方案。通过合理利用这个插件,可以避免手动计算和调整`iframe`...
### iframe自适应高度实现方法详解 在网页设计与开发中,`iframe`(Inline Frame)是一种常用的HTML元素,用于在当前文档中嵌入另一个HTML文档。然而,在实际应用过程中,经常会遇到`iframe`内容高度固定导致页面...
iFrame自适应高度兼容各主流浏览器 iFrame自适应高度是指在网页中嵌入iFrame时,使其高度能够自动适应其内容的高度,从而避免了出现滚动条的问题。下面是实现iFrame自适应高度的方法和相关知识点。 知识点1:...
`iframe`的自适应高度是一项关键技术,它确保了嵌入的内容能够完全显示,避免滚动条的出现,从而提供更好的用户体验。 `iframe`的基本语法如下: ```html <iframe src=...
因为有一个项目要用到iframe自适应高度,网上搜索了以下结果无数,不过看来看去都是那几个,而且基本都测试了一遍,所说的兼容根本不是那么回事,要不IE不正常,要不其他浏览器显示不正常,最后无奈,综合网上的方法...
在探讨“基于jQuery的兼容各种浏览器的iframe自适应高度的脚本”这一主题时,我们首先需要理解几个关键概念:iframe、自适应高度以及jQuery。 ### 1. iframe概述 iframe,即Inline Frame,是HTML中一个用于在当前...
##### 方法三:动态调整多个`iframe`的高度 如果页面中有多个`iframe`需要自适应高度,可以通过遍历`iframe`数组,逐一应用高度调整逻辑。 ```javascript var iframeids = ['myframe1', 'myframe2']; function ...
总的来说,实现`iframe`自适应高度的方法主要有JavaScript动态计算、jQuery操作和跨域通信三种。根据实际项目需求和兼容性考虑,可以选择合适的方法。在实际应用中,还需要注意浏览器的兼容性和安全问题,确保解决...
跨域问题是指当iframe加载的页面与主页面不在同一个域时,出于安全考虑,浏览器会限制JavaScript对iframe内容的访问,这会使得自适应高度变得更加复杂。 总的来说,虽然iframe在使用上存在一定的限制和挑战,但通过...
### iframe自适应高度(DOM动态操作) #### 概述 在网页开发中,`iframe`是一种常用的技术,用于在一个HTML页面中嵌入另一个HTML页面。然而,在实际应用中经常会遇到一个问题:即`iframe`的高度与内嵌页面的实际...