• [置顶] iframe使用总结(实战)


    说在前面的话,iframe是可以做很多事情的。
    例如:
    a>通过iframe实现跨域;
    b>使用iframe解决IE6下select遮挡不住的问题
    c>通过iframe解决Ajax的前进后退问题
    d>通过iframe实现异步上传。(Easyui中form组件就是用的iframe,实现表单提交时,可以提交上传域)
    下面就一些问题一一论述。

    1、iframe基本知识:

    iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。
    在 HTML 4.1 Strict DTD 和 XHTML 1.0 Strict DTD 中,不支持 iframe 元素。
    提示:您可以把需要的文本放置在 <iframe> 和 </iframe> 之间,这样就可以应对无法理解 iframe 的浏览器。
    <iframe width=420 height=330 frameborder=0 scrolling=auto src="URL"></iframe>

    可选属性:

    标准属性:

    2、操作iframe:

       注:测试环境IE:8.0,FF:23.0.1
       a>隐藏iframe表框
    		i>标签中设置:frameborder="0",<iframe frameborder="0" width="400" height="400" src="http://blog.csdn.net/cuew1987" scrolling="no"></iframe>
    		ii>DOM操作:
    			<body>
    			<iframe frameborder="1" width="400" height="400" src="http://blog.csdn.net/cuew1987" scrolling="no" id="myiframe"></iframe>
    			<script>
    			var myiframe = document.getElementById("myiframe");
    			myiframe.style.border="none";//FF下有效,IE下无效 
    			myiframe.setAttribute("frameborder",0);//FF下有效,IE下无效 
    			myiframe.frameBorder = 0;//FF下有效,IE下无效 
    			</script>
    			</body>
       b>动态创建iframe
       <script>
    		var newFrame = document.createElement("iframe");
    		newFrame.src ="http://blog.csdn.net/cuew1987";
    		newFrame.frameBorder = 0;//FF、IE隐藏边框有效
    		newFrame.width = "400px";
    		newFrame.height = "400px";
    		newFrame.scrolling = "no";
    		document.body.appendChild(newFrame);
       </script>
       c>获取iframe
    		i>var obj = document.getElementById("iframeID");
    		  获取iframe对象,可直接操作iframe标签属性,如只想改变iframe的 src 或者 border ,scrolling 等attributes
    		ii>var dom = frames["iframeName"];
    		   获取iframe的DOM对象,此对象可用来操作对象,比如想操作iframe页面中的元素。
        d>获取iframe中的window对象
    		function getIframeWindow(obj) {
    			//IE || w3c
    			return obj.contentWindow || obj.contentDocument.parentWindow;
    			//parentWindow 是 parent window object
    		}
    		document.getElementById取到的iframe是不能直接操作里面的document的,只能这样取:
    		IE:frames[id].document或obj.contentWindow.document;
    		FF:dom.contentDocument或obj.contentDocument;不绑定任何事件.
    	e>获取iframe页面高度
    		function getIframeHeight(obj){
    			var idoc = getIframeWindow(obj).document; 
    			if(idoc.body){
    				return Math.max(idoc.body.scrollHeight,idoc.body.offsetHeight);   
    			}else if(idoc.documentElement){
    				return Math.max(idoc.documentElement.scrollHeight,idoc.documentElement.offsetHeight);   
    			}
    		}
    	f>父子页面互访
    		i>子访问父:
    			parent.html:
    			<body>
    				<div>等到的信息:<div id="msg"></div></div>
    				<iframe frameborder="1" width="400" height="400" src="son.html" scrolling="no" id="myiframe"></iframe>
    			</body>
    			son.html:
    			<body>
    			<input type="button" onClick="setMsg()" value="setMsg">
    			<script>
    			function setMsg(){
    				var msg = window.parent.document.getElementById("msg");
    				msg.innerHTML= "Hello world!!";
    			}
    			</script>
    			</body>
    		ii>父访问子:
    			parent.html:
    			<body>
    			<div>等到的信息:<div id="setMsg"></div></div>
    			<input type="button" value="setMsg" onClick="setMsg()"><br>
    			<iframe frameborder="1" width="400" height="400" src="son.html" scrolling="no" id="myiframe"></iframe>
    			<script type="text/javascript">
    			function setMsg(){
    				var obj = document.getElementById("myiframe");
    				var msg = getIframeWindow(obj).document.getElementById("msg");
    				document.getElementById("setMsg").innerHTML = msg.innerHTML;
    			}
    			</script>
    			</body>
    			son.html:
    			<body>
    			<div id="msg">Hello world!!!</div>
    			</body>


    3.iframe高度自适应和跨域:

    实际使用iframe中,会遇到iframe高度的问题,由于被嵌套的页面长度不固定而显示出来的滚动条,不仅影响美观,还会对用户操作带来不便
    	a>同域下的高度自适应
    	parent.html:
    	<body>
    	<iframe width="400" id="myiframe" onload="setHeight()" height="1" frameborder="0" src="son.html"></iframe>
    	<script type="text/javascript">  
    	function getIframeWindow(obj) {
    		return obj.contentWindow || obj.contentDocument.parentWindow;
    	}
    	function getIframeHeight(obj){
    		var idoc = getIframeWindow(obj).document; 
    		if(idoc.body){
    			return Math.max(idoc.body.scrollHeight,idoc.body.offsetHeight);   
    		}else if(idoc.documentElement){
    			return Math.max(idoc.documentElement.scrollHeight,idoc.documentElement.offsetHeight);   
    		}
    	}
    	function setHeight(){   
    		var myiframe = document.getElementById("myiframe");
    		myiframe.height = getIframeHeight(myiframe);
    	} 
    	</script> 
    	</body>
    	另:document.documentElement与document.body相关说明(W3C DOM2.0规范)
    	document.doucmentElement:
    		documentElement of type Element, readonly,This is a convenience attribute that allows direct access to the 
    		child node that is the root element of the document. For HTML documents, this is the element with the tagName "HTML".
    	document.body:
    		document.body is the element that contains the content for the document. In documents with <body> contents, returns the <body> element, 
    		and in frameset documents, this returns the outermost <frameset> element.
    		Though body is settable, setting a new body on a document will effectively remove all the current children of the existing <body> element.
    	IE在怪异模型(Quicks Mode)下document.documentElement无法正确取到clietHeight scrollHeight等值,比如clientHeight=0。
    	获取scrollTop:
    	var sTop=Math.max(
    		(document.body?document.body.scrollTop:0),
    		(document.documentElement?document.documentElement.scrollTop:0),
    		(window.pageYOffset?window.pageYOffset:0)
    	);    
    
    	b>跨域下高度自适应
    	页面:
    	index.html:(http://www.csdn.net)
    	<iframe width="400" id="myiframe" onload="setHeight()" height="1" frameborder="0" src="son.html"></iframe>
    	son.html:
    	<body >
    	<iframe id="agentIframe" style="position:absolute; top:-10000;left:-1000;" height="10" width="100%"></iframe>
    	</body>
    	<script>
    		function getHeight(){
    			var idoc = document; 
    			if(idoc.body){
    				return Math.max(idoc.body.scrollHeight,idoc.body.offsetHeight);   
    			}else if(idoc.documentElement){
    				return Math.max(idoc.documentElement.scrollHeight,idoc.documentElement.offsetHeight);   
    			}
    		}
    		window.onload = function(){
    			var h = getHeight();
    			document.getElementById("agentIframe").src="http://www.csdn.net#"+h;
    		}
    	</script>
    	agent.html:(http://www.csdn.net)
    	<script>
    	(function(){
    		var con = parent.parent.document.getElementById('frame_content');     
    		var href = parent.parent.frames["frame_content"].frames["iframeC"].location.hash;      
    		con.style.height = href.split("#")[1]+"px";
    	})();
    	</script>
    

    4.iframe背景透明:

    在ie6/7/8下引入iframe的时候,它的背景默认是白色,即使设置了style=”background-color:transparent;”也无效,
    但是其他浏览器(firefox,chrome,opera,ie9)都正常显示,要解决这个兼容性问题,必须用到一个属性。
    下面来看看现象:

    index.html:
    <body style="background-color:#00f;">
    <iframe frameborder="0" height="200" width="200"  src="son.html" scrolling="yes" id="myiframe" 
    style="background-color:transparent;"></iframe>
    </body>


    结果如下图:(FF中有滚动条是因为在index.html中设置了有滚动条)

    解决:
    给iframe设置属性:allowTransparency=”true” //设置为true允许透明

    <body style="background-color:#00f;">
    <iframe allowTransparency="true" frameborder="0" height="200" width="200"  src="son.html" 
    scrolling="yes" id="myiframe"></iframe>
    </body>


    备注:iframe不设置此属性时,可使用iframe解决在IE6、7环境中遮住select

    5.判断页面中是否有iframe:

    	a>首先来看看window.frameElement这个属性。
    		返回嵌入当前window对象的元素(比如 <iframe> 或者 <object>),即为包含本页面的iframe或frame对象。如果当前window对象已经是顶层窗口,则返回null.
    		看看一个例子:
    		parent.html:
    		<body>
    		<iframe frameborder="1" width="400" height="400" src="son.html" scrolling="no" id="myiframe"></iframe>
    		</body>
    		son.html:(注意frameElement用在son.html中,如果用在parent.html中,则返回null)
    		<body>
    		<div id="msg">Hello world!!!</div>
    		<script type="text/javascript">
    			var iframe = window.frameElement;
    			if(iframe){
    				iframe.src = "http://blog.csdn.net/cuew1987";
    			}
    		</script>
    		</body>
    		备注:虽然该属性名为frameElement,但该属性也会返回其他类型比如 <object> 或者其他可嵌入窗口的元素.
    	b>兼容性如下图:


    	c>定义函数:
    		i>判断父页面中是否含有iframe
    		function hasIframe(){
    			return document.getElementsByTagName("iframe").length > 0;
    		}
    		ii>判断某个页面是否在iframe标签中
    		function innerIframe(){
    			var iframe = window.frameElement;
    			if(iframe){
    				return typeof iframe !== "undefined";
    			}
    		}

    6、HTML5中iframe:

    HTML 4.01 与 HTML 5 之间的差异在 HTML 5 中,仅仅支持 src 属性
    <iframe src="/index.html"></iframe>
    HTML5中全局属性:

    7、easyui中form组件提交(包括上传域):

    	function submitForm(target, options) {
    		options = options || {};
    		if (options.onSubmit) {
    			if (options.onSubmit.call(target) == false) {
    				return;
    			}
    		}
    		var form = $(target);
    		if (options.url) {
    			form.attr("action", options.url);
    		}
    		var frameId = "easyui_frame_" + (new Date().getTime());
    		var frame = $("<iframe id=" + frameId + " name=" + frameId + "></iframe>").attr(
    				"src",
    				window.ActiveXObject ? "javascript:false" : "about:blank").css(
    				{
    					position : "absolute",
    					top : -1000,
    					left : -1000
    				});
    		var t = form.attr("target"), a = form.attr("action");
    		form.attr("target", frameId);//在iframe中提交表单
    		try {
    			frame.appendTo("body");
    			frame.bind("load", cb);
    			form[0].submit();
    		} finally {
    			form.attr("action", a);
    			t ? form.attr("target", t) : form.removeAttr("target");
    		}
    		var checkCount = 10;
    		function cb() {
    			frame.unbind();
    			var body = $("#" + frameId).contents().find("body");
    			//contents()查找匹配元素内部所有的子节点(包括文本节点)。如果元素是一个iframe,则查找文档内容
    			var data = body.html();
    			if (data == "") {
    				if (--checkCount) {
    					setTimeout(cb, 100);
    					return;
    				}
    				return;
    			}
    			var ta = body.find(">textarea");
    			if (ta.length) {
    				data = ta.val();
    			} else {
    				var pre = body.find(">pre");
    				if (pre.length) {
    					data = pre.html();
    				}
    			}
    			if (options.success) {
    				options.success(data);
    			}
    			setTimeout(function() {
    				frame.unbind();
    				frame.remove();
    			}, 100);
    		};
    	};
    	另:form 的target属性:
    	a>HTML4中:
    	定义和用法:target 属性规定在何处打开 action URL。
    	兼容性:在 HTML 4.01 中,不赞成使用 form 元素的 target 属性;在 XHTML 1.0 Strict DTD 中,不支持该属性。
    	属性值:
    	_blank 新窗口中打开
    	_self  默认,在相同的框架中打开
    	_parent 父框架中打开
    	_top    整个窗口中打开
    	framename  指定的frame name属性值的框架中打开
    
    	b>HTML5中:
    	HTML 4.01 与 HTML 5 之间的差异
    	在 HTML5 中 target 属性不再是被废弃的属性。不再支持 frame 和 frameset。
    	现在,parent, top 和 framename 值大多用于 iframe。
    

    8、网上问题收集:

    a>window.frameElement在chrome下undefined?

    问题描述:
    今天在重新编写我的日历组件的时候,由于用到使用iframe自定义属性传值,
    将父页面的值写在iframe 自定义属性上,然后在iframe页面中使用 window.frameElement.getAttribute() 获取,
    奇怪的是之前编写的日历控件代码一直都这样写,没有发生过错误,但是今天在chrome里面 window.frameElement 竟然是 undefined,
    在firefox 甚至IE6下都没有问题,后来百度没有答案, 再google 也,没有答案。
    解决:
    最后自己根据以往经验想到或许是本地调试权限问题,于是打开apache使用域名的形式访问,果然可以了,呵呵!

    问题收集持续更新。。。

    说在最后的话:此文中许多都是前辈们的经验,在此做一总结,丰富自我的同时,以备需要之人参考,如果你是大神,请飘过,文中有不当之处,还望各位不要手下留情,不吝赐教,感激不尽!

    今天上午打开微博的第一条消息就是博友转发的李开复:“世事无常,生命有限。原来,在癌症面前,人人平等。”,已身患淋巴癌,在这里希望李开复老师能早日康复!经过几个晚上的努力,此篇文章终于写完,生命不息,奋斗不止!

    201309062026新浪微博李开复:“在以往的职业生涯里,我一直笃信“付出总有回报”的信念,所以给自己的负荷一直比较重,甚至坚持每天努力挤出三小时时间工作,还曾天真的和人比赛“谁的睡眠更少”、“谁能在凌晨里及时回复邮件”……努力把“拼命”作为自己的一个标签。现在,冷静下来反思:这种以健康为代价的坚持,不一定是对的。”

    我想这就是所谓的人生价值吧。祈福!

  • 相关阅读:
    “冷面杀手”王励勤赢了
    当VS.NET 无法调试时,不妨尝试一下下面的办法
    Oracle如何调用Windows动态链接库
    根本不值得一提的乒乓球国手王浩
    向总版主提一些建议
    你的家乡话,你还知多少
    黄山三日游(200706020604)
    今天是我的生日,常怀感恩的心
    如果有一个工具可以帮助你将你的代码可视化,你需要吗?
    是社会变化太快,还是我心态有有点怪
  • 原文地址:https://www.cnblogs.com/riskyer/p/3306207.html
Copyright © 2020-2023  润新知