VS2005里Frameset的使用方法

----------------
二. 使用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()。
posted @ 2012-02-01 10:48  浅谈生活  阅读(672)  评论(0编辑  收藏  举报