2.9. 框架

框架用于拆分浏览器窗口以便同时在一个窗口中加载多个页面,实现窗口某个部分被滚动或替换而其它部分保持原来视图不变的效果,一定程度上减少网页文件的大小、缩短浏览者等待的时间。

下图所示的网页就可以使用横幅和目录型框架网页来实现(事实上,FusionCharts 使用了其它方法模拟了类似的效果)。其中,无论用户在顶端横幅还是左侧目录中单击超级链接或按钮,实际内容的变化都发生在中间底部那个比较大的内容“工作区”中,即一个浏览器窗口被拆分成相互关联的横幅、目录、内容三个部分,每个部分都加载并显示一个独立的网页。

![virb 的注册表单](../images/fcframeset.png)

[fusioncharts docs](http://docs.fusioncharts.com/tutorial-setup.html) 的横幅和目录型结构

frameset 元素用于创建 框架集 以定义如何拆分浏览器窗口,窗口拆分出来的每一个部分都称为一个 框架,使用 frame 元素来表示。

frameset 元素使用 colsrows 属性来定义在水平和竖直方向拆分浏览器窗口的方法,它们都接受使用引号括起来并用逗号分隔的值列表,这些数值指定了框架的像素数或百分比宽度(对列而言)或者高度(对行而言),值的数目决定了浏览器将会在浏览器窗口中显示 的框架的 数量

如:

<frameset rows="150, *, 150">
    <frame src="top.htm" />
    <frame src="main.htm" />
    <frame src="bottom.htm" />
</frameset>

会将浏览器窗口沿水平方向拆分成 3 行,其中,顶端和底部框架的高度为 150px 并分别加载页面(使用 frame 元素的 src 属性指定) top.htm 和 bottom.htm,而中间框架的高度为当前浏览器工作区高度减去顶端和底部高度之和之后的数值,并加载页面 main.htm。通常作为 通配符 出现的“*”表示其它框架高度或或确定后的剩余值。

<frameset cols="20%, *">
    <frame src="content.htm" />
    <frame src="main.htm" />
</frameset>

会将浏览器窗口沿竖直方向拆分成 2 列,其中左侧框架宽度为浏览器窗口宽度的 20%,而右侧主要框架的宽度将是浏览器窗口的剩余宽度。

通常一个 frameset 元素只设置 rows 或 cols 属性中的一个,要实现在水平和竖直方向都对浏览器窗口进行拆分的混合框架结构,需要使用 frameset 元素的嵌套。

<frameset rows="30%, 70%">
    <frame src="banner.htm" />
    <frameset cols="25%, 75%">
        <frame src="content.htm" />
        <frame src="main.htm" />
    </frameset>
</frameset>

上例中,先进行行拆分,再讲下方窗口拆分成两列,这样得到 3 个框架页面。

此处需要特别指出的一点是,框架集的定义需要放在和要加载的子页面独立的一个网页文件中,该文件的形式是这样的:

<html>
    <head>
        <title>框架集定义</title>
    </head>
    <frameset rows="100, *">
        <frame src="top.html" name="top" />
        <frame src="main.html" name="main" />
    </frameset>
    <noframes>
        <body>
            抱歉,您的浏览器不支持框架!
        </body>
    </noframes>
</html>

这里尤其要注意,body 元素用于在包含一个页面中的可见元素,由于框架集会将浏览器拆分成多个浏览器窗口以加载多个页面,所以框架集页面的代码中 body 几乎没有存在的必要。但是在框架集中可以使用 noframes 元素包含 body 元素用于在浏览器不支持 frameset 相关元素时向用户显示提示消息,虽然较新的浏览器事实上都支持框架。

HTML 4.01 中为 frame 元素指定了 frameborder 属性用于确定是否显示相邻框架的边框,其属性值是 1(等同于 yes)或 0(等同于 no),虽然该属性表示一种判断,但其属性值的形式说明该属性值并不是一个布尔属性。

某些浏览器中还可以进一步使用 borderbordercolor 指定边框的宽度和颜色,但它们并没有出现在 HTML 4.01 的规范[[1]](http://www.w3.org/TR/html401/present/frames.html#h-16.2.1)[[2]](http://www.w3.org/TR/html401/present/frames.html#h-16.2.2)中。

事实上,大部分浏览器中,无论是 frameborder,还是 border 或 bordercolor,对 frameset 元素中也可指定,不同浏览器对于这三个属性的实现存在明显差异。

如果边框显示,可以为 frame 元素指定布尔属性 noresize 使用用户无法通过拖动框架之间的边框来改变框架的宽度或高度。

可以使用 frame 元素的 scrolling 属性指定当框架页面中内容超过框架宽度和高度是如何显示滚动条,其属性值可能是:

  • auto:在需要的时候显示滚动条
  • yes:即使不需要也始终显示滚动条
  • no:即使需要也不显示滚动条

frame 元素的 name 属性也非常重要,尤其是需要在框架页面之间导航时。如,在一个横幅目录型框架中,如果希望从目录中单击超级链接,不改变目录中页面的内容,而把链接引用的文件显示在内容框架中,此时应当将目录页面中的超级链接的 target 属性值指定为内容框架的 name 属性值。超级链接 a 元素的 target 属性值除了框架集中 frame 元素的 name 属性值以及之前介绍过的 _blank 之外,还可以是:

  • _self:不指定 target 属性时的默认值,当前框架中打开引用文档
  • _parent:在所属框架集视图中打开引用文档
  • _top:离开框架,在当前浏览器整个窗口中打开引用文档

_parent 和 _top 在大部分情况下表现一致,除非在框架集中定义的加载的某个页面又是另外一个加载了多个页面的框架集定义页面。

下面的示例可以帮助我们理解 target 属性设置为不同值时框架间导航的各种情况。

上例中,浏览器中直接加载的页面 fs_frameset.htmlHTML 代码是:

<html>
    <head>
        <title>hyperlinks in frames</title>
    </head>
    <frameset rows="80,*" frameborder="yes">
        <frame src="fs_top.html" name="top" scrolling="no"
        noresize="noresize" id="top" title="顶端导航" />
        <frameset cols="200,*">
            <frame src="fs_innerframeset.html" name="wordofday" border="20"
            scrolling="No" id="left" title="框架中的框架集" />
            <frame src="fs_voclist.html" name="list" id="main" title="单词列表" />
        </frameset>
    </frameset>
    <noframes>
        <body>
        </body>
    </noframes>
</html>

第一个 frameset 元素将浏览器窗口拆分成上下两个部分,而第二个嵌套的 frameset 元素将底部框架拆分成左右两个部分,其中左侧框架加载的页面 HTML 代码如下所示:

<html>
    <head>
        <title>Inner Frameset</title>
    </head>
    <frameset rows="90, *" frameborder="yes">
        <frame src="fs_innertop.html" name="topFrame" scrolling="No"
        noresize="noresize" id="innerLinks" title="链接框架" />
        <frame src="fs_wordofday.html" name="mainFrame" id="wot" title="每日单词" />
    </frameset>
    <noframes>
        <body>
        </body>
    </noframes>
</html>

也就是说,这个页面是另外一个框架集页面。

浏览器中打开 fs_frameset.html 后呈现的 4 个实际页面中显示了使用 7 个数字标记的 7 组超级链接,并且在这些链接之后标记了它们 target 属性的属性值,单击这些超级链接将在不同位置显示它们引用的页面或位置。

框架在特定场景中比较有用,比如为了在一个窗口中呈现同时运行的多个页面一些后台管理系统,但是这种页面管理方式也增加了打印、查看源代码、导航等的难度,应该谨慎选用。