您的位置:首页 > Web前端 > JavaScript

JavaScript 学习笔记(二)

2006-01-20 10:27 393 查看

JavaScript 学习笔记(二)

彭建军
2005-01-18
根据网上收集的文章整理

创建新的 window (窗口) 对象

你有时需要打开一个新的浏览器窗口,用来显示信息或广告,但是在这里我要提醒你一下,大部分人在浏览一个网站的时候,是不会注意弹处的新窗口里边写些什么,他们会很快地关掉窗口,只有少数的人会留意这些弹出的窗口。然而,这项技术还是很不错的。

弹出窗口的小测试
在这个 在线示例 中,我们给出一个小测试问题的列表,对应于每一个问题都一个显示答案的超链接,而这些超链接将会弹出一个小窗口来显示答案,看一看代码就清楚了。

实际上,每一个答案的超链接都调用了同一个函数 showAnswer(),通过传递的参数 url (此参数是答案所在的页面的地址 URL) 的不同,在弹出的小窗口中显示不同的页面;在这个函数中使用了 window.open() 方法来创建新的窗口:

function showAnswer(url) {
window.open(url, "answer", "height=100,width=100,directories=no," +
"location=no,menubar=no," +
"resizeable=no,status=no,toolbar=no");
return false;
}

open() 方法有三个参数:打开窗口中的页面地址 URL (包括路径和文件名),给新窗口取的一个英文名字,打开的窗口的一些属性设置 (如窗口的高度、宽度、是否显示滚动条、是否显示浏览器的菜单栏等等)。

新窗口的名字在某些时候可能会用到,在别的窗口中使用 TARGET="新窗口的名字" 使超链接所链接的页面在新窗口中显示,描述窗口特性的参数是一个包含关键字和关键字值的字符串,各个关键字之间使用英文逗号 (,) 隔开,使用这个参数的时候一定要小心,各个关键字、关键字值、逗号之间千万不要有空格。

注意:此例中的 “+” 好只是为了代码能够换行书写才加上的,其实它们只是连结字符串而已,没有别的,不使用 “+” 好一样是可以的。

窗口特性 (即是打开的浏览器的样子) 的关键字、关键字值可以参考下表:

是否显示工具栏:toolbar[=yes|no]|[=1|0]
是否显示地址栏:location[=yes|no]|[=1|0]
是否显示前进、后退、刷新按钮:directories[=yes|no]|[=1|0]
是否显示状态栏:status[=yes|no]|[=1|0]
是否显示菜单栏:menubar[=yes|no]|[=1|0]
是否显示滚动条:scrollbars[=yes|no]|[=1|0]
用户是否可以改变窗口的大小:resizable[=yes|no]|[=1|0]
是否在新窗口中保留浏览器的浏览历史纪录:copyhistory[=yes|no]|[=1|0]
窗口的宽度 (单位为像素):width=pixels
窗口的高度 (单位为像素):height=pixels
如果在字符串中给定了这些值的话,窗口就会按你定义的现实,否则将会使用默认的值,想要进一步了解这方面的信息请参考 Netscape's JavaScript Guide !

给窗口指定页面

当你使用上面的方法创建了一个新窗口之后,你还可以再次给这个窗口指定新的页面,这就要用到 open() 方法的返回值了,请看下边的代码:

myWin = window.open(url, "", "height=100,width=100");
...
myWin.location = "newpage.html";

上边的代码将打开的新窗口的页面重新指定为 newpage.html,这样窗口中就会显示页面 newpage.html 了。同时,在打开的新窗口中,你也可以通过使用 window 对象的 opener 属性将窗口对象指向打开此窗口的母窗口,这样也就可以对母窗口的数据或函数进行操作了,例如下边的代码中就是将母窗口的页面重新指定为 newpage.html:

window.opener.location = "newpage.html";

关闭一个窗口

再让我们看一下前边的 在线示例 中我们所打开的新窗口,你会窗口中没有菜单栏,那我们该如何将此窗口关掉呢?不用担心,我们可以使用 window 对象的 close() 方法来关闭打开的小窗口,那个 “关闭窗口!” 按钮中就是使用了此方法:

<form>
<input type=submit value="关闭此窗口" onClick="window.close(); return false;">
</form>

当你按下按钮后,就会触发 onClick 事件,从而调用 window 对象的 close() 方法,此方法将当前的窗口关闭掉。

处理 frame [帧] 对象

正如我们在前边的章节中提到的那样,frame 帧其实是单独的窗口,它对应于单独的窗口对象,有自己的 location、history 和 document 属性。

在这个 在线示例 中你将会看到一系列的帧,代码如下:

<html>
<head>
<title></title>
</head>

<frameset rows="300,*">
<frame name="a" src="example3-2a.html">
<frameset cols="33%,33%,33%">
<frame name="b" src="example3-2b.html">
<frame name="c" src="example3-2c.html">
<frame name="d" src="example3-2d.html">
</frameset>
</frameset>

</html>

