- 浏览: 196972 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
guji528:
使用Python通过正则表达式替换很方便:
sprin ...
Python正则表达式指南 -
guji528:
很实用,先keep再看
Python正则表达式指南 -
yushine:
1,2,3,5 已经做了剩下的本来也正准备做。
2012, 每一个软件工程师必须做的11件事 -
mynetstudy:
用导出不就可以了吗
递归删除SVN工作目录下的.svn目录
为什么是三谈
为什么是三谈呢?一是因为这真的是一个被说烂的话题,二是因为太师傅在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);
发表评论
-
Highchart Vs Flot.js – Comparing JavaScript Graphing Engines
2012-09-06 02:18 1715In previous projects at MailCha ... -
JavaScript世界的一等公民 - 函数
2012-08-15 13:54 789简介 在很多传统语言( ... -
jQuery:click() bind() live() delegate()区别
2012-08-03 10:30 1040click(),bind(),live()执行事件方法区别: ... -
5大富文本编辑器比较
2011-12-08 11:21 2493说到富文本编辑器,不由我不想到 office word. ... -
js中date对象扩展的相关函数
2011-10-14 15:03 1656该文章收集了对js中date对象扩展的相关函数,包括:把字符串 ... -
领悟 JavaScript 中的面向对象
2011-09-29 15:57 368领悟 JavaScript 中的面向 ... -
使用面向对象的技术创建高级 Web 应用程序
2011-09-29 15:56 791使用面向对象的技术创建高级 Web 应用程序 Ray Dja ... -
Firebug控制台详解
2011-08-11 15:24 741作者: 阮一峰 日期: 2011年3月26日 ... -
Backbone JS框架指南
2011-05-27 22:49 2866Posted Mar.13, 2011 unde ... -
10个最佳jQuery Lightbox效果插件收集
2011-04-10 01:25 1200原文:10个最佳jQuery Lightbox效果插件收 ... -
JS获取当前页面的URL信息
2011-02-23 10:14 1574js和php一样,都有获取url的函数,一直没有用过,今天需 ... -
输入法下keyup失效的解决方案
2011-01-17 10:02 2911【转】http://realazy.org/blog/2007 ... -
radio disapled readonly 失效传值问题
2011-01-10 16:44 2092关键字: radi ... -
JOHN RESIG的膜拜帖
2010-10-12 15:56 1198JOHN RESIG, jquery的创造者, 被认为是js世 ...
相关推荐
js控制 Iframe 框架自适应被嵌入页面高度
这个库允许的高度与同跨域iframe来适应他们所包含的内容的宽度自动调整大小。它最常见的问题与使用iframes提供一系列的功能,其中包括: 高度和宽度大小的iframe内容大小。 作品以多个嵌套的iframe。 跨域iframe域...
JAVASCRIPT让IFRAME框架的高度自适应
主要介绍了js实现iframe自动自适应高度的方法,涉及javascript操作iframe框架的技巧,非常具有实用价值,需要的朋友可以参考下
Iframe框架高度自适应的实现.doc
网站实现了网页的布局,左边固定,点击左边的链接,在右边显示相应信息,iframe自适应高度,用js更改链接样式。网站是本人在练习的时候弄的,页面简单,功能实现了。看了就明白了。 vs2005的
iframe自适应高度(兼容目前所有主浏览器)
NULL 博文链接:https://z-one.iteye.com/blog/1725511
iframe使用 自适应高度 封装js
本文实例讲述了JS实现iframe自适应高度的方法。分享给大家供大家参考,具体如下: <iframe id="mainFrame" name="mainFrame" src="/zwgk/hsearchview" width="740" frameborder="0" scrolling="no" scrolling=...
关于IFRAME 自适应高度的研究——之前自己也碰到过这个问题,为了得到答案去网上搜索,发现有不少人也遇到了这样的问题,现在就把解决方法共享一下。 重要提示:src=中你必须填写的网页地址,一定要和本页面在同一...
main.htm: <... <head> <... charset=gb2312′ /> <... <...iframe自适应加载的页面高度</title> </head> <body> <div><iframe src=”child.htm”></i
就是绑定事件必须在iframe加载完毕之前绑定,否则不会执行。 以下是jQuery,load事件的概述 在每一个匹配元素的load事件中绑定一个处理函数。 如果绑定给window对象,则会在所有内容加载后触发,包括窗口,框架,对象...
iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。 HTML 与 XHTML 之间的差异 在 HTML 4.1 Strict DTD 和 XHTML 1.0 Strict DTD 中,不支持 iframe 元素。 提示和注释: 提示:您可以把需要的文本...
25、可以自适应iframe内容的大小(不跨域的前提下) 26、对超过预设面积大小的对话框拖动自动采用替身的方式,以求拖动更流畅 27、新增加一个'data'的接口,它保存了你对话框每次创建的消息对象 (操作iframe消息...
-修正Form不能自适应浏览器大小的改变(feedback:kaywood)(WorkItem#6309)。 -增加重载方法Alert.Show(message, title, icon)(feedback:TheBox)(WorkItem#6353)。 -为容器控件(比如Panel,Region,Tab等)增加AJAX...
-修正Form不能自适应浏览器大小的改变(feedback:kaywood)(WorkItem#6309)。 -增加重载方法Alert.Show(message, title, icon)(feedback:TheBox)(WorkItem#6353)。 -为容器控件(比如Panel,Region,Tab等)增加AJAX...
5.6 动态添加iframe框架 5.7 用层实现长文章分页 5.8 iframe自适应高度 5.9 类似MSN的消息提示 5.10 只打印iframe的内容 第6章 下拉列表特效 6.1 下拉框实现多选 6.2 实现两个select的同步 6.3 被选中的列表项下次不...
5.6 动态添加iframe框架 5.7 用层实现长文章分页 5.8 iframe自适应高度 5.9 类似MSN的消息提示 5.10 只打印iframe的内容 第6章 下拉列表特效 6.1 下拉框实现多选 6.2 实现两个select的同步 6.3 被选中的列表项下次不...
1.15 实现iframe高度自适应 1.16 实现左右div自适应相同高度 1.17 获取鼠标在屏幕中的坐标 1.18 获取鼠标在窗口客户区中的坐标 1.19 获取鼠标在窗口页面中的坐标 1.20 设置Flash对象的WMode窗口模式 1.21 实现类...