今天我们将开始学习动态html最精彩的部分:动态html编程。htm之所以成功的原因之一在于它提供了在互联网上展现网页的统一方式。一旦你标识了一个网页,它在任何地方都可以看到。javascript也是如此。及时它的版本会有很多种,但它的核心和语法是统一的,它在支持javascript的所有浏览器中都可以应用。css也具有统一的语法。在所有的浏览器中它的显示结果也应该是一致的。所以它能帮助你生成跨平台风格一致的动态网页。
但是,还有一些小问题。
在1997中期时,netscape和microsoft都推出了自己的动态html浏览器,但那时没有一种规范编程语言同网页元素之间的交流的统一规定。但是在那时已经有了javascript同网页中的图象、链接和表单元素进行交流的规范。然而这两家公司对于如何控制网页元素存在不同的见解。
netscape对javascript加入了一系列的对象,并引入了<layer>标签,伴随产生的便是它的dhtml 理念:-或者采用<layer>标签分层的内容分层,或者<div>标签的css定位,它们可以用javascript的对象访问,而且它的属性(left, top, visibility,和background color)可以被控制。
但是微软走得更深入一些。它推出了全新的html生成引擎,它不仅能定位任何元素,还能改变对css设置的任何选项。(例如,你可以改变字体或你的em标签) ,而且,它还完善了文件对象模块(document object model),使其能通过任何ie支持的编程或脚本语言访问。 这两种体制之间的明显区别在于其语法。netscape 支持树
形语法:
document.layers[toplayer].document.layers[sublayer].document.layers[bottom].left
而internet explorer将所有的html对象都放在一个水平结构上,使你可以修改也是对象:
bottom.style.left
如果你在这种浏览器中使用了另一种浏览器支持的方法,则浏览器会显示错误信息。但是还有许多技术可以对这种不兼容性作出变通处理。一旦你掌握了其中的诀窍,你就可以左右逢源,无所不能。本课中将学习如何利用最少量的条件访问文件对象模块dom,然后我们将介绍一个将对象在屏幕中移动的简单javascript脚本。
首先我们学习为两种浏览器生成不同的动态html。我不打算在此列出两种浏览器各自的动态html特点,我只列出两种浏览器所支持的相同的动态html功能。
你可以看到它们之间没有完全相同的项目。object.name似乎相同,但是对对象使用css时必须制定id属性,所以你只能对图象、链接和表单 使用该功能。所以为了编写脚本,你必须设定很多条件。听起来很痛苦,但其实还不象你想象的那么糟。
有很多中办法可以利用javascript设定条件。其中办法是确定用户所使用的浏览器的类型和版本,并据此作出评估。现在我还发现了更好的解决办法。
浏览器类型和版本条件设定的第1个问题是浏览器的改变的问题。如果你将浏览器版本设定为internet explorer 4.0和netscape 4.0,那么等5.0版的浏览器发布时你的网页会发生什么情况?或者这两种新发布的浏览器版本互相兼容,而你的脚本中都没有考虑到这些问题又会如何? 所以根据浏览器类型和版本设定条件的方法不可行。
更好的方法是根据功能设定条件。如果你读过javascript教程 ,你一定知道javascript的”if”语句中测试一个语句返回的是真true (1)还是假false (0),然后它将根据返回的布尔值执行一个语句。通常情况下它被用来测试某些变量的条件,例如:
if (x<=5) settimeout(dosomething(), 500);
但是一个对象是否存在也可以作为被测试的条件。如果某个对象存在,则返回真,否则返回假。所以为了提供一个有效的测试条件,你必须从某个特定角度来测试一个对象的代表性质以便应用动态hmtl。
netscape利用分层运行动态html。它的运行方式同图象数组在navigator中的方式类似。你设定一个分层对象的数组,象对图象的引用那样设定引用方式。所以document.layers[foobar] 则是代表被相对定位或是绝对定位了的<div>的对象 (在netscape 模式中,它必须是在你的文件name或id属性为”foobar”的一个绝对定位或相对定位了的<div>或<span>)。然后你就可以设定上述各种属性。你还可以用document.foobar来代表这个对象。
在internet explorer中,则用一种水平的结构来代表对象。所以id或name属性为foobar的<div>就是foobar,所以你可以用foobar.style.left来访问或设定这个对象的左边的位置。还有许多种循环访问一系列对象的方法(非常有用)。在explorer的文件对象模块(document object model)中,对象可以代表所有在该对象之下的对象(object object object)。所以foobar.all 包含所有包含在foobar之下的html标签。无论什么时候你都可以找到一个很好的类属对象-document.all,因为所有的网页中都有一个文件(document),因此它必然有一个document.all对象。
所以如果你想控制某个对象的位置,你应该这样编写你的javascript:
<script language=”javascript”>
function moveit() {
if(document.layers) {
document.truck.left -= 5;
if (document.truck.left<0){
document.truck.left=480}
}
else if (document.all) {
truck.style.left=”parseint(truck.style.left)” 5;
if (parseint(truck.style.left)<0)
{ truck.style.left=”480;” } }
if ((document.layers) || (document.all))
{ settimeout(moveit(), 100); } } </script>
它的执行结果应该是:
代码的含义如下:
如果客户端支持document.layers对象,
将名为truck的对象层左移5个位置.
如果名为truck的对象层的位置小于0,
则名为truck的对象层的的left属性设置
为480。
但是,如果客户端支持document.all对象,
则将名为truck的html对象的样式选项left的整
数值减去5。
如果名为truck的html对象的样式选项left的整
数值小于0,则将其数值设为480。
如果客户端支持document.all或document.layers对象
中的任何一种,
等候10秒钟,然后执行函数moveit。
现在你自己作一下这个程序。让拖拉机在页面中移动。注意:你应该采用行内样式,例:<div id=”truck”
style=”position: absolute; left: 20; top: 20″>。
现在你已经可以在页面中移动对象了。 但是如果你需要将多个对象按照特定的顺序移动或者执行多个事件触发的行为时,不仅的代码体积会增加(每次访问一个对象时你都必须使用一次if/then 语句),而且每次都必须为某个行为键入document.truck.left 是一件很烦人的事。在netscape模块中,当你嵌入div时,文件对象模块的层次结构就会增加,如下:
<div id=”foo”>
<div id=”bar”>
<div id=”sna”>
</div>
</div>
</div>
要访问foo,则必须执行document.foo, 而要访问bar,则必须执行document.foo.document.bar。而要访问sna,则必须执行document.foo.document.bar.document.sna。
我快要受不了啦啦啦!!!
所以你必须解决引用对象时造成的代码体积膨胀的问题,还得避免每次移动一个对象时必须设定条件。但你可以用一个技巧解决这个问题。
任何用javascript编写过网页的人都知道任何打开一个小窗口:
windowid = window.open(name, http://blah.com/');
这项指令就可打开一个小窗口,但是你还可以通过使用windowid 作一个引用在继续控制追赶窗口。例如windowid.location = http://www.taylor.org/就可以改变窗口资源的定位。”windowid.close()”就可关闭该窗口。你所做的只是对一个javascript对象设置一个引用。在动态html中也可以使用同样的技巧。
你可能会注意到在上一页的图表中,大多数定位属性的语法都很相似。只不过它们被用在了不同的对象上。我们可以用一个javascript例程解决上面的问题。
<script>
function setup(){
if(document.layers){
datruck = document.truck;
} else if(document.all) {
datruck = truck.style;
}
}
</script>
现在moveit函数可以被改为
function moveit() {
datruck.left = parseint(datruck.left) – 5;
if(parseint(datruck.left) < 0){
datruck.left = 480;
}
settimeout(moveit(), 100);
}
代码短了一些,对吧?下面我们将使页面这些图象都动起来。
现在你所能控制的属性已经不只是left和top了,当然,还 有z-index。现在我们制作网猴们互相追赶的效果。
function movemonkey(monkey, dir) {
if (document.all) {
var wtmonkey = document.all(monkey).style;
} else if (document.layers) {
var wtmonkey = document.monkeycontainer.document.layers[monkey];
}
if ((parseint(wtmonkey.left) <0) || (parseint(wtmonkey.left)> 150)) {
dir = dir * -1;
wtmonkey.zindex = 5 – dir;
}
wtmonkey.left = parseint(wtmonkey.left) + dir;
settimeout(movemonkey(\ + monkey + \, + dir +), 100);
}
网猴的名字被传递给函数,函数则改变网猴的左边的定位。然后进行标准的功能检查,为特定的浏览器设定引用参数。然后它改变z-index,如果网猴移动到了桌子的任何一端,则函数改变网猴移动的方向。
注意这不是编制类属javascript移动例程的唯一方法。你可以随意添加、减少或编写自己的例程。下面是今天的家庭作业。将作出动画效果。你可以使用上面所提供的代码或者编写你自己的代码。当你编写例程时注意netscape嵌入定位对象的方法。