前端頁面中的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",<iframeframeborder="0"width="400"height="400"src="http://blog.csdn.net/cuew1987"scrolling="no"></iframe>
- ii>DOM操作:
- <body>
- <iframeframeborder="1"width="400"height="400"
- <script>
- var myiframe = document.getElementById("myiframe");
- myiframe.style.border="none";//FF下有效,IE下無效
- myiframe.setAttribute("frameborder",0);//FF下有效,IE下無效
- myiframe.frameBorder =
- </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>等到的資訊:<divid="msg"></div></div>
- <iframeframeborder="1"width="400"height="400"src="son.html"scrolling="no"id="myiframe"></iframe>
- </body>
- son.html:
- <body>
- <inputtype="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>等到的資訊:<divid="setMsg"></div></div>
- <inputtype="button"value="setMsg"onClick="setMsg()"><br>
- <iframeframeborder="1"width="400"height="400"src="son.html"scrolling="no"id="myiframe"></iframe>
- <scripttype="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>
- <divid="msg">Hello world!!!</div>
- </body>
3.iframe高度自適應和跨域:
- 實際使用iframe中,會遇到iframe高度的問題,由於被巢狀的頁面長度不固定而顯示出來的滾動條,不僅影響美觀,還會對使用者操作帶來不便
- a>同域下的高度自適應
- parent.html:
- <body>
- <iframewidth="400"id="myiframe"onload="setHeight()"height="1"frameborder="0"src="son.html"></iframe>
- <scripttype="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)
- <iframewidth="400"id="myiframe"onload="setHeight()"height="1"frameborder="0"src="son.html"></iframe>
- son.html:
- <body>
- <iframeid="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:
- <bodystyle="background-color:#00f;">
- <iframeframeborder="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允許透明
- <bodystyle="background-color:#00f;">
- <iframeallowTransparency="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>
- <iframeframeborder="1"width="400"height="400"src="son.html"scrolling="no"id="myiframe"></iframe>
- </body>
- son.html:(注意frameElement用在son.html中,如果用在parent.html中,則返回null)
- <body>
- <divid="msg">Hello world!!!</div>
- <scripttype="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 = $("<iframeid=" + 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。