本文介绍了IE和Navigator两种浏览器对DHTML标准实现的差异,特别是如何编写Navigator中运行的DHTML程序。
DHTML(Dynamic HTML)是W3C组织提出的一种新的规范,它对原有的HTML做了许多扩充,并结合Javascript,使得静态的HTML页面产生了许多动态效果,例如菜单的展开和收起,页面元素的外观动态改变等。IE 4.0以上,Navigator 4.0以上的版本都支持这个标准。但是,不同的浏览器厂家对它都做了不同程度的扩充。以最流行IE的和NS为例,IE的实现更接近于W3C的方案,而NS,说实话,与W3C的方案差异很大,而且并没有完全实现,甚至可以说是另一套方案。笔者在初识DHTML时,按照书上讲的编写了几个小程序,在IE上一试就通,而在NS上可以说费尽了周折才逐渐找到解决方案。由于市面上很少有讲述NS的DHTML实现方案的书(大概NS由于的实现不符合标准),而真正的商业网站至少应同时支持IE和NS这两种主要的浏览器,我愿意把我的一些心得写出来与大家共享,使大家不必再走我走过的弯路。对于二者的实现相同的部分,本文作一简略介绍,您若有兴趣可参考有关书籍或网上资源。
DHTML实际上由三两部分组成:CSS(Cascade Style Sheet,级联样式表),层(Layer)和Javascript。
所谓CSS,概念上类似于C++中的类,在类定义中指明元素的外观样式,如字体,颜色,大小等等,页面中的任何一个HTML元素如被指定属于这个类,就自动拥有该类的特性;还可以为某种HTML元素定义样式,这样页面中的所有这种元素都有了同样的外观。如果将这样的样式定义存在一个单独的.css文件中(就象C++那样将类定义存在 .h文件中),再在页面中将其包含进来,则一个网站的所有页面就有了同样的外观。IE和NS对CSS的实现基本相同,在此就不再详细介绍了。
两者的差异主要体现在层的实现上。所谓层,就是页面上的一块区域,其中可以包含任何的HTML元素,通过改变层的属性,其间的元素可以跟着出现,消失,更改,移动等。 在IE中,层依靠<DIV></DIV>和<SPAN></SPAN>来实现,两者基本相同,通常<DIV>用于较大的层,<SPAN>用于较小的层,并且<DIV>在实现的层后面加上一个回车换行,而<SPAN>不加。它的语法如下(二者相同):
<div id=layername style="style definition">Layer content</div> 或
<div id=layername class="classname">Layer content</div>
其中style definition是一组有分号隔开的样式定义,常用的有以下几种:
position:其值可以为absolute和relative,所谓absolute(绝对定位),就是层的内容不必按照出现的先后次序在浏览器上依次排列,而是可以像素为单位定位到浏览器用户区域的任意位置;而relative(相对定位)则是层按照相邻的内容依次排列。
left,top,width,height:指层的左上角坐标以及它的宽度和高度。
z-index:由于层可以被放置在页面的任何位置,当它与其它内容重合时,z-index值大的显示在上面,所有层的z-index值为1。但是在NS中,所有的表单元素(文本框,列表框,按钮等),只要是可见的就无法被遮住,而无论z-index值是多少。因此在设计页面时,要注意不要使动态出现或隐藏的元素(例如弹出式菜单)的位置上放置表单元素。
Visibility:指明层是否可见,通过在程序中动态改变这个值,可以实现层的出现和消失,比如下拉菜单就要依靠它来实现。它的三个候选值为:inherit,可见性与父元素的可见性相同;visible,可见(在NS中是show);hidden,不可见(在NS中是hide)。
NS同样支持这两个标记,但是支持得很不好,经常出现一些莫名其妙的错误,我想这可能是出于策略上的考虑,而不见得是NS的产品质量不好。NS引入了另两个标记,<layer>和<ilayer>,<layer>用于绝对定位,<ilayer>用于相对定位,因此在这两个标记的样式定义中没有position属性。
两个浏览器对层的不同实现体现在以下几点:
1. 层的引用。在IE中,页面上的每个可编程元素(不仅是层,还包括其它任何指明了ID值的元素,详见下文)都是document.all集合的一项;而在NS中,页面中每个层,无论是用上面四个标记中的哪个定义的,也无论是绝对或是相对定位,都是document.layers集合的一项。因此,若想引用名为layer1的层,应以如下语法:
IE:document.all["layer1"]或document.all.layer1
NS:document.layers["layer1"]或document.layers.layer1
2. 层的坐标和大小。在IE中,每个涉及层的外观的属性,如位置,大小,颜色等,都是层的style属性集合的以一项,如层的左上角x坐标为document.all.layer1.style.pixelLeft,y坐标为 document.all.layer1.style.pixelTop,宽度为document.all.layer1.style.pixelWidth,高度为document.all.layer1.style.pixelHeight。还有几组属性如scrollxxx,offsetxxx,clientxxx,其中xxx为Left,Top,Width,Height ,分别描述层的滚动,位移,客户区等属性,详见MSDN中关于坐标的描述。而在NS中,每个层都有一个clip属性集,x,y,width,height是这个集的集合元素。
另外,IE中所有元素拥有同一个坐标系,无论它位于层外或层内;在NS中,每个层都有一个独立的坐标系。
3. 层的内容。IE中的层包含innerHTML和outerHTML属性(由于并非描述层的外观,所以它们不是style属性集的元素,而是层的属性),其含义如下:
innerHTML:层中的HTML代码,但是不包括层的定义。
outerHTML:层中的HTML代码,且包括层的定义。
改变这些属性值就可以改变层的内容,如下语句改变层layer1的内容为加粗的字符串"layer1":document.all.layer1.innerHTML=”<b>layer1</b>” ,而在NS中,每一个document.layers集合中的元素,即一个层,都NS被视为一个独立的窗口,有独立document属性,就象Javascript中的document属性一样,通过调用document.write函数,可以动态改变层的内容。上例在NS中应修改为:
document.layers.layer1.document.open();
doucment.layers.layer1.write("<div><b>layer1</b></div>");
document.layers.layer1.document.close;
同样,对于层中的其它可编程元素,例如图象,其引用语法如下:document.layers.layer1.document.images[imgname],而如果该图象位于层的外面,其语法应为document.images[imgname],而在IE中,无论图象位于层内或层外,其语法都是后者。
Javascript是Netscape公司首先提出的一种客户端编程的脚本语言,随后有扩展到服务器端。它的语法和概念都类似于C++,但是没有C++那样严格。IE同样支持客户端Javascript(微软还推出了类似的,功能更强大的Vbscript,但是NS却不支持)。两种浏览器对Javascript的基本实现是一样的,但是又都对它做了许多不同的扩展,而在DHTML编程中,很多情况下都需要用到这些扩展。由于此时已经没有标准可遵循,二者已经看不出有相同之处。例如,浏览器的客户区的宽度,在IE中是document.body.clientWidth,在NS中是window.innerWidth;再比如你想知道用户按浏览器的滚动条滚动了多少像素,在IE中是