HTML FRAMES 可以将文档(HTML 页面)呈现在多个视口中,并且该文档(HTML
页面)可以成为一个独立的窗口或子窗口。当某些视口发生滚动或变化(页面内容改变或被重定向)时,多个视口提供给设计者保持其他视口的信息始终可见的一种方法。例如,在同一个窗口中,第一个 FRAME
可以用来呈现标题等静态信息,第二个 FRAME 可以用来呈现一个导航菜单,第三个 FRAME 可以用来呈现主题内容并且它可以被用户滚动或通过第二个窗口中的导航菜单被新页面替换掉,而这些发生在第三个
FRAME 中的变化是不会影响其他两个 FRAME 的。
请参考 HTML4.01:16.1 Introduction to
frames 。
包含 FRAME 的 HTML 文档(又称:"frameset document")与不包含 FRAME 的文档有着不同的标记。一个标准的 HTML 文档包含一个 HEAD 部分和一个 BODY 部分,然而一个
"frameset document" 包含一个 HEAD 部分和一个 FRAMESET 部分。
文档的 FRAMESET 部分用来指定视口在客户端主窗口中的布局。另外,当客户端不支持 FRAME 或被配置为不显示 FRAME 时,FRAMESET 部分可以包含一个非 FRAME 元素作为替换内容。
通常被放置在 BODY 元素内的元素不能出现在第一个 FRAMESET 元素之前,否则 FRAMESET 元素将被忽略。
请参考 HTML4.01:16.2 Layout of frames
。
更多参考资料:
W3C HTML4.01:16.2.1 The FRAMESET
element。
W3C DOM-level_2:Interface
HTMLFrameSetElement。
关于 window.frames 集合资料,请参考各浏览器厂商相关文档: MSDN、 Mozilla Developer Center、 Safari
Refernece Library。
各浏览器对 BODY 元素或通常被放置在 BODY 元素内的元素出现在第一个 FRAMESET 元素之前时,最终生成的文档树存在差异。
由于该问题会引起各浏览器中最后生成的文档树存在差异,最终会导致页面中其他元素的布局可能在各浏览器中的最终表现不同。
所有浏览器 |
---|
下面分别建立四个 HTML 页面,top.html、test.html、frame1.html、frame2.html,页面间的关系及主要内容和作用如下:
top.html中的代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <style> body{font:'arial' 16px/1.5;} </style> <script> window.onload=function(){ var tree = "", string = ""; function build(){ var htmlElement = window.frames["ifr"].document.documentElement; traverse(htmlElement,0); document.getElementById("info").innerHTML += tree; } function traverse(element,level){ var tabs; if (!element.children.length){ tabs = "└"; tree += new Array(level + 1).join(' ') + tabs + element.tagName + "<br />"; return; }else{ tabs = "+"; tree += new Array(level + 1).join('--') + tabs + element.tagName + "<br />"; level++; } for (var i = 0, l = element.children.length; i < l; i++){ traverse( element.children[i] ,level ); } } build(); } </script> </head> <body> <iframe name="ifr" src="test.html"> </iframe> <div id="info"> test.html中 HTML 结点下的结点树形结构如下:<br/> </div> </body> </html>
test.html中的代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> * { font-family: 'Lucida Console' } </style> </head> <form><div><input type="hidden" value="test"/></div><p><span></span></p></form> <frameset cols="40%, 60%"> <frame src="frame1.html" /> <frame src="frame2.html" /> </frameset> </html>
test.html 中 HTML 的结点树形结构如下:
IE6 IE7(S) IE8(S) | IE7(Q) IE8(Q)1 | FireFox |
---|---|---|
+HTML ---+HEAD └TITLE └META └STYLE ------+FORM └INPUT ---+FRAMESET └FRAME └FRAME ---+BODY └DIV ------+P └SPAN |
+HTML ---+HEAD └TITLE └META └STYLE ------+FORM └INPUT ---+FRAMESET └FRAME └FRAME |
+HTML ---+HEAD └META └TITLE └STYLE ---+FRAMESET └FRAME └FRAME |
Opera1 | Safari1 | Chrome |
+HTML ---+HEAD └META └TITLE └STYLE ---+BODY ------+FORM ---------+DIV └INPUT ---------+P └SPAN ------+FRAMESET └FRAME └FRAME |
+HTML ---+HEAD └META └TITLE └STYLE ---+BODY ------+FORM ---------+DIV └INPUT ---------+P └SPAN ---+FRAMESET └FRAME └FRAME |
+HTML ---+HEAD └META └TITLE └STYLE ---+BODY ------+FORM ---------+DIV └INPUT ---------+P └SPAN |
注【1】:Opera 和 Safari 中的差异在于 FRAMESET 结点在文档树中所处的位置不同。Opera 中属于 BODY 的子元素,Safari 中属于 HTML 的子元素。
各浏览器中产生差异的主要原因为:在一个页面中,当 BODY 元素或通常被放置在 BODY 元素内的元素出现在第一个 FRAMESET 元素之前时,各浏览器是按照 "HTML Document" 还是按照 "frameset document" 去生成最终文档树所产生的。从运行结果中可以看到在 IE7(Q) IE8(Q) Opera Safari Chrome 生成的文档树中加入了 BODY 结点,这是各浏览器的修复功能所产生的,根据规范中的描述(通常被放置在 BODY 元素内的元素不能出现在第一个 FRAMESET 元素之前,否则 FRAMESET 元素将被忽略。)可知,只有在 Chrome 中符合规范的描述。
读者也可以将此测试用例在不同浏览器中运行后使用各浏览器特有的调试工具查看最终生成的文档树结构。
针对此问题在各浏览器中产生的差异,要看设计者的最终目的是什么,但始终应该参照规范中的描述使得 BODY 元素或通常被放置在 BODY 元素内的元素不能出现在第一个 FRAMESET 元素之前。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.11 8.0.552.5 dev Safari 5.0.2 Opera 10.63 |
测试页面: |
top.html
|
本文更新时间: | 2010-10-20 |
FRAME FRAMESET BODY