目錄索引:
一、 簡介
二、 屬性
三、 功能
四、 應用
一、簡介
網頁“幀”的概念最早是由Netscape所提出,當時全部由“幀”構成的頁面,也被稱之為 “框架集”頁面,在一個“框架集”頁面中,“幀”
是其最小構成單位,每個幀都是一個窗口,用於實現在一個框架集頁面中載入許多其它頁面。而且,W3C也為其推出了三種文檔類型之一的 框架型:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
到了 1996年,Internet Explorer 將iframe元素加入到了 HTML 中,並在IE 4.0中實現了對其支持,在IE5.5中,實現了通過設置allowTransparency屬性來設置透明的 iframe 功能。
iframe 規定了一個“獨立幀”,也叫內聯框架。在這個框架中,可以用於保存另一個頁面的的窗口,文檔等內容。相比於“框架集”頁面,iframe可以被放入到頁面中的任意位置,並且可以與當前頁面其它元素同時存在。
在 HTML4.0 版本之后,iframe 以及“框架集”技術都被不建議使用,這是因為 iframe 對瀏覽器加載頁面具有很大的干擾性,搜索引擎的蜘蛛不會識別在 iframe 中被調用的圖片、文本、url等內容的,因為該內容不屬於該頁面,只是訪問的時候被臨時的調用,
但是目前的 HTML5 中 iframe 又被重新啟用。這是因為它對以下的使用環境,還具有很大的優勢:
· 引入第三方的內容
· 用於需要保存歷史記錄或操作步驟以及焦點的獨立子窗口。
· 用於解決跨域問題。
簡單的了解了iframe與框架集的歷史前身,下面讓我們從最基礎開始學習與iframe相關的知識。
二、屬性
iframe 是一種古老的技術,同時也是一個不斷在改進的技術,學習 iframe 的屬性,這里只針對性的學習 iframe 具有使用價值的屬性。
1. src
規定載入頁面的 URL。
2. name
定義框架窗口的名稱。
a,shape,form等標簽的target屬性,可以指定內容在該框架窗口中打開。
3. frameborder
規定內聯框架邊框線是否顯示,值如果為0表示不顯示邊框線,不為0則表示顯示邊框線。
4. width
設置內聯框架的寬。
5. height
設置內聯框架的高。
6. scrolling
用於控制 iframe 是否出現滾動條,如果取值為 no 則表示不出現滾動條。
7. allowTransparency
設置 iframe 是否為透明。值為 boolean,取值為 true 表示將 iframe 設置為透明。
* 該屬性只有IE瀏覽器支持。
8. seamless
設置 iframe 嵌入的內容,在展示上是否是當前文檔的一部分。
該屬性是 HTML5 新增屬性,實際上也就是取消 iframe 的邊框,滾動條而已。
9. srcdoc
該屬性是 HTML5 新增屬性。用於設置 iframe 中顯示的html內容,值為 html 代碼。
該屬性可覆蓋src屬性,如果指定了 srcdoc 那么 iframe 就顯示 srcdoc 指定的html內容,否則才會顯示src載入的頁面。
示例:
<iframe srcdoc="<p> Hellow World ! </p>" src="exmaple.com/index.html"></iframe>
10. sandbox
該屬性是 HTML5 新增屬性。啟用一系列對 <iframe> 中內容的額外限制。
其是有:
allow-forms : 允許iframe中的表單提交
allow-same-origin : 開啟同源策略,這里的所開啟的同源策略相當於瀏覽器同源策略的子集。
allow-scripts : 允許iframe中的腳本運行
allow-top-navigation : 嵌入的頁面的上下文可以導航(加載)內容到頂級的瀏覽上下文環境(browsing context)。如果未使用該關鍵字,這個操作將不可用。
三、功能
1. 創建 iframe
通過JavaScript創建iframe的標准方法是利用createElement這個方法:
var ifr = document.createElement('iframe');
而IE 8- 則支持另一種特殊插入方法:
var ifr = document.createElement('<iframe id="iframe' src="" ></iframe>');
2. 獲取iframe中的內容
* 以下操作都是在同源情況下執行
· 獲取 window
標准寫法是通過contentWindow屬性,獲取iframe內部的窗口(window)對象。
var ifr = document.getElementById('iframe'); ifr.contentWindow // 即iframe所載入頁面的window對象。
同樣 iframe 也會像 <frame> 元素一樣,加入 window.frames 偽數組中
window.frames['iframe'] // 通過frames偽數可以直接獲取iframe所載入頁面的window對象。
注:iframe 是 id名稱。
也就是說: ifr.contentWindow === window.frames['iframe']
· 獲取 document
用JavaScript獲取iframe載入頁面的document對象,有兩種方式:
方式一: ifr.contentWindow.document
方式二: ifr.contentDocument
需要注意的是,方式二 只有IE8+才能支持。
兼容性解決方案:
var getIframeDocument = function(ifr){ return ifr.contentDocument || ifr.contentWindow.document; };
3. 獲取上層windo對象
在當前iframe頁面中,可以利用以下方式獲取上層頁面的window對象:
window.parent // 獲取上層頁面的window對象。 window.top // 獲取頂層頁面的window對象。
4. 獲得iframe在父頁面中的html標簽
在iframe頁面中可以通過 window.frameElement 獲取到位於上層頁面中的 iframe DOM 對象。
* 注意在某些瀏覽器下,該方式只能作用在服務器環境下。
5. iframe onload
之前遇到過一個需求,需要判斷iframe是否加載完畢,如果沒有加載完成便要展示一個loading層,用於提示正在加載中...
拿到這個需求之后,我直接采用了onlaod事件去判斷iframe是否加載完畢:
代碼:
var ifr = document.getElementById('iframe'); ifr.onload = function() { alert('加載完成!'); }
經過測試,發現在chrome、firefox等主流瀏覽器中都是正常,但是在IE中會出現有時不能觸發onload事件的情況。
當時同事提供了另一種解決方案:
var ifr = document.getElementById('iframe'); ifr.onload = function() { alert('加載完成!'); } ifr.src = 'url';
即頁面中先放入一個空的iframe,先綁定onload事件,再去為iframe設置src的值。
這種方式確實能夠解決onload在IE中有時無法觸發的問題,但是通過js去傳入iframe src的值,這種操作對於加載時間還是有很大的犧牲。因為這種方式首先要頁面加載,然后試行JS,最后才是iframe去加載具體內容。
最后通過查閱資料,發現在IE中 iframe是支持 onreadystatechange 事件,這個事件會根據 iframe 的加載狀態不斷改變,最終再通過readyState去判斷是否加載完成。
具體實現代碼:
function iframeLoad(obj, fn) { obj.isloaded = false; obj.onreadystatechange = function() { if (this.readyState == 'complete') { if (!this.isloaded) { this.isloaded = true; fn && fn(); } } }; obj.onload = function() { if (!this.isloaded) { this.isloaded = true; fn && fn(); } }; }
最后在無意之中看到別人代碼中通過attacheEvent為iframe綁定onload事件,我才明確,原來IE中iframe的onload事件不是不能觸發,而是需要IE私有的事件綁定方法綁定才能觸發:
完美解決代碼:
function iframeLoad(ifr, fn) { if (window.attachEvent) { ifr.attachEvent('onload', fn); } else { ifr.onload = function() { fn(); } } }
6. iframe 全屏
全屏方法是HTML5的新標准,目前在瀏覽器中只有Chrome以及Firefox才支持,具體實現的標准也都是各個瀏覽器廠商的私有標准。
例如Chomre瀏覽器中:
element.webkitRequestFullScreen() // 開啟全屏 document.webkitCancelFullScreen(); //退出全屏 element.onwebkitfullscreenchange; // 全屏事件 document.IsFullScreen; // 是否全屏
而Firrefox中:
element.mozRequestFullScreen(); // 開啟全屏 document.mozCancelFullScreen(); //退出全屏 element.onmozfullscreenchange; // 全屏事件 document.mozFullScreen; // 是否全屏
通過以上方法與屬性,我們可以為iframe設置全屏展示效果。
四,應用
1. 防嵌套網頁
我們不僅要學會如何嵌套好頁面,也應該掌握自己的頁面不被其它方惡意嵌套。
最簡單的方式,判斷頂層窗口是否就是本窗口。
if (window != window.top) { window.top.location.href = self.location.href; }
2. 廣告
通過iframe載入廣告頁面,優點就在於iframe相當於一個獨立的沙盒,你引入額外的css和js文件,也不會對當前頁面的布局或功能產生影響。
一般而言使用iframe 載入廣告都是在頁面中創建一個跟自己同域的空iframe。然后用這個iframe去載入對應的廣告頁面即可。
嵌入廣告用的iframe模板:
<iframe width="728" height="90" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" onload="" style="left:0;position:absolute;top:0;"></iframe>
3. 高度自適應
· 外部檢測高度
(function(root){ var iframe = document.getElementById('iframe'); function setHeight(){ var doc = iframe.contentDocument || iframe.contentWindow.document, height = doc.documentElement.scrollHeight || doc.body.scrollHeight; iframe.style.height = height + 'px'; } if(window.attachEvent){ iframe.attachEvent('onload',function(){ setHeight(); }); }else{ iframe.onload=function(){ setHeight(); } } }(window));
這種方式,需要在 iframe 的 onload 事件中進行高度處理,如果此時改變嵌套頁面的內容,並不會再次觸發onload事件。
· 內部響應高度
(function(root){ var height = 0, back = 0; function heightCompare(){ try{ height = document.documentElement.scrollHeight || document.body.scrollHeight; if(height != back){ window.frameElement.style.height = height + 'px'; back = height; } setTimeout(arguments.callee,1000); }catch(e){} } heightCompare(); }(window));
相比之下,更加推薦這種方式,因為通過定時器實時檢測,可以動態的根據iframe頁面中的內容變化而變化。另外代碼的維護也統一在被嵌套頁面。
PS : ~ 轉載 的童鞋請注明出處哦!另外,如果有不足之處,或者是更好的建議,請一定要給我留言 ~