前面的話
框架<frame>已經被廢棄,而內嵌框架<iframe>依然在使用。通過使用框架,可以在同一個視窗顯示不止一個頁面。每份HTML文件稱為一個框架,並且每個框架都獨立於其他的框架
<frameset>
框架結構標籤(也稱為框架集)定義如何將視窗分割成框架,每個frameset定義了一系列行或列
[注意]不能將<body>標籤與<frameset>標籤同時使用
【屬性】
cols 定義框架集列的數目和尺寸
rows 定義框架集行的數目和尺寸
<frameset rows="150,300,150"> <frameset rows="25%,50%,25%"> <frameset cols="100, *"> <frameset rows="*, 100, *"> <frameset cols="10%, 3*, *, *">
<frame>
框架標籤定義了放置在每個框架中的HTML文件
【屬性】
src 規定在框架中顯示的文件的URL
name 規定框架的名稱,用於在javascript中引用元素或作為連結的目標
noresize 指定使用者無法調整框架大小
longdesc 指向帶有框架內容長描述的頁面
scroll
scroll="auto"//預設,需要時顯示滾動條 scroll="yes"//始終顯示滾動條 scroll="no"//從不顯示滾動條
frameborder
frameborder="0"//無邊框 frameborder="1"//(預設,有邊框)
<frame src="frame_a.htm" frameborder="0" name="frame1" scrolling="yes" noresize="noresize" longdesc="w3school.txt" />
<frameset cols="25%,75%"> <frame src="frame_a.htm"> <frame src="frame_b.htm"> </frameset>
<frameset rows="50%,50%"> <frame src="/example/html/frame_a.html"> <frameset cols="25%,75%"> <frame src="/example/html/frame_b.html"> <frame src="/example/html/frame_c.html"> </frameset> </frameset>
<iframe>
內聯框架用於在網頁中顯示網頁。iframe標籤可以很方便地建立框架,但由於建立一個框架意味著要建立一個完整的頁面環境,很耗費資源;因此能不用就儘量不用
【屬性】
src 規定在內聯框架中顯示的文件的URL
name 規定內聯框架的名稱,用於在javascript中引用元素或作為連結的目標
height 規定iframe的高度
width 規定iframe的寬度
longdesc 指向帶有內聯框架內容長描述的頁面(已廢棄)
frameborder(已廢棄)
frameborder="0"//無邊框 frameborder="1"//(預設,有邊框)
scrolling(已廢棄)
scrolling="auto"//預設,需要時顯示滾動條 scrolling="yes"//始終顯示滾動條 scrolling="no"//從不顯示滾動條
seamless 規定iframe看上去像是包含文件的一部分,設定該屬性後,iframe無邊框或滾動條
sandbox 啟用對<iframe>中內容的限制,可以用空格分隔多個屬性值(IE9-不支援)
sandbox=""//應用所有的限制 sandbox="allow-same-origin"//允許iframe內容被視為與包含文件有相同的來源 sandbox="allow-top-navigation"//允許iframe內容從包含文件導航載入內容 sandbox="allow-forms"//允許表單提交 sandbox="allow-scripts"//允許指令碼執行
srcdoc 規定在iframe中顯示的頁面的HTML內容(IE瀏覽器不支援),若瀏覽器支援srcdoc屬性,則將顯示srcdoc屬性的內容;否則將顯示src屬性中規定的檔案
<iframe srcdoc="<p>Hello world!</p>" src="/demo/demo_iframe_srcdoc.html"> </iframe>
target屬性
要了解框架之間的關係,就必須瞭解target屬性
target屬性表示連結開啟方式
1、_self 當前視窗(預設)
2、_blank 新視窗
3、_parent 父框架集
4、_top 整個視窗
5、_framename 指定框架
//外層框架 <frameset cols = "20%, *"> <frame src="left.html"> <frame src="right.html"> </frameset> //裡層框架 <frameset rows = "50%,*"> <frame src="top.html"> <frame src="bottom.html" name="bottom"> </frameset> //錨點頁 <ul class="list"> <li class="in"><a href="chap1.html" target="_self">chap1(_self)</a></li> <li class="in"><a href="chap2.html" target="_blank">chap2(_blank)</a></li> <li class="in"><a href="chap3.html" target="_parent">chap3(_parent)</a></li> <li class="in"><a href="chap4.html" target="_top">chap4(_top)</a></li> <li class="in"><a href="chap5.html" target="bottom">chap5(framename)</a></li> </ul>
框架指令碼
如果頁面中包含框架,則每個框架都擁有自己的window物件,並且儲存在frames集合中。在frames集合中,可以通過數值索引(從0開始,從左至右,從上到下)或者框架名稱來訪問相應的window物件。每個window物件都有一個name屬性,其中包含框架的名稱
<frameset rows = "40%,*"> <frame src="https://www.hao123.com/" name="topFrame"> <frameset cols = "50%,50%"> <frame src="http://www.baidu.com" name="leftFrame"> <frame src="http://www.kongzhong.com/" name="rightFrame"> </frameset> </frameset>
top物件始終指向最高(最外)層的框架,也就是瀏覽器視窗。使用它可以確保在一個框架中正確地訪問另一個框架。因為對於在一個框架中編寫的任何程式碼來說,其中的window物件指向的都是那個框架的特定例項,而非最髙層的框架。下圖展示了在最髙層視窗中,通過程式碼來訪問前面例子中每個框架的不同方式
與top相對的另一個window物件是parent。顧名思義,parent(父)物件始終指向當前框架的直接上層框架。在某些情況下,parent有可能等於top。但在沒有框架的情況下,parent一定等於top(此時它們都等於window)
<frameset rows = "40%,*"> <frame src="top.html" name="topFrame"> <frameset cols = "50%,50%"> <frame src="left.html" name="leftFrame"> <frame src="right.html" name="rightFrame"> </frameset> </frameset>
<!-- right.html--> <frameset cols = "50%,50%"> <frame src="red.html" name="redFrame"> <frame src="blue.html" name="blueFrame"> </frameset> </head>
瀏覽器在載入完第一個框架集以後,會繼續將第二個框架集載入到rightFrame中。如果程式碼位於redFrame(或blueFrame)中,那麼parent物件指向的就是rightFrame。可是,如果程式碼位於topFrame中,則parent指向的是top,因為topFrame的直接上層框架就是最外層框架
[注意]除非最高層視窗是通過window.open()開啟的,否則其window物件的name屬性不會包含任何值
與框架有關的最後一個物件是self,它始終指向window。實際上,self和window物件可以互換使用。引入self物件的目的只是為了與top和parent物件對應起來,因此它不格外包含其他值
所有這些物件都是window物件的屬性,可以通過window.parent、window.top等形式來訪問。同時,這也意味著可以將不同層次的window物件連綴起來,例如window.parent.parent.frames[0]
在使用框架的情況下,瀏覽器中會存在多個Global物件。在每個框架中定義的全域性變數會自動成為框架中window物件的屬性。由於每個window物件都包含原生型別的建構函式,因此每個框架都有一套自己的建構函式,這些建構函式一一對應,但並不相等。例如,top.Object並不等於top.frames[0].Object。這個問題會影響到對跨框架傳遞的物件使用instanceof操作符。最典型的影響就是陣列的型別檢測
iframe指令碼
通過getElementsById()等方法獲得的是iframe的DOM節點,而並非iframe的window。使用contextWindow屬性可以獲得iframe節點的包含的window物件,或者使用contentDocument屬性獲得包含的document物件
[注意]IE7-瀏覽器不支援contentDocument屬性
如果使用frames[序號]或者frames[name]獲得的就是iframe的Window物件
<iframe id = "frameID" name="frameName" src="top.html"></iframe> <script> var frameID = document.getElementById('frameID'); var frameWindow = frameID.contentWindow; var frameDocument = frameID.contentDocument; //<iframe> window document console.log(frameID,frameWindow,frameDocument); //window window console.log(frames[0],frames.frameName); </script>
iframe元素遵守同源政策,只有當父頁面與框架頁面來自同一個域名,兩者之間才可以用指令碼通訊
iframe視窗內部,使用window.parent引用父視窗。如果當前頁面沒有父視窗,則window.parent屬性返回自身。因此,可以通過window.parent是否等於window.self,判斷當前視窗是否為iframe視窗
if (window.parent !== window.self) { // 當前視窗是子視窗 }
iframe嵌入視窗的window物件,有一個frameElement屬性,返回它在父視窗中的DOM節點。對於那麼非嵌入的視窗,該屬性等於null
<!-- 父網頁--> <iframe id = "frameID" name="frameName" src="top.html"></iframe> <script> var num = 10; </script>
<!-- 子網頁 --> <script> var num = 5; console.log(window.parent.num,window.top.num,window.self.num);//10 10 5 console.log(window.frameElement);//<iframe> </script>
window物件的frames屬性返回一個類似陣列的物件,成員是所有子視窗的window物件。可以使用這個屬性,實現視窗之間的互相引用。比如,frames[0]返回第一個子視窗,frames[1].frames[2]返回第二個子視窗內部的第三個子視窗,parent.frames[1]返回父視窗的第二個子視窗
需要注意的是,window.frames每個成員的值,是框架內的視窗(即框架的window物件),而不是iframe標籤在父視窗的DOM節點。如果要獲取每個框架內部的DOM樹,需要使用window.frames[0].document的寫法
另外,如果iframe元素設定了name或id屬性,那麼屬性值會自動成為全域性變數,並且可以通過window.frames屬性引用,返回子視窗的window物件