至于帧的结构、帧是如何分布的等等问题这里就不多讲了,我们希望你能查看一下例子中的源代码,你会发现帧 A 中有一个名为 setFrameColor() 的函数,它的作用是用来改变帧 B、帧 C、帧 D 的背景色,参数 fname 为目标帧的名字,参数 color 为目的背景颜色:

function setFrameColor(fname, color) {

window.parent.frames[fname].document.bgColor = color;
return false;
}

正如前边例中所演示的那样,B、C、D 帧的背景颜色确确实实被 document.bgColor 改变了,这里头最重要的是对帧对象的指定,这也是 window.parent.frames[fname] 的作用了,如果参数 fname 的值为 B,则改变帧 B 的颜色。

我们通过当前帧 (帧 A) 的 window.parent 属性指定到顶部的帧 (frameset,此帧包含了A、B、C、D四个帧) ,然后通过顶部帧的 frames 数组加上帧的名字 fname 指定目标帧 (帧 B、C、D),最后通过目标帧的 document.bgColor 属性改变该帧的背景色。

引用别的帧/窗口的变量和函数

你不只是可以引用别的帧/窗口的 document、window 对象,而且还可以访问使用别的帧/窗口的变量和函数。

现在我们将上边的例子修改一下,请看 在线示例 。在新的例子中,我们给下边的三个帧都加了一个按钮,用来恢复各个帧的默认背景色,按下这些按钮后,将会调用帧 A 中的函数 setFrameColor()。下边就是调用帧 A 中 setFrameColor() 函数的代码:

window.parent.frames["A"].setFrameColor(window.name, "#ffffff");

正如你所看到的,我们使用了与前边一样的技巧。首先使用 window.parent 指向顶层的帧 (frameset),然后使用 frames["A"] 指向帧 A,然后在后边加上帧 A 中的函数 setFrameColor(),并且加上两个参数,这样就可以运行帧 A 中的函数了。

需要注意的是函数 setFrameColor() 中使用的类似 window.name 的语句,这个名字和 frames[] 数组中使用的是相同的名字,同时这个名字还是 <FRAME> 标记中通过 NAME="帧的英文名" 设置的名字。

类似地,你也可以使用相同的方法使用别的窗口/帧里边的全局变量,只需要将上边例中的函数名改成全局变量名即可。

window 对象的 location 和 history 属性

window 对象的 location 属性包含了当前页面的地址 (URL) 信息,你可以直接改变此属性值,将其设置成新的地址 (URL):

window.location = "http://www.yahoo.com";;;
或者
location = "http://www.yahoo.com";;;

你还可以通过下边的两种方法中的任何一种来使浏览器从服务器上下载 (Load) 页面:

reload() - 促使浏览器重新下载当前的页面,也就是“刷新”当前页面了。
replace(URL) - 促使浏览器根据 URL 参数中给出的地址 (URL) 下载页面,同时在当前浏览器存储的历史记录 (即所浏览过的页面的列表) 中使用新的地址(即此方法中的 URL 参数) 覆盖当前的页面。
使用 replace() 方法意味着用户将不能通过按 “返回” 按钮回到前边浏览过的那个页面,但这并不是说用户完全不能回到原来的所有页面,他们只不过是无法回到被 replace() 方法替换的那一个页面 (注意:只是被替换的那一个页面)。

表面上看起来这种方法并不是很有用,而且好像还有点令人讨厌,但是,在一些特殊的情况下这种方法却是很有用的。看看这个 在线示例 就知道了,此例中使用 setTimeout() 方法每个三秒钟就下载一个新的页面,让程序运行一段时间,然后点击浏览器的 “后退” 按钮,你会看到浏览器的历史记录,好多好多,你再试着通过鼠标点击回到开始的页面,怎么样,回去了吗?好像比较麻烦,因为有一大堆的页面在那里挡着。

想要解决这个问题可以使用 replace() 方法,看一下这个改进后的 在线示例 就知道了,新的例子中,你只需点击一次 “后退” 按钮即可以回到最初的页面了。

history 对象

history 对象是一个很有用的对象,此对象记录着浏览器所浏览过的每一个页面,这些页面组成了一个历史记录列表。history 对象具有两种方法:

forward() - 将历史记录向前移动一个页面;
back() - 将历史记录向后移动一个页面;
而还有一个 go() 方法也可以控制历史纪录,而且功能更加强大,使用此方法需要一个参数,这个参数值可以是正负整数、零和字符串,例如 history.go(-2) 将是当前页后退两页;如果给定的参数是字符串,那么浏览器就会搜索列表,找到最接近当前页面位置的并且地址 URL 中含有此字符串的页面,然后转到该页面。

请看,下边的两条语句是等价的:

history.go(-1);
history.back();

下边的代码将页面转到距离本页面位置最近的同时页面地址 URL 中含有字符串 "netscape" (不区分字母的大小写) 的页面:

history.go("netscape");

在使用这三个方法的时候,如果没有找到符合条件的历史记录的话,将不会发生任何变化,不会改变当前的页面,也不会显示错误。

