[返回]
软件世界1999年第9期

JavaScript中对象的层次结构

王 水

  JavaScript对象的层次结构,实际上就是html对象的层次结构的体现;其基本的对象继承关系如下:


  但是,由于不同的浏览器对JavaScript语句解释的不同,因此在具体的语法实现上也有差别。就流行的两种浏览器(IE和NE)相比较来说,Netscape要求有更加严格的层次语法,包括必须使用表单容器、不能省略对象层次描述等。

  以一个包含两个框架的页面为例,其主页面代码如下,注意通过name参数为框架命名,使得我们在后续的操作中可以通过名称引用对应的框架:

  〈html〉



  〈head〉

  〈meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80"〉

  〈title〉〈/title〉

  〈/head〉



  〈frameset id="mainframe" frameborder="0" rows="10%,90%"〉

  〈frame name="head" src="head.html" noresize scrolling="no"〉

  〈frame name="page" src="page.html" noresize scrolling="auto"〉

  〈noframes〉

  〈body bgcolor="#FFFFFF"〉

  〈h3〉This page needs frame-support! 〈/h3〉

  〈/body〉

  〈/noframes〉

  〈/frameset〉

  〈/html〉

  作为一个简单的例子,在head.html中只包含一个按钮控件showImg和一个隐含控件hparam,其中隐含控件在动态html设计中一般用于接收从上级程序中传递过来的参数。考虑到我们要为该"head"导航条加入JavaScript程序,在本页代码的后面加上对JavaScript文件的引用。代码如下:

  〈html〉



  〈head〉

  〈meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80"〉

  〈title〉〈/title〉

  〈/head〉



  〈body bgcolor="#FFFFFF"〉



  〈form name="myform"〉

   〈INPUT type="button" name="showImg" value="Show Image" onclick="doShowImg()"〉

   〈INPUT type="hidden" size="80" name="hparam" value="10"〉

  〈/form〉



  〈script language="JavaScript" src="myjs.js"〉

  〈/script〉

  〈/body〉

  〈/html〉



  在page.html中,放入一个图片对象:

  〈html〉



  〈head〉

  〈meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80"〉

  〈title〉〈/title〉

  〈/head〉



  〈body bgcolor="#FFFFFF"〉

  〈p〉〈img name="pageImg"〉 〈/p〉

  〈/body〉

  〈/html〉

  例如,为了在head中点击showImg时能够在doShowImg函数中设置page框架中的pageImg对象的src属性,从而使浏览器显示该图像,一种想当然的程序写法是,在myjs.js中加入如下事件函数::

  function doShowimg() {

page.pageImg.src = "file:///c:/windows/logo.gif";

  }

  然而,由于对JavaScript函数的引用在框架head中,因此,上述语法将试图在当前文档中查找page容器对象,并在其中定位pageImg对象,将该对象的src属性赋值为"file:///c:/windows/logo.gif"。

  但实际上,page对象并不在当前文档中,它是当前对象的父级窗口中的一个框架,而pageImg为该框架中文档(document)对象的一个成员,因此,正确的写法为:

  parent.page.document.pageImg.src = "file:///c:/windows/logo.gif";

  如果进一步,希望由隐含对象hparam的值设置图像的宽度,在IE中可以使用如下语法:

  parent.page.document.pageImg.width = document.myform.hparam.value;

  需要注意的是,hparam是名为myform的表单中的一个控件,该表单隶属于document文档对象。从这个语法上,我们可以看到IE和NE的不同:

  首先,NE不允许实时地对图片对象的尺寸作更改,上述语法的结果只是一条令人沮丧的警告信息:

  parent.page.document.pageImg.width is read-only.

  其次,IE允许你关于document文档对象作这样一个假设:(1)最底层的对象(在上例中是pageImg)可以默认是处于document容器对象中;(2)如果一个表达式中的顶级对象(例如上例中的myform)是document对象的子对象,也就是说,可将上面的赋值语句简化为:

  parent.page.pageImg.width = document.myform.hparam.value;

  也正因为如此,IE允许直接引用表单对象,也就是说,下列语法是正确的:

  parent.page.pageImg.width = myform.hparam.value;

  而以上语法在NE中是不允许的。

  第三,在IE中,还可以进一步简化:IE允许表单对象直接处于文档对象之下,也就是说,在html文档中,可以不使用〈form〉容器对象而直接使用按钮、菜单、文本框等表单对象。因此,如果在head.html中去掉对表单的定义:

  〈html〉



  〈head〉

  〈meta http-equiv="Content-Type" content="text/html; charset=gb_2312-80"〉

  〈title〉〈/title〉

  〈/head〉



  〈body bgcolor="#FFFFFF"〉



  〈INPUT type="button" name="showImg" value="Show Image" onclick="doShowImg()"〉

  〈INPUT type="hidden" size="80" name="hparam" value="10"〉



  〈script language="JavaScript" src="myjs.js"〉

  〈/script〉

  〈/body〉

  〈/html〉

  则可以使用如下语法(在IE中)为图像宽度属性赋值:

  parent.page.pageImg.width = hparam.value;

  而同样的页面在NE中,根本显示不出来按钮,而是将您的按钮文本罗列在页面上(更不用说响应事件了)!

  最后,我们看看,如何解决动态改变图片大小的方法:

  实际上,JavaScript的标准层次结构和语法格式,NE和IE都是同样支持的,因此,可以使用如下流程实现图片大小的改变:

  1. 清除page.html页面;

  2. 重新设置图片对象,使用新的尺寸值;

  3. 关闭页面(document对象),显示页面;

  代码简要如下:

  parent.page.document.clear();

  parent.page.document.write('〈img src="logo.gif" width=w1 height=h1');

  parent.page.document.close();