VS2005里Frameset的使用方法
一. 建立Frame
1.建立一个基本的Frame
2.建立frame之间的链接
3.美化你的Frame
4.浮动(float)Frame
二. 使用Frame
1.当我们使用Frame
2.设计一个含框架(Frame)的站点
三. 关于Frame的脚本
1.Frame导航的脚本
2.动态Frames脚本
3.Frame窗口间的脚本影响
4.浮动Frame的脚本
5.预防脚本出错
-----------------------------------------------------
前言
Frame是HTML中用来设置框架的标签。框加可以在一个页面里开设多个窗口,以满足不同的设计需要,例如:将网站的菜单导航部分固定在一个窗口中,可以减少相同页面下载时间。从Navigator 2.0允许使用Frame标签开始,现在大部分的浏览器都支持frame标签,并且已经成为HTML 4.0的标准规范。我们的文章分三部分:
一. 建立Frame
学习Frame标签的最好办法是直接建立Frame网页。
二. 使用Frame
熟练掌握Frame,可以成为你设计制作的得力助手。使用不好,则会产生麻烦讨厌的结果。我们将帮助你正确使用Frame,如果你已经建立了Frame网页,我们可以提供关于更好的组织构架frame的一些建议。
三. 关于Frame的脚本
已经有相当多的关于Frame的控制脚本,可以帮助你建立多样的,动态的Frame。
----------------
一. 建立Frame
----------------
1.建立一个基本的Frame
一个frame页的HTML原代码和普通的网页代码不完全相同。它也样有<HTML>标签和<HEAD>标签,可以包含网页标题和一些脚本或者meta标签,但是因为Frame中显示的是其他页面,所以在内容上,使用<FRAMESET>替代<BODY>标签。
<FRAMESET>标签中用来横向,纵向划分浏览器窗口的属性是<rows>和<cols>,通过它们可以设置横向或纵向分割的尺寸。设置方法有三种:1.使用精确的pix数值,2.使用相对百分比,3.使用*号。例如:
cols="80,20%,*" 是指纵向分80 pixels, 浏览器窗口宽度的20%, 和剩余的部分三个窗口
rows="25%,75%" 是指将浏览器窗口分为上下两个窗口,上面占25%,下面占75%
rows="*,3*" 和上一句的意思一样,分成上面1/4,下面3/4的两个窗口
在<FRAMESET>和</FRAMESET>标签之间,你需要为每一个窗口设置<FRAME>标签,标签里设置该窗口的名称和所显示的页面URL。注意:窗口名称要不同,便于将来对该窗口进一步操作。例如:
<HTML>
<HEAD>
<TITLE>简单的frameset</TITLE>
</HEAD>
<FRAMESET cols="40%,60%" rows="2*,*">
<FRAME name="TopLeft" src="red.htm">
<FRAME name="TopRight" src="green.htm">
<FRAME name="BotLeft" src="blue.htm">
<FRAME name="BotRight" src="white.htm">
</FRAMESET>
</HTML>
在上面的例子中,<FRAMESET>中同时使用'rows'和'cols'属性建立一个四方格样子的框架,frame的设置默认的是从左面到右面,从上面到下面。
要制作非格子状的框架,你可以嵌套<FRAMESET>,在一个窗口中再划分出子窗口,只要用<FRAMESET>代替<FRAME>标签。同样,也可以在子窗口里再设置它的rows,cols,建立子窗口的子窗口。例如:下面这段代码显示了三层<FRAMESET>嵌套的四个窗口:
<FRAMESET rows="105,*">
<FRAME name="adbanner" src="ad.html">
<FRAMESET cols="40%,60%">
<FRAME name="left" src="red.htm">
<FRAMESET rows="*,*">
<FRAME name="top" src="blue.htm">
<FRAME name="bottom" src="white.htm">
</FRAMESET>
</FRAMESET>
</FRAMESET>
2.建立frame之间的链接
在一个含框架的静态页面中,点击某个窗口中的链接来调用新的页面,新页面只会显示在这个窗口中。但是,如果我希望点击一个窗口中的链接,内容显示在另外一个窗口内,应该怎样做呢?就象常见的点击左列菜单,右面主窗口中显示变化内容。你可以这样实现,在链接标签<a>的中增加target属性来指定要链接Frame的name。用target属性可以指定当前浏览器窗口中任何存在的frame页。如果该frame页不存在,将会打开一个新窗口。
例如:你现在有一个简单的含左右两个窗口的Frame页面,文件名为home.html,原代码为:
<HTML>
<HEAD><TITLE>My home page</TITLE></HEAD>
<FRAMESET cols="115,*">
<FRAME src="menu.htm">
<FRAME name="content" src="main.htm">
</FRAMESET>
</HTML>
你需要点击左列窗口menu.htm中的链接,变化内容显示在右列名为content的窗口中,那么menu.htm的代码可以这样写:
<HTML><HEAD></HEAD>
<BODY>
<A href="main.htm" target="content">Main page</A><P>
<A href="menu1.htm" target="content">menu1</A><P>
<A href="menu2.htm" target="content">menu2</A><P>
<A href="menu3.htm" target="_blank">menu3</A>
</BODY></HTML>
其中target="content"就是指将链接的内容显示在name为content的窗口中。最后的target="_blank"是target标签的保留参数,意思是将链接打开在一个新窗口中。同样的保留参数还有:
"_parent"是指将链接内容显示在父窗口中;
"_top"是指将链接内容显示在整个窗口中;
"_self"是指将链接内容显示在自己当前的frame窗口中。
target属性同样可以用在map图的<AREA>标签中,一张图的不同部分可以链接到不同的frame窗口中,例如:
<AREA shape=circle coords="75,75,50"
href="main.htm" target="content"
alt="Main page">
如果一个页面内大部分或者所有的链接都指向同一个frame窗口,你可以用<BASE>标签在此页的<HEAD>区设置默认的链接frame窗口,例如:<BASE target="content">,如果有特殊的链接,则单独设置。
注意:<FRAME>标签中必须设置src属性,如果你希望初始页是空白页,必须在src中指定一个空白页。
3.美化你的Frame
Frame的普通设置已经没有问题了。浏览器开发商又为<FRAME>增加了许多属性来帮助网页设计师美化框架,以满足不同的设计需求。
默认的,Frame的不同窗口中间有凸起的边框为界。现在你可以去掉这些边框,使不同窗口完美的结合在一起,看上去象是一个单独的完整页面。在HTML 4.0中,在<FRAME>标签中设置frameborder=0属性,就可以消除边框。Netscape3.0和IE3.0以上版本浏览器都支持这个属性。你如果需要保留边框,可以将frameborder设置为1。
不同的浏览器还提供一些特有的frame属性,用来设置彩色的边框。因此为了确保frame的框架不被显示出来,你还必须在<FRAMESET>标签里增加两个属性:针对InternetExplorer浏览器设置framespacing=0,针对NC和Opera浏览器设置border=0。例如:
<HTML>
<HEAD><TITLE>My 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>
在我们上面的例子中,你会注意到有更多的属性需要设置。例如你可以用鼠标拖动随意改变frame窗口的大小。我们可以用'noresize'属性来锁定这一功能。同样的可以用'scrolling=no'属性来禁止滚动条的出现,如果需要滚动条可以设置为'scrolling=yes',默认设置是滚动条在内容超出窗口尺寸时自动出现。
还有两个<FRAME>属性:'marginheight'和'marginwidth',设置确切的pixel数值可以设定页面内容和边框的距离。通常我们设置为0,如果不设置,它的属性将采用浏览器的默认设置。
4.浮动(float)Frame
目前,浮动Frame只有IE3.0以上版本支持,然而,它们已经被收录到HTML 4.0标准规范中。在NC5.0以上版本也开始支持这一效果。
和一般Frame不同,浮动Frame类似一个物件直接包含在普通页面里,看上去更象是一张图片,一个java applet。设置浮动frame使用<IFRAME>标签,<IFRAME>标签有着<FRAME>标签的大部分属性,象:name,src,marginwidth,marginheight, frameborder, 和scrolling,但是它又有类似图片的height,width和align属性。(IE浏览器甚至支持非标准的hspace和vspace属性。)
浮动frame和标准frame有一样的target属性规则:如果你想链接到它的父窗口,同样可以直接target父窗口的名称,这个规则适用于浮动Frame在其他frame窗口中。例如:
<IFRAME name="floater" src="start.htm"
width=150 height=200 hspace=10 align=left>
<p>你的浏览器不支持IFRAME</p>
</IFRAME><BR>
<A href="one.htm"
target="floater">显示one.htm</A><P>
<A href="two.htm"
target="floater">显示two.htm</A><P>
<A href="start.htm"
target="floater">返回start.htm</A>
注意:<IFRAME>也是围堵标签,需要以</IFRAME>标志结束。如果浏览器不支持<IFRAME>,所有放在<IFRAME>和</IFRAME>之间的内容将被忽视,上面的例子中你只能看到<IFRAME>下面的连接和其中的文字。
浮动frame同样支持用百分比或者具体数值设置高和宽。
----------------
二. 使用Frame
----------------
1.当我们使用Frame
使用Frame的目的是划分窗口,通过这个方法,可以只改变页面的部分内容或者使页面的一部分可以卷动。设计师们常常使用Frame来设计工具(菜单)条,使菜单部分不变,内容部分随菜单的点击而变化。这样可以减少下载文件的大小,因为页面中相同的菜单部分可以不需要重新下载。
使用Frame,大量的小页面文件增加了站点管理的复杂性和层次。每个链接你都需要考虑是否连接到正确的页面,正确的窗口。
另一个frame应用问题是:大部分浏览器的bookmark只支持最初的框架(最外面的页面),如果你进入frame中多层后,希望bookmark子窗口的页面,你得到的只能是最初的Frame页面。这个限制使读者很难直接返回到一个特定的子页面。然而,如果你的站点信息组织得很好,导航清晰,层次不深,Frame可以工作得很好。即使访问者必须点击多层,也可以得到高效简捷的导航。
使用frame不单单为了导航方便,它同样可以用来建立动态的交互性页面,当前大部分浏览器都支持这个功能。它可以和javascript配合建立复杂的多文件结构。
2.设计一个含框架(Frame)的站点
很多流行的网页制作工具可以帮助你方便的建立Frame页面,帮助你设置正确的链接target。但即使你是手工写你的frame站点,建立和管理frame,导航都是很容易的。你甚至可以为不支持frame浏览器的用户提供可以浏览的页面内容。
在常见的'菜单-内容'框架结构中,将导航菜单和内容放在不同的两个frame窗口中,点击菜单,内容显示在另外窗口中。同时也可以设置多级菜单,点击主菜单,在同一个frame窗口中显示子菜单,点击子菜单,内容显示在另外的内容窗口中。在子菜单中点击返回,可以回到上一级的主菜单。
用这种方法也可以为不支持Frame的浏览器制作导航。因为Frame页面不需要<BODY>标签,支持frame的浏览器在读到<BODY>标签时会忽略跳过;而不支持frame的浏览器会忽视<FRAMESET>标签去处理<BODY>的内容。根据这个特性,我们可以同时设置<FRAMESET>和<BODY>标签内容,这样可以使各种浏览器的用户都可以看到正确的内容。例如:
<HTML><HEAD>
<TITLE>Welcome to my site!</TITLE>
</HEAD>
<FRAMESET cols="150,*">
<FRAME name="menu" src="menu.htm">
<FRAME name="content" src="intro.htm">
</FRAMESET>
<BODY>
Welcome to my site.<P>
<A href="intro.htm">Introduction</A>
<A href="products.htm">Products</A>
<A href="reviews.htm">Reviews</A>
</BODY></HTML>
在HTML 4.0标准规范中提供一个<NOFARMES>标签用来包住支持frame浏览器忽略的内容。例如<BODY>中的内容。但是Navigator 4.0和以下版本不支持<NOFRAMES>标签,所以还是需要用上例的方法来设置frame页面。
----------------
三. 关于Frame的脚本
----------------
1.Frame导航的脚本
当你熟练掌握了HTML,你很快就会想知道:如何点击一个连接同时改变两个Frame窗口的内容。这就需要特定的javascript脚本来实现。
每个窗口物件都有一个frames数组特性,在一个普通的网页中,这个数组是空的,长度为0;在含frame窗口的页面中,另外设有一个frame的索引来排列各子窗口的顺序(其中设置frameset的页面是各子窗口页面的父窗口)。所以,你可以在父窗口中用self.frames[2]定义第三个窗口(注意,索引数值是从0开始的);或者在其它子窗口中用parent.frames[2]来定义第三个窗口。
在javascript中,每个窗口内的物件都可以调用这个窗口的特性,例如方法,事件,属性,包括frames数组,所以改变一个子窗口中的内容就非常简单了,只需要修改它的location.herf属性。举例说明:下面建立一个上下两窗口的框架,其中下面的窗口又划分为三个一样的frame子窗口:
<FRAMESET rows="60%,40%">
<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>
要点击上面窗口link.htm中的链接,同时改变下面窗口中三个子窗口内容,可以加入下面的功能代码并将链接设置为href="java script:navAll()":
<SCRIPT language="JavaScript"><!--
function navAll() {
parent.frames[1].location.href="red.htm";
parent.frames[2].location.href="blue.htm";
parent.frames[3].location.href="white.htm"; }
// --></SCRIPT>
如果你的frame页面中已经包含其他的jacascript脚本,它们也将照常工作。注意很重要的一点,你的<FRAME>标签中必须设置src属性,否则脚本无法正常工作。
2.动态Frames脚本
如果一个frame内容只有少量的信息,采用脚本来显示内容的效率常常比独立的HTML网页高,因为普通HTMl页面必须从服务器上重新调阅,而脚本可以直接在客户端生成一些简单的页面。
用这种方法你可以写任何内容到任何窗口,甚至整个frame文档。不同之处就是你可以写不同的内容在同样的窗口,而不需要使用任何DHTML。
假设你想放自己部门员工的一组照片在一个Frame窗口中,鼠标点击照片时,在照片下方的frame窗口中显示他们的名称,职务。那么你可以用下面的一段javascript脚本来代替建立独立的网页。首先建立一个数组,用来存放员工的名称和职务:
empID = new Array();
empID[0] = 'Dana, CEO';
empID[1] = 'Tom, senior editor';
empID[2] = 'Percy, head designer';
empID[3] = 'Mike, astrologer';
然后在照片上建立map图,使不同的链接区域<AREA>链接到showMe(n)功能,以显示不同人的信息。就象下面代码表示的,我们用javascript在frame窗口中写入一个简单的页面:
part1 = '<HTML><HEAD></HEAD>';
part1+= '<BODY bgcolor=#ffffff><DIV align=center>';
part2 = '</DIV></BODY></HTML>';
function showMe(n) {
parent.frames[1].document.open();
parent.frames[1].document.write(part1);
parent.frames[1].document.write(empID[n]);
parent.frames[1].document.writeln(part2);
parent.frames[1].close();
}
用脚本生成新页面并不一定需要类似上面的静态数组,它们也可以随机生成或者由客户定制。
3.Frame窗口间的脚本影响
单独使用javascript,窗口间的影响是有限的,你只能通过创建它的窗口页面来检测或访问这个窗口。但是使用另外的方法:利用Frame的特性,窗口间的javasript功能和变量可以互相访问和操作。例如,如果第三个frame子窗口的页面代码中有sayGobble(vol)功能函数,这个功能相对其它子窗口的调用格式为parent.frames[2].sayGobble(vol),同样的,父窗口中的变量可以在子窗口中声明为parent.myName='Imelda'。
在一个静态的frame框架中的功能函数和变量,可以读取或写入到其他的frame页面。这个功能不但可以有效的利用通用的功能,更加可以维持数据到令一个框架窗口。
下面的框架页面只包含一个frame页面--query.htm,并声明了变量myword:
<HTML><HEAD>
<TITLE>Passing data</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
myWord="";
//--></SCRIPT>
</HEAD>
<FRAMESET rows="*,1" FRAMEBORDER=no>
<FRAME name="active" src="query.htm">
<FRAME name="dummy">
</FRAMESET>
</HTML>
页面query.htm有一个文本输入框和一个指向result.htm的链接。链接的鼠标点击事件将把输入的内容写入到父窗口的myWord变量中,就向这样:
<HTML><HEAD></HEAD>
<BODY>
<FORM name="myForm">
<INPUT type=text size=12 name="myText">
<P>
<AonClick="parent.myWord=myText.value"
href="result.htm">点击这里看你的输入文字用黄色字体显示在蓝色背景上</A>
</FORM>
</BODY></HTML>
新的页面--result.htm,刷新并写入query.htm中的myWord变量内容:
<HTML>
<HEAD></HEAD>
<BODY bgcolor=#0000cc vlink=#99ffff>
<FONT size=+3 color=#ffff00>
<SCRIPT language="JavaScript"><!--
document.write(parent.myWord);
//--></SCRIPT>
</FONT><P>
<A href="query.htm">重新再来一次</a>
</BODY></HTML>
这个简单的例子有着广泛的应用,你可以引导访问者按你设定的顺序浏览网页,你也可以根据客户输入的数据定制特别的页面。
在保存数据方面,这个方法并不能替代cookies或者CGI,因为当你一旦关闭或者刷新整个框架页面,数据将会丢失。这种方法的好处是不需要服务器特别权限的支持,也不会给安全上带来什么问题。
4.浮动Frame的脚本
支持浮动frame的浏览器同样支持在IFRAME中使用类似普通frame的脚本。唯一不同的地方是:普通无框架页面可以建立一个frames索引。浮动frame建立索引是根据HTML代码中的<IFRAME>顺序。类似普通frame,浮动frame中每一个元素都遵循窗口物件的特性。
在IFRAME中保证脚本安全执行,你必须确认窗口中的frames.length不为0。例如,在下面的例子中,链接的target是浮动frame,内容显示在<IFRAME>中,如果浮动frame不存在,则使用"_top"参数产生新窗口:
<IFRAME name="floater" src="trog.htm"
width=200 height=200></IFRAME>
<A href="grot.html" target="floater"
onClick="if (!self.frames.length)
this.target='_top'">See grot.htm</A>
一个含有浮动frame的页面就是这个frame的父窗口。所以多个浮动frame之间可以通过父窗口的parent.frames数组属性来访问。
5. 预防脚本出错
虽然HTML的frame有标准的规范说明,但是DOM(Documentation Object Model 参见http://www.w3.org/TR/REC-DOM-Level-1/)的第一级只将它定义为一个HTML元素,而不是一个窗口元素。有关frame的javascript行为(behavior)没有明确的定义,这个定义的缺乏将使得在读取frame框架的时候,脚本会发生冲突。
第一个矛盾就是页面的onload和onunload事件是和<BODY>标签相关联的,而<FRAMESET>页面却忽略了<BODY>标签。目前的做法是将这些事件放置在frame框架的最上面的窗口页面中,也就是第一个调入的页面。但有些3.0的浏览器不支持这样的做法。
在即时修改frame页面内容的时候,许多浏览器同样会发生脚本出错。出错的原因是:<FRAME>标签中定义了页面内容,而在后面的脚本中却要求读取或写入其他的东西,两者发生冲突。这些浏览器常常执行javascript脚本的命令,又继续读取最初设定的页面代码,从而产生javascript error信息。这些问题的解决方案是在你开始操作frame之前,确认所有frame页面读取完毕。这有一个好的办法:就是使你的frame初始页面尽量简单,并在读取完毕后报告。
例如:假设您有一个框架页面需要在读取完毕后执行goToIt()功能,将下面的javascript脚本放入最初frameset页面:
countDown=frames.length;
function soundOff() {
countDown--;
if (countDown==0) {
goToIt();
}
}
然后在每个子窗口的页面代码<BODY>标签里加入onLoad="parent.soundOff()",当所有frame页面都被读取并执行soundOff()功能后,countDown变量值为0,开始执行goTOIt()。