小技巧:如果在你的网站中有很多页面,那么提供一个 “返回” 功能是很必要的,这样可以方便用户浏览你的网站,但是你并不知道用户是从哪一个页面来到当前页面的,于是你就不能使用 <A HREF="页面的地址">...</A> 的方式来做超链接了,但是可以使用下边的代码来做 “返回” 的超链接:

<a href="#" onClick="history.back(); return false;">返回</a>

改变窗口页面的内容

你可以使用 window 对象的 scroll() 方法使窗口/帧的内容滚动,这种滚动可以是水平方向的也可以是垂直方向的,在这个 在线示例 中,帧里边的美国各个城市天气变化的内容将会不停的滚动。

此例中,当页面滚动到一定的值 (此例中为 750 像素) 的时候,又将页面重新设置成最初的样子 (即坐标值为:(0,0)),这样看起来就是不停的滚动了。可惜的是,并不是所有的浏览器都提供实际的页面高和宽的像素值,所以你要亲自实践一下看看这些值要多大才合适。

你还可以重新书写一个页面中的内容,这就要用到 document 对象的 write() (此方法输出的时候不换行) 和 writeln() (此方法输出完成后自动换行)方法了。这两个方法需要一个字符串参数,这个参数就是要在页面中输出的字符串,可以在字符串中带上HTML代码,那样输出的结果就和其它网页是一样的了,看看这个 在线示例 ,查看一下源代码就知道了。这个例子中是上边的帧通过 writeln() 方法向下边的帧输出内容。

在此例中,你可以试一试输入一些 HTML 代码,看看有什么效果!比如说输入下边的代码:

<script>
alert("Hi mom!");
</script>

在下边帧上,点击鼠标右键,查看一下源代码,你会发现源代码就是你输入的那些字符。

在函数 rewriteFrame() 中,有如下语句:

window.parent.frames["text"].document.writeln(document.forms[0].text.value);
window.parent.frames["text"].document.close();

第一条语句是将表单 (form) 的 text 中输入的内容写到下边的帧中,第二行代码是调用 document.close() 的方法告诉浏览器向页面写的操作已经结束。如果你想要是你的输入覆盖掉以前的,那就要使用 document 对象的 close() 方法。

一个小小的改进

你可能会注意到上边的例子中,当你点击浏览器的后退按钮的时候,你会看到你的每一次 “提交” 动作都产生了一个新的页面,他们都留在了历史记录中,所以像前边说的一样,你要按很多此 “后退” 才能会回到最初的页面,如果你想除掉这种情况,可以使用 document 对象的 open() 方法,只要在 rewriteFrame() 中加一条语句即可:

window.parent.frames["text"].document.open("text/html", "replace");
window.parent.frames["text"].document.writeln(document.forms[0].text.value);
window.parent.frames["text"].document.close();

open() 方法的第一个参数值 "text/html" 是用来告诉浏览器准备接受 HTML 数据,而第二个参数值 "replace" 告诉浏览器不要将新写入的页面加入到浏览器的历史记录列表中,和 location.replace(URL) 是很相似的,功能是一样的。

4、JavaScript关于表单

form 对象

在我们使用单独的表单 form 对象之前,首先要引用 form 对象。正如我们在第二部分所讲的那样,form 对象由网页中的 <FORM></FORM> 标记对创建,相似的,form 里边的元素也是由 <INPUT> 等标记创建的,他们被存放在数组 elements 中。

在前边我们已经讲过了如何使用 elements 数组了。例如,在一个页面中有两个 form 对象:

<html>
<head>
<title></title>
</head>
<body>

<form name="customerinfo" action="/cgi-bin/customer.cgi" method="post">
Name: <input name="customername" type="text"><br>
Address: <input name="address" type="text"><br>
<input type="submit" value="Update"><input type="reset" value="Clear">
</form>

<form name="orderdata" action="/cgi-bin/order.cgi" method="post">
Item Number: <input name="itemnumber" type="text"><br>
Quantity: <input name="quantity" type="text"><br>
<input type="submit" value="Update"><input type="reset" value="Clear">
</form>

</body>
</html>

要使用名为 'quantity' 的元素,可以使用下边三种方法中的任何一种:

var e = document.forms["orderdata"].elements[1];
var e = document.forms.orderdata.elements["quantity"];
var e = document.orderdata.quantity;

每一种元素类型 (type) 多对应每一种不同的对象,这些对象有一些共同的属性和方法,如:value 属性和 focus() 方法,此外,它们还有自己独特的属性和方法,下边我们将会按顺序对每一种元素类型进行讲解。

你可以通过元素的 type 属性知道元素是什么类型,在上边的例子中,我们可以使用下边的代码来获得名为 'quantity' 的元素的类型:

document.orderdata.quantity.type

结果将会返回 'text'。

处理一个表单 form

通常一个 <FORM> 标记中含有 ACTION="...." 的语句,这个语句是用来指定一个表单提交后的服务器端处理文件的文件名 (包括路径,即整个URL),在的一部分中,我们曾经使用过 onSubmit 事件来判断用户的输入是否正确,如果正确就将这些信息提交到服务器进行处理,而服务器上用来处理这些信息的程序所在的文件就是通过 ACTION="..." 来指定的。

