1、 快速精通掌握 FRAME 的使用FRAME(框架)是 Web 上经常会看到的页面结构。使用可视 Web 开发工具(比如 Dreamweaver 或者Frontpage) ,虽然可以在 WYSIWYG 环境中通过简单的鼠标托拽完成 FRAME 的构建,但是要实现真正细致甚至强大的功能,仔细理解 FRAME 的代码结构至关重要!你将发现,FRAME 原来是这样的亲切易用。 创建基本的 FRAMESET FRAMESET 页面与普遍的 Web 页面有些不同。虽然仍旧以HTML和包含标题的HEAD标记以及其他脚本开始,但是其内容仅仅是表示的各个页面的版式设计。因此,不再需要有BODY元素,只需要FR
2、AMESET标记。 通过FRAMESET标记的rows和cols属性,浏览器窗口被分割为一个个格子。rows和cols的设置值可以是固定的像素值,可以是总空间的百分比值,还可以是用*以及一个数字相乘表示的分割剩余空间的比例值。比如说: cols=“80,20%,*“ 分为 3 列,宽度分别为 80 像素,窗口宽度的 20,以及剩余宽度 rows=“25%,75%“ 分为 2 列,宽度分别为窗口宽度的 25和 75 rows=“*,3*“ 与上述第 2 个表示的一样,分为 2 列,但表示方法不同:第一列宽度为第二列的 1/3 在FRAMESET和/FRAMESET之间,用多个FRAME标记表示每
3、个分割区。col 表示从左到右的列,row 表示从上到下的行。每个 FRAME有一个 src 属性,给出了这个 FRAME 的内容。它可以是浏览器能显示的任何一个合法 URL,或者是另外一个 FRAMESET。为预防递归现象,一个 FRAME不能包含它本身所在的 FRAMESET 页面。要用 name 属性定义 FRAME 的名字,这样就可以在代码或者脚本程序中引用它。 请看一段基本的 FRAMESET 代码: HTML HEAD TITLESimple FRAMESET/TITLE /HEAD FRAMESET cols=“40%,60%“ rows=“2*,*“ FRAME name=“T
4、opLeft“ src=“red.htm“ FRAME name=“TopRight“ src=“green.htm“ FRAME name=“BotLeft“ src=“blue.htm“ FRAME name=“BotRight“ src=“white.htm“ /FRAMESET /HTMLFRAMESET rows=“105,*“ FRAME name=“adbanner“ src=“ad.html“ FRAMESET cols=“40%,60%“ FRAME name=“left“ src=“red.htm“ FRAMESET rows=“*,*“ FRAME name=“top“
5、src=“blue.htm“ FRAME name=“bottom“ src=“white.htm“ /FRAMESET /FRAMESET /FRAMESET FRAME 间的链接 一个 FRAMESET 结构的页面,新文档只转载进窗口的一部分中,而其他页面则保持静态不变。当用户点击 FRAME 中的链接时,新内容就在同一 FRAME 内打开。要让新内容在其他 FRAME 中打开,可以设置A标记的 target 属性值为那个 FRAME 的 name 值。 而且,我们还可以设置打开目标为当前可见的任意一个 FRAME,而不局限于本身的 FRAMESET。目标可能是一个嵌套的 FRAMESET
6、 中的 FRAME,也可能是其他窗口中的 FRAME。但是如果目标FRAME 不存在,就会产生一个带有目标 FRAME 名字的新窗口。 下面举个例子说明一下,假设有一个简单含 2FRAME 的 FRAMESET,文件名叫做 home.html,代码如下: HTML HEAD TITLE FrommCo home page/TITLE/HEAD FRAMESET cols=“115,*“ FRAME src=“menu.htm“ FRAME name=“content“ src=“main.htm“ /FRAMESET /HTML 文件 menu.htm 在左边的 FRAME 中,其中有一系列链
7、接,点击它们后新内容将在右边的叫做 content 的 FRAME 中打开。下面是 menu.html 的代码: HTMLHEAD/HEAD BODYP BR IMG src=“http:/ alt=“FrommCo“P A href=“main.htm“ target=“content“Main page/AP A href=“mission.htm“ target=“content“Our mission/AP A href=“staff.htm“ target=“content“Our staff/AP A href=“splash.htm“ target=“_parent“FrommC
8、o splash page/A /BODY/HTML 请注意最后一个链接中 target 的定义为_parent ,这属于 4 个特殊的保留值。它们是: _parent:在当前 FRAMESET 位置显示新 href。 _top:在当前整个窗口位置显示新 href,比如本身 FRAMESET 位于另一个 FRAMESET 中。 _self:强制在当前 FRAME 中显示新 href。 _blank:在新窗口中显示 href。 表示客户端图形地图的AREA 标记同样可以应用 target 属性,比如: AREA shape=circle coords=“75,75,50“ href=“main.
9、htm“ target=“content“ alt=“Main page“ 还有一种经常的情况是:Web页面中的大部分或者全部链接都要求在一个特别的 FRAME 中打开。这时,可以在页面的HEAD 代码区使用BASE标记设置默认的 target,然后再分别定义特殊链接的 target 值。 修饰 FRAME FRAMESET 不仅在宽度、高度等方面具有可控制的数值,在美观方面也同样可以精确设置。 默认情况下,FRAMESET 的 FRAME 间有一个凸起的边沿,表示分割效果。如果不喜欢这个,想营造“无缝连接”的效果,可以在FRAME标记中设置 FRAMEborder=0 来消除它。在 3.0
10、及高版本的Navigator 和 Internet Explorer 中,如果在FRAMESET标记中设置 FRAMEborder=0,那么除了设置为FRAMEborder=1 的 FRAME 外,所有其他 FRAME 的边沿都将消失。 虽然设置了 FRAMEborder=0,有些浏览器仍旧会在 FRAME 间保留一些边沿的颜色痕迹。这时,可以在FRAMESET标记中添加 FRAMEspacing=0(对 Internet Explorer)或者 border=0(对 Navigator 和Opera)实现真正的无缝连接。 请看下面的代码是如何使用这些属性的:HTML HEAD TITLE F
11、rommCo home page/TITLE/HEAD FRAMESET cols=“115,*“ FRAMEspacing=0 border=0 FRAME src=“menu.htm“ FRAMEborder=0 noresize scrolling=no FRAME name=“content“ src=“main.htm“ FRAMEborder=0 /FRAMESET /HTML 上面的代码中有 2 个新的属性:noresize 表示锁住 FRAME 而不允许使用鼠标改变大小,scrolling=no 表示屏蔽 FRAME 的滚动条,scrolling=yes 表示允许, scrol
12、ling=auto 表示根据显示内容需要自动显示滚动条。 浮动 FRAME 浮动 FRAME 是 HTML4.0 规范中的一个定义,目前的浏览器都支持它。 不象 FRAMESET 表示的分割区样子,一个浮动 FRAME 作为一个内置对象存在于 Web 页面上,其样式就象一个页面上的一个图形或者一个 applet。浮动 FRAME 使用IFRAME标记,它具有与FRAME相同的大多数属性设置,包括:name、src、 marginwidth、marginheight、FRAMEborder 以及scrolling。同时,它还具有与图形或者 applet 一样的 height、width 和 al
13、ign 属性。 而且,浮动 FRAME 遵循与普通 FRAME 一样的 target 原则:我们可以通过它的 name 来指向它。本原则适用于在任一类型 FRAME 中的浮动 FRAME,反之易然。浮动 FRAME 中的没有 traget 的链接指向它本身,而_parent 链接则指向包含IFRAME的文档所在的 FRAME 或者窗口。比如: IFRAME name=“floater“ src=“start.htm“ width=150 height=200 hspace=10 align=left IMG src=“http:/ alt=“You cant see the floating
14、FRAME“ width=150 height=200 hspace=10 align=right /IFRAMEBR A href=“one.htm“ target=“floater“Show one.htm /AP A href=“two.htm“ target=“floater“Show two.htm/AP A href=“start.htm“ target=“floater“Bring back start.htm/A 注意,对应支持IFRAME标记的浏览器,任何位于IFRAME和/IFRAME间的内容都将忽略。反之,其中的内容将显示出来,这可以用作解释当前浏览器不支持IFRAME。
15、 何时使用 FRAME 我们知道,FRAMESET 的基本用途就是分割浏览器窗口,使得窗口的一部分内容改变,而其他部分保持不变。利用这个特性,就可以实现工具栏导航功能,一个 FRAME 内放置静态菜单页面,用户点击其中的项目后,在另外的 FRAME 内显示相关的内容。这样就可以从整体上减少文件大小,因为不必在每个内容页面中再包含菜单项目。 FRAME 有 2 个明显的不足: FRAME 从另外的级别上增加了站点的管理,原因在于超级链接不仅仅要指向适当的页面,而且也会装载到相关的 FRAME 内。 另外,大多数浏览器在执行“添加书签”的操作时,只能记录下 FRAMESET 的初始位置。不管添加书
16、签时是位于多么深的 FRAMESET 中,当再次选择这个书签时,就会返回到 FRAMESET 的初始页面。这就加大了访问者浏览指定内容的难度。 但是,如果好好地组织站点信息,使导航操作只有不深的几层,那么,使用 FRAME 就能很好地为访问者服务。记住:访问者都希望简洁的导航信息。 当然,导航并非是使用 FRAME 的唯一原因,也可以使用 FRAME 创建交换工具和交换页面。而且,FRAME 的多文档框架结构非常适于被 javascript 应用程序所操作。 用 FRAME 设计站点 最常用的 FRAME 结构就是“菜单内容”FRAMESET。一个 FRAME 内放置导航菜单,另一个FRAME
17、 内转载子菜单,每个子菜单的链接就指向本身。唯一的有 target 的链接都在菜单 FRAME 内。 请看下面的例程代码: HTMLHEAD TITLEWelcome to my site!/TITLE /HEAD FRAMESET cols=“150,*“ FRAME name=“menu“ src=“menu.htm“ FRAME name=“content“ src=“intro.htm“ /FRAMESET BODY !-如果是支持 FRAME 的浏览器,则不会显示下面的内容;否则,也显示出简单菜单页面 - Welcome to my site.P A href=“intro.htm“
18、Introduction/A A href=“products.htm“Products/A A href=“reviews.htm“Reviews/A /BODY/HTML 用脚本控制导航 FRAME 上面介绍了 FRAME 的 HTML 代码结构,现在开始走向更深一步:使用脚本程序控制 FRAME。 每个 Window 对象有一个 FRAMEs 数组。对于普通的 Web 页面,这个数组是空的,其属性 length为 0。带有 FRAMESET 的页面,按照其上FRAME标记的前后顺序,生成一个 FRAME 数组。由于FRAMESET 所在页面是每个 FRAME 的 parent 窗口,数组
19、索引从 0 开始,所以从 FRAMESET 中引用第3 个 FRAME 时就使用 self.FRAMEs2,从其他 FRAME 文档中引用第 3 个 FRAME 时就使用parent.FRAMEs2。 FRAME 数组中的每一个成员都是一个窗口,它们具有普通窗口的一切方法、事件以及属性,并且包括它自己的 FRAME 数组(当它包含另外一个 FRAMESET 时) 。因此,用脚本去修改一个 FRAME 的内容就象修改它的 location.href 一样简单。 下面举例说明,假设一个 FRAMESET 包含 3 个同样的 FRAME,都位于窗口下部: FRAMESET rows=“60%,40%
20、“ FRAME name=“link“ src=“link.htm“ FRAMESET cols=“*,*,*“ FRAME name=“blank1“ src=“blank.htm“ FRAME name=“blank2“ src=“blank.htm“ FRAME name=“blank3“ src=“blank.htm“ /FRAMESET /FRAMESET 第一个 FRAME 中的文档叫做 link.htm,使用点击其中的单一链接就可以修改其他三个 FRAME 中的内容。实现代码如下: a href=“javascript:navAll()“修改下面 3 个 FRAME 的内容/a
21、SCRIPT language=“javascript“!- function navAll() parent.FRAMEs1.location.href=“red.htm“; parent.FRAMEs2.location.href=“blue.htm“; parent.FRAMEs3.location.href=“white.htm“; / -/SCRIPT 用脚本控制动态 FRAME 如果 FRAME 中变化的内容不多,就可以考虑使用脚本程序动态生成其内容。这样就不用再创建单独的小 HTML 页面,无需从服务器上下载。创建内容的方法与在任何窗口中书写内容一样,都是通过document 对
22、象。 举个例子说明一下。假设要在一个 FRAME 内显示小组成员的相片,并在其下的一个小 FRAME 内显示该成员的名字等信息。首先建立信息数组: empID = new Array(); empID0 = Dana Corolla, CEO; empID1 = Arturo Montero, senior editor; empID2 = Percy Tercel, head designer; empID3 = Angus Coupedeville, astrologer; 然后,建立小组成员照片的图形地图,将每个AREA链接到函数 showMe(n),由它负责根据索引数据创建信息: pa
23、rt1 = HTMLHEAD/HEAD; part1+= BODY bgcolor=#ffffffDIV align=center; part2 = /DIV/BODY/HTML;function showMe(n) parent.FRAMEs1.document.open(); parent.FRAMEs1.document.write(part1); parent.FRAMEs1.document.write(empIDn); parent.FRAMEs1.document.writeln(part2); parent.FRAMEs1.close(); FRAME 间的脚本控制 使用 ja
24、vascript,我们既可以从创建窗口的页面访问那个窗口,也可以从这个窗口创建的窗口访问它。另一方面,FRAMESET 中的文档(包括 FRAMESET 本身)总是可以访问和操纵其中每个的 javascript 函数和变量。比如说,第三个 FRAME 中有函数 sayGobble(vol),那么在其他 FRAME 中就可以使用parent.FRAMEs2.sayGobble(vol)来引用它。同样,FRAMESET 页面中的变量 myName 可以被任何FRAME 以 parent.myName=“Imelda“的命令进行设置。 不管在其他 FRAME 中的内容如何,在静态 FRAME 或者
25、FRAMESET 中的函数和变量始终保持可用。这个特征非常有价值,不仅可以将通用函数保存在其中从而压缩代码,而且,还可以实现页面间转换时的状态保持。 下面的 FRAMESET 页面只有一个 FRAME 叫做 query.htm,并且定义了一个 javascript 变量myWord:HTMLHEAD TITLEPassing data/TITLE SCRIPT LANGUAGE=“javascript“ !- myWord=“; /-/SCRIPT /HEAD FRAMESET rows=“*,1“ FRAMEBORDER=no FRAME name=“active“ src=“query.h
26、tm“ FRAME name=“dummy“ /FRAMESET /HTML 页面 query.htm 有一个文本输入框以及一个到 result.htm 的链接,链接的 onClick 事件将设置 FRAMESET 页面的 myWord 变量为文本输入框的内容。代码如下: HTMLHEAD /HEAD BODY FORM name=“myForm“ INPUT type=text size=12 name=“myText“ P A href=“result.htm“See it in yellow on blue!/A /FORM /BODY/HTML 页面 result.htm 取回并打印出
27、 myWord 的数值,代码是: HTML HEAD /HEAD BODY bgcolor=#0000cc vlink=#99ffff FONT size=+3 color=#ffff00 SCRIPT language=“javascript“!- document.write(parent.myWord); /-/SCRIPT /FONTP A href=“query.htm“Do it again /a /BODY/HTML 这个例子很有实用价值。比如说,你可以设定访问者按一定的次序打开页面,收集用户信息,最后定制出用户特制的显示内容。 谈到状态维护功能,这个方法不会比使用 cookie
28、 或 CGI 更好,因为当 FRAMESET 重载或者退出时,变量值就丢失了。但是,它不要求服务器端响应,也不存在安全问题,因此还是可以小试一把的。 用脚本控制浮动 FRAME 用脚本控制普通 FRAME 与浮动 FRAME 的方法基本相同,唯一的差别是浮动 FRAME 按IFRAME出现的顺序定义索引位置。如果 FRAMEs.length 不为 0,就表示可以安全地处理浮动FRAME。比如说,在下面的代码中,如果存在叫做 floater 的浮动 FRAME,链接就指向它;否则就指向“_top“: IFRAME name=“floater“ src=“trog.htm“ width=200 h
29、eight=200/IFRAME A href=“grot.html“ target=“floater“ See grot.htm/A 带有浮动 FRAME 的 Web 页面是 FRAME文档的 parent 窗口,因此,多个浮动 FRAME 仍然可以通过 parent.FRAME 数组去访问每一个 FRAME。 预防脚本编程错误 尽管 FRAME 是 HTML 的一个稳定规范说明,但 DOM 模型只把它们当做 HTML 元素而不是窗口,因此围绕 FRAME 的脚本编程并不是能很周全地定义。这个不足导致了当装载 FRAME 时会发生一些脚本执行方面的冲突。 立即修改 FRAME 内容的脚本经常
30、会产生错误。原因在于:浏览器通常是先执行脚本命令,然后在按照 src 所示装入页面内容。 解决方法很直接,就是判断 FRAME 内容是否装载完毕。有一个好的处理技巧是以 HTML 页面开始所有的 FRAME,由它象主 FRAMESET 报告装载请看。比如说,有一个 FRAMESET 页面,要等装载完所有的 FRAME 后才能执行函数 goToIt(),那么就将下面的 javascript 程序段放进 FRAMESET 文档中: countDown=FRAMEs.length; function soundOff() countDown-; if (countDown=0) goToIt(); 然后,在每个 FRAME 页面的BODY标记中设置上。当 FRAME 页面装载并执行 soundOFF()后,等到 countDown 为 0 时,就表示 FRAME 完全装载完毕。 总结 FRAME 是双刃剑,使用不好会造成混乱的站点结构和外观,使用得当将大大方便用户的操作方式以及形成清晰的页面风格。相信你看完本文后,会对 FRAME 有了更亲切的认识。