[置頂] iframe使用總結(實戰)

說在前面的話,iframe是能夠作不少事情的。
例如:
a>經過iframe實現跨域;
b>使用iframe解決IE6下select遮擋不住的問題
c>經過iframe解決Ajax的前進後退問題
d>經過iframe實現異步上傳。(Easyui中form組件就是用的iframe,實現表單提交時,能夠提交上傳域)
下面就一些問題一一論述。
javascript

一、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>css

可選屬性:

標準屬性:

 

二、操做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)都正常顯示,要解決這個兼容性問題,必須用到一個屬性。
下面來看看現象:html

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中設置了有滾動條)java

解決:
給iframe設置屬性:allowTransparency=」true」 //設置爲true容許透明node

<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解決在IE六、7環境中遮住selectchrome

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";
			}
		}

六、HTML5中iframe:

HTML 4.01 與 HTML 5 之間的差別在 HTML 5 中,僅僅支持 src 屬性
<iframe src="/index.html"></iframe>
HTML5中全局屬性:apache

七、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。

八、網上問題收集:

a>window.frameElement在chrome下undefined?跨域

問題描述:
今天在從新編寫個人日曆組件的時候,因爲用到使用iframe自定義屬性傳值,
將父頁面的值寫在iframe 自定義屬性上,而後在iframe頁面中使用 window.frameElement.getAttribute() 獲取,
奇怪的是以前編寫的日曆控件代碼一直都這樣寫,沒有發生過錯誤,可是今天在chrome裏面 window.frameElement 居然是 undefined,
在firefox 甚至IE6下都沒有問題,後來百度沒有答案, 再google 也,沒有答案。
解決:
最後本身根據以往經驗想到或許是本地調試權限問題,因而打開apache使用域名的形式訪問,果真能夠了,呵呵!瀏覽器

 

問題收集持續更新。。。app

 

說在最後的話:此文中許多都是前輩們的經驗,在此作一總結,豐富自個人同時,以備須要之人蔘考,若是你是大神,請飄過,文中有不當之處,還望各位不要手下留情,不吝賜教,感激涕零!

今天上午打開微博的第一條消息就是博友轉發的李開復:「世事無常,生命有限。原來,在癌症面前,人人平等。」,已身患淋巴癌,在這裏但願李開復老師能早日康復!通過幾個晚上的努力,此篇文章終於寫完,生命不息,奮鬥不止!

201309062026新浪微博李開復:「在以往的職業生涯裏,我一直篤信「付出總有回報」的信念,因此給本身的負荷一直比較重,甚至堅持天天努力擠出三小時時間工做,還曾天真的和人比賽「誰的睡眠更少」、「誰能在凌晨裏及時回覆郵件」……努力把「拼命」做爲本身的一個標籤。如今,冷靜下來反思:這種以健康爲代價的堅持,不必定是對的。」

我想這就是所謂的人生價值吧。祈福!

相關文章
相關標籤/搜索