如果你想要通过 form 的元素来获得用户的输入,而不在服务器上处理,那就不要在 <FORM> 标记中加入 ACTION="...." 和 METHOD="....",就像我们在在线示例中使用的“查看源代码!”的按钮,这个按钮就是在客户端而不是服务器端运行了一些代码来查看源文件。

form 对象各元素类型

button 按钮对象

按钮有三种类型,一般的按钮 (button),“提交” (submit) 按钮和 “重置” (reset) 按钮,它们有共同的属性和方法,也有各自不同的属性和方法。这三种按钮可以在 <INPUT> 标记中通过 TYPE="...." 来创建,例如:

<input type="submit" value="Submit">
<input type="reset" value="Clear">
<input type="button" value="Cancel" onClick="cancel();">

它们三个的不同之处在于,submit 提交按钮有个默认动作是点击此类按钮以后自动提交表单的内容;reset 重置按钮的默认动作是点击此类按钮以后自动将表单的内容恢复到最初的状态;而对于一般的 button 按钮来说,则没有默认动作,需要通过使用 onClick 事件句柄,在此事件触发时调用函数才行。

你也可以通过使用 onClick 事件句柄来改变 submit 和 reset 按钮的默认动作。这个 在线示例 中就使用了这三种不同的按钮来完成计算功能。

技巧1:在此例中我们使用了 JavaScript 的内建函数 parseInt(),此函数将文本框里的字符串对象转换成数值对象。否则字符 "2" 和字符 "2" 进行 "+" 运算的结果是 "22",而不是 4。

技巧2:reset 按钮有默认动作,那就是将表单中所有的内容恢复到最初的状态,如果想改变其默认动作,可以像这个 在线示例 那样。

text (文本框)、password (密码输入框)、hidden (隐藏域) 和 textarea (多行文本框) 对象

这几个对象都很相似,输入的都是字符串,它们仅仅是显示的方式不一样而已:

text - 一个单行的文本输入框
password - 一个单行的密码输入框,输入的字符将不会显示出来,显示出来的只是 '*' 号
hidden - 一个单行的文本域,但是它不会在页面上显示任何东西,而且使用网页的用户不能直接修改它的值,但是你却可以通过代码修改它的值
textarea - 多行的文本输入框,可以在框中使用 “回车” 换行
技巧:hidden 域是一个很有用的对象,它可以将一些不想在页面上显示的信息传给服务器,但是,虽然这些信息不会显示在页面上,你还是不能将重要的信息,如密码等信息放到此域中,因为用户在客户端是可以通过查看源文件知道这些信息的。

text 和 textarea 元素提供了 onChange 事件,当这些输入框的内容发生变化时就会触发此事件。看看这个 在线示例 就知道了。你会注意到 onChange 事件只是发生在用户离开输入框 (使用了 TAB 键或鼠标焦点离开) 或者按了 “回车” 键的时候发生。

你只有确实地改变了文本框中的内容才会触发此事件。如果你将输入的内容清楚,然后输入完全相同的内容,将不会触发 onChange 事件。

checkbox (复选框) 和 radio (单选框) 按钮对象

checkbox 和 radio 按钮可以为用户提供一序列选项,checkbox 用于可以多选的选项中,而 radio 用于只能单选的选项中。

checkbox 对象通过 value="...." 来设置值,但表单提交之后,服务器接收到的只是选中的项的值,此对象有一个 checked 的属性,此属性用来判断每一个复选框的状态,即选中还是没选中,例如:<INPUT TYPE="checkbox" checked> 表示此复选框被选中;而 <INPUT TYPE="checkbox"> 表示此复选框没有被选中。

你可以通过 JavaScript 代码修改、设置 checkbox 的 checked 属性,就像这个 在线示例 中的那样,将 checkbox 的 checked=false 则不选中该复选框,checked=true 则相反。

单选框 radio 按钮与 checkbox 不同,它是在一序列选项中只能选一个,例如,我们对来访用户的年龄进行调查,看他们属于哪一个年龄段,则可以使用下边的代码:

<input name="agegroup" type="radio" value="under 21">21岁以下<br>
<input name="agegroup" type="radio" value="21 to 35">21岁到35岁<br>
<input name="agegroup" type="radio" value="36 to 45">36岁到45岁<br>
<input name="agegroup" type="radio" value="46 to 65">46岁到65岁<br>
<input name="agegroup" type="radio" value="over 65">65岁以上

我们注意到这些选项对应的 radio 按钮对象有一个相同的对象名 'agegroup',这是说明这些按钮都是在一个组里的,在这个组里,任何时候都只能有其中的一项 (不可能有两个或两个以上) 被选中,当表单被提交到服务器的时候,服务器接收到的值就是选中的那一项。同时,agegroup 对象的值也是选中的那一项的 value 属性的值。

一个组中的每一个 radio 按钮都代表一个 radio 对象,和 checkbox 类似,每一个都有 checked 和 value 属性,此属性对应于 HTML 标记中的 value="...." 代码,和 checkbox 所不同的是当组里的一个 radio 按钮被选中时,则其它 radio 按钮将不会被选中。

现在问题来了:在一组 radio 按钮中,如何去访问其中的任何一个 radio 按钮?使用 radio 按钮组的名字 (如上边的 agegroup) 是不行的,它的值只是选中的按钮的值,那你要访问其它没有被选中的值该怎么办呢?看看下边的代码就知道了:

var rb;

for (i = 0; i < document.forms["myform"].agegroup.length; i++) {
rb = document.forms["myform"].agegroup[i];
if (rb.checked) {
...
}
}

R原来使用组的名字 (如 agegroup) 作为数组,然后给数组加上下标即可 (如 agegroup[0] 是访问 agegroup 组中的第一个 radio 按钮)。另外要记住的是在这个数组中,只有一个元素的 checked 属性值是 true,因为任何时候都只有一个 radio 按钮被选中。请看 在线示例 。

select 和 option 对象

使用 select 选项列表 (即是通常的下拉列表框之类的) 也是一种给用户提供选项的有用方法,看一下下边的代码:

<select name="state" size=1>
<option value="AL">Alabama
<option value="AK">Alaska
<option value="AZ">Arizona
<option value="AR">Arkansas
<option value="CA">California
<option value="CO">Colorado
<option value="CT">Connecticut
<option value="DE">Delaware
<option value="DC">District of Columbia
...
<option value="WY">Wyoming
</select>

一个 select 对象是由 <SELECT> 标记创建的。此对象的 options 属性是一个对应于 option 对象群的数组,每一个 <OPTION> 标记对应一个 option 对象,也就是对应一个 select 对象的选项。

注意:IE 3.0 不支持 select 和 option 对象。

select 对象的另外两个常用的属性是 length 和 selectedIndex 属性。length 属性是选项的个数,也就是 options 数组的元素个数;selectedIndex 属性则给出了被用户选中的那个选项在 options 数组中的下标。

下边的代码中,变量 i 是当前用户选中的那个选项在 options 中的下标,而第二行语句通过变量 options[i] 使得变量 s 指向被选中的选项对应的那个 option 对象:

var i = document.forms["myForm"].state.selectedIndex;
var s = document.forms["myForm"].state.options[i];

不过上边的代码只是对于 select 对象为单选的情况下有用,当你在 <SELECT> 标记中加入 MULTIPLE 属性后,用户就可以选择多个选项了,在这种情况下,selectedIndex 属性只是指向第一个被选中的项。

为了处理多选的情况,你可以使用 option 对象的 selected 属性通过循环检测每一个 option 对象,就像这个 在线示例 演示的那样,查看一下源代码就知道它是如何实现的了。

创建和删除 option 对象

注意:IE 4.0 对选择列表 selection 和 option 的方法不同于 Netscape,这一部分内容只能运用在 Netscape 3.0 或者更高版本。

你还可以通过代码创建和删除选项 option 对象。创建 option 对象使用 Option 数据结构,例如:

var opt = new Option(text, value, defaultSelected, selected)

参数 text 是显示在页面上的选项的文字,参数 value 对应于 <OPTION> 标记中的 value="...." 属性,即 option 对象的值;参数 defaultSelected 和 selected 是布尔值,用来设置此新建的 option 对象是否为默认选项,以及是否被选中,这两个参数都是可选的,即可以不提供这两个参数的参数值。这个 option 对象可以被加入到一个 options 数组中。而删除一个已经存在的 option 对象,只需将此对象在数组中的那个元素设置为空 ('null' 值) 即可,同时,这样也使数组变小了。

这个 在线示例 演示了如何创建一个两层的菜单系统,而且此菜单系统的第二层菜单是根据第一层菜单动态生成的。注意,这个例子不能在 IE 浏览器中使用。

此例中一些值得注意的地方:

第一,为每一个二级菜单设置一个数组;
不管选择了哪个大类,都会触发 onChange 事件,然后调用 setOptions() 函数设置二级菜单;
函数 setOptions() 首先将原有的二级菜单全部选项删除,然后再将新的二级菜单加入到选项列表中;
一旦二级菜单被设置完成,我们就调用 history.go(0) 来刷新当前页面,促使新的选项能够显示出来。

5、JavaScript 高级话题

创建你自己的对象

正如您所看到的,JavaScript 提供了很多网页组件和数据的对象及对象类型。但是,您的目光不能仅仅限于这些,您可以根据自己的需要创建自己的对象、属性和方法,这是很有用的,比如说您需要一个比较复杂的数据结构的时候,您就需要这样做。

在创建一个新的对象之前,您首先要创建一个数据结构。这些工作都在一个函数里边处理,在该函数中定义您的对象的属性(可以给这些属性设置初始值),然后你就可以创建居于此对象的方法了。

构造对象函数

每一个对象都需要一个构造对象函数,我们通过使用 new 关键字调用此函数来创建一个新的对象实例。这类函数定义了对象的属性,同时给这些属性设置初始值。您还可以在此类函数中声明对象的方法。

下边就是使用构造对象函数的一个例子,在这个函数中定义了一个新的对象 Product,此对象定义了每一个产品的基本属性:

function Product(name, num, price, shipping, quantity) {

this.name = name;
this.catalogNumber = num;
this.price = price;
this.shippingCost = shipping;
this.quantity = quantity;
}

注意关键字 this,它指向被创建的对象。您可以像下边那样创建新的 Product 对象实例:

var item1 = new Product("blender", "9003-2", 24.95, 2.50, 2);
var item2 = new Product("juicer", "9117-1", 49.95, 5.00, 1);

你还可以像访问其它对象的属性那样访问 Product 对象的属性:

var total = (item1.price + item1.shippingCost) * item1.quantity;

定义方法

上边的例子中通过访问 Product 对象 item1 的 price、shippingCost 和 quantity 属性计算 item1 的总价值,如果我们需要经常计算总价值,那么像上边那样用起来就很不方便,不过不用担心,我们可以为计算总价值创建一个方法,很简单,只要在构造对象函数中添加一行代码:“this.totalCost = totalCost;”,然后在构造对象函数的后边定义一个名为 totalCost 的函数:

function Product(name, num, price, shipping, quantity) {

this.name = name;
this.catalogNumber = num;
this.price = price;
this.shippingCost = shipping;
this.quantity = quantity;
this.totalCost = totalCost;
}

function totalCost() {

return ((this.price + this.shippingCost) * this.quantity);
}

注意在构造对象函数中定义该对象方法的格式:this.methodName = functionName,这里的方法名和函数名并不需要使用相同的名字,我们这里是为了看得清楚才使用相同的名字 totalCost 的。现在我们就可以使用此对象的方法了:

var total = item1.totalCost();

如果想了解如何构建和使用自定义对象,可以看一下这个 在线示例 ,这个例子中定义了一个简单的购物车,我们构建的对象名为 ShoppingCart,同时还给这个对象定义了增加和删除产品项的方法。

Cookies

使用 cookie,您可以将一些数据信息保存在客户端用户的机器中,而在以后用户浏览您的网页的时候再调出来使用。通常我们使用 cookie 保存一些数据、登陆帐号等。

创建一个 cookie 需要用到下边的信息:

cookie 的名字=cookie 的值 - 这个字符串表示 cookie 的数据,请看下边;
结束时间 - 您的 cookie 在客户端保留的时间,即是截止时间,如果当天的时间大于这个日期时间,那么客户端用户的机器将会删除这个 cookie;
域 (Domain) 和路径 (Path) - 这些是用于安全方面的,默认的情况下,域的值是服务器主机的域名,路径是当前这个设置 cookie 的页面在主机中相对于域名的路径 (这样就只有在相同路径下的那些页面可以使用此 cookie 了);
安全性 - 如果这个安全性标志被设置成 true 的话,那么 cookie 将会在一个安全的方式 (SSL 连接) 下发送到客户端。
通常,您只需要设置前两项 "cookie 的名字=cookie 的值" 和 "结束时间" 即可。在设置结束时间的时候,您可以使用 Date 对象,但要注意格式,单位是毫秒。下边就是一个例子,在这个例子中,"结束时间" 被设置成从当前时间算起过任意多天 (此例设置的 "结束时间" 是 7 天后):

var days = 7;
var expdate = new Date();
expdate.setTime (expdate.getTime() + (86400 * 1000 * days));

我们通过 documents.cookie 属性来对 cookie 的数据进行存取。cookie 的格式是 "cookie的名字=cookie的值; expires=cookie的结束时间; path=路径",而所有的 cookie 都是保存在 documents.cookie 属性中的,它们之间使用分号 ";" 分开,所以虽然您可以单独地设置各个 cookie,但却要通过切分操作才能得到各个 cookie 的值,请参照下边的示例。

经常用到的 cookie 函数

为了让您有个好的开始,下边的三个函数分别提供了设置、删除、获取 cookie 的功能:

function setCookie (name, value, expires) {

documents.cookie = name + "=" + escape(value) +
"; expires=" + expires.toGMTString() + "; path=/";
}

function getCookie(name) {

var search;

search = name + "="
offset = documents.cookie.indexOf(search)
if (offset != -1) {
offset += search.length ;
end = documents.cookie.indexOf(";", offset) ;
if (end == -1)
end = documents.cookie.length;
return unescape(documents.cookie.substring(offset, end));
}
else
return "";
}

function deleteCookie(name) {

var expdate = new Date();
expdate.setTime(expdate.getTime() - (86400 * 1000 * 1));
setCookie(name, "", expdate);
}

escape() 和 unescape() 是 JavaScript 的内建函数,它们用来将一些特殊字符转换成十六进制代码。通常情况下,cookie 中的名字、值都不能包含任何空格、逗号或分号。使用这两个函数可以将这一类的字符转换成合法的可供 cookie 使用的十六进制字符。

删除所有您不再使用的 cookie 是一个很好的习惯,因为客户端会限制您可以存储的 cookie 个数 (对于 Netscape 浏览器来说:每一个主机/域最多是 20 个 cookie,总共可以存储 300 个)。上边的删除 cookie 的函数将 cookie 的结束时间设置成前一天的时间,这样就可以达到删除的目的了。

事件捕捉

我们在这个教程中已经学过了事件句柄 (event handler),Internet Explorer 浏览器几乎为每一个 HTML 标记提供了事件句柄,而 Netscape 却有所不同,虽然它也为很多 HTML 标记提供了事件句柄,但是一些事件必须通过别的方法来捕捉。

在 Netscape 中捕捉事件

在 Netscape 4 或者更高版本的浏览器中,你可以捕捉当前浏览窗口中 window、layer 或 document 级别的对象的事件。captureEvent() 方法可以完成此操作, 此方法指定想要捕捉的事件,然后在通过编写函数来处理此事件句柄。

下边的例子中我们通知 window 对象捕捉鼠标点击的事件:

window.captureEvents(Event.CLICK);
window.document.onClick = myClick;

function myClick(even) {
...
}

请注意,我们在到 captureEvents() 方法中传送参数 Event.CLICK。这个事件对象 Event 包含了与事件有关的信息。而 Event.CLICK 是一个指向通常事件类型的对象实例,其它一些事件类型如下:

CLICK - 当鼠标点击的时候触发此事件
MOUSEDOWN - 当鼠标被按下的时候触发此事件
MOUSEUP - 当鼠标被松开的时候触发此事件
MOUSEMOVE - 当鼠标移动的时候触发此事件
KEYPRESS - 当从键盘输入的时候触发此事件
KEYDOWN - 当按下键盘的时候触发此事件
KEYUP - 当松开键盘的时候触发此事件
如果想捕捉更多的事件,您必须使用逻辑或运算符“|”来分割各个事件类型,如下边的代码所示:

window.captureEvents(Event.MOUSEDOWN | Event.KEYDOWN);
window.document.onMouseDown = myMouseDown;
window.document.onKeyDown = myKeyDown;

我们将 event 对象传递给事先安排好的事件句柄 (即此事件的处理函数),这个对象包含了一些通常的时间数据,例如它的类型等等。

Internet Explorer 中的事件

在 Internet Explorer 中不需要传递 event 对象,因为通常的时间对象都是 window 对象的一个属性。不幸的是,IE 的这些属性和 Netscape 的却不尽相同。

编写具有兼容性的代码

幸运的是,这两种浏览器之间还是有共同的代码可以使用的,最重要的是能够使用代码将两种浏览器区分开来。你可以尝试使用一些对象来试探浏览器的类型,例如,你可以使用 document.layers 对象来试探,这个对象是 Netscape 支持的对象,而相对应的 document.all 对象则是只有 IE 才支持的对象, Netscape 则不支持:

if (document.layers) {

// 在此处编写 Netscape 支持的代码
...
}

else if (document.all) {

// 在此处编写 IE 支持的代码
...
}

else {

// 在此处编写 Netscape 和 IE 都支持的代码
...
}

如果所试探的对象不存在 (即当前的浏览器不支持),它的值为空 (null) ,这就促使 if 表达式的值为“假” (false)。这种方法也可以用来防止这两种浏览器不支持该对象的老版本试图执行这些代码。

正则表达式

正则表达式是用于模式匹配的,它提供了强大的字符串替换、转换以及搜索功能。

Netscape 和 IE 在正则表达式对象的使用上有细微的不同,但是下边的代码却是通用的:

var myRE = /匹配模式/标记;

匹配模式的过程被看成是逐字匹配的,同时使用正则表达式还能匹配特殊字符或特殊格式的字符串 (左边的符号是匹配模式中使用的特殊格式):

a* - 匹配零个或零个以上的字符 a。
a+ - 匹配一个或一个以上的字符 a。
. - 匹配任何字符。
a|b - 匹配字符 a 或者 b。
a{n} - 匹配 n 个连续的字符 a。
[abc] - 匹配一个字符,这个字符是方括号“[]”中的任何一个字符,使用 [0-9] 匹配 0 到 9 的任何数字,使用 [a-z] 匹配字母 a, b, ... , z 中的任何小写字母,大写字母使用 [A-Z]。
/b - 匹配一个不以英文字母或数字为边界的字符串。
/s - 匹配一个空白的字符 (包括空格、Tab、换行等等)。
/w - 匹配一个任何英文或者数字的字符,和 [0-9a-zA-Z] 是等同的。
由于 '*' 是特殊字符,它的作用是匹配零个或零个以上的 '*' 前边的字符,所以如果想匹配字符 '*',需要在此字符前加一个反斜杠 '/' 字符。因此 '/*' 是匹配一个字符 '*'。你可以到 Netscape's JavaScript Reference 中去看一下有关正则表达式的细节。

标记可以是下边的值:

i - 忽略大小写。
g - 全局匹配,匹配所有符合匹配模式的字符,而不只是匹配第一个符合匹配模式的字符。
test() 方法用来比较已知的字符串,如果匹配则返回“真”值 (true)。可以看一下这个 在线示例,在这个例子中,使用了正则表达式来判断用户的输入是否符合电子邮件 (Email) 地址的格式:userid@domain.net

动态HTML [DHTML]

动态 HTML (Dynamic HTML 或 DHTML) 给 HTML 增加了几个新的标记,同时也增加了几个 JavaScript 的对象。动态 HTML 的一个主要特性是充分利用网页中的层 (layer) 和位置 (position)。

在这里我们再次声明,Netscape 和 IE 在应用上是有所不同的,Netscape 增加了支持“级联样式单” (Cascading Style Sheets 或 CCS) 的 <LAYER> 标记用来定位网页中的元素,而 IE 却支持更多的样式单,这些样式单都是居于 World Wide Web 联盟标准的 (可以参见第六部分的 DHTML 相关链接)。

给页面的内容定位

虽然 Netscape 对 CSS 的支持比较有限,但是我们还是可以很容易地使用 <LAYER> 标记来创建被定位的内容。下边的代码在两种浏览器中可以产生相同的效果:

Netscape

<layer bgcolor="#ffffcc" left=150 top=200 width=200 height=20>
显示的文本。
</layer>

IE

<div style="background-color:#ffffcc position:absolute;
left:150px; top:200px; width:200px; height:20px;">
显示的文本。
</div>

正如你所看到的,我们可以对被定位的内容块 (在上边例子中的内容块是“显示的文本”,也即是在 <layer>....</layer> 或 <div>....</div> 标记对之间的内容) 定义几个特性,例如背景颜色、字体颜色等等。top 和 left 的值用来告诉浏览器这一块内容在网页中的位置,top 是距离浏览器窗口顶部的长度,left 则是距离浏览器窗口左边框架的长度,它们的单位都是象素 (pixel)。

为了让代码在两种浏览器中都能实现相同的效果,我们可以使用前边讲过的方法首先探测一下浏览器的类型,然后再分别使用 document.writeln() 输出适用于两种浏览器的代码参见 在线示例 。

文档对象模型DOM

现在我们已经可以给网页中的内容定位了,但我们怎样才能熟练巧妙地使用这种方法使它成为 DHTML 技术的一部分呢?“文档对象模型” (简称 DOM) 是一个很流行的名字,它指的是在网页中的 JavaScript 分级对象。DHTML 为层与样式单增加了一些新的对象,你可以像使用 JavaScript 中其它对象那样使用这些对象。

当然,Netscape 和 IE 在 DOM 上的应用也有所不同,但是我们还是可以像上边的例子那样使用相应的代码来实现相同的效果。

你可以将一个内容块从一个地方移动 (重新定位) 到另一个地方,可以让它从看得见变成看不见。为了实现这些目的,你要针对不同的浏览器正确地处理好 JavaScript 对象。

让我们重新写一下上边的代码,并且在代码中给内容块加上名字,这样我们才能在程序代码中引用这些内容块作为对象来使用 (这其实就是 DOM 的一部分):

Netscape

<layer name="block1" bgcolor="#ffffcc" left=150 top=200 width=200 height=20>
Some text to display.
</layer>

IE

<div id="block1" style="background-color:#ffffcc position:absolute;
left:150px; top:200px; width:200px; height:20px;">
Some text to display.
</div>

现在我们将内容块放在 JavaScript 函数中当作对象来使用,同时返回此内容块对象本身:

function getBlock(name) {

// For Netscape.

if (document.layers)
return(document.layers[name]);

// For IE.

else if (document.all) {
layer = eval('document.all.' + name + '.style');
return(layer);
}

// 以上都不是,则返回 null.

else
return(null);
}

正如你所看到的,Netscape 使用 document.layers 数组来存储块对象,而 IE 则是创建名为 document.all.块名字.style 的对象来表示块。上边的函数返回了块对象,于是我们就可以使用这个返回值来访问块的属性或执行块的方法了。

现在让我们来看一下 在线示例 是如何移动一个块的。对于 Netscape 来说,我们只要设置块对象的 left 和 top 属性的值就可以达到移动块的目的,在 IE 中则是使用 pixelLeft 和 pixelTop 属性。在下边的函数 moveBlockBy 中将会改变这些属性的值:

function moveBlockBy(x, y) {

var block = getBlock("block1");

if (document.layers) {
block.left += x;
block.top += y;
}
else if (document.all) {
block.pixelLeft += x;
block.pixelTop += y;
}
}

参数 x 和 y 是块在水平和垂直方向上的移动增量。

处理浏览器的兼容性问题

正如你所看到的,两种浏览器在 DOM 上的运用也有很多不同之处,这样就给你在网页中实现 动态 HTML 效果带来了挑战,所以在编写代码的时候应该尽量避免使用不兼容的属性、方法等。

当然,你也可以只设计谋一种浏览器的代码,例如只设计 IE 浏览器可执行的代码,而不考虑 Netscape,但是这样你就将会失去 Netscape 的用户群。或者你也可以设计多套网页或网站,让它们分别支持各种浏览器,但是这样将会给维护网页或网站带来很大的麻烦,增加复杂性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: