第一节 JavaScript基础
1. 接触JavaScript
u JavaScript简史
对网页设计人员来说,这是一个充满着挑战和机遇的时代。近几年来,网页设计工作已经从一种混乱无序和即兴发挥的状态,逐渐发展为一种有着成熟的设计原则可供遵循的流水线作业。有越来越多的网页设计人员开始采用一种标准化的思路来建立网站,而实现这一思路和方法的具体技术则称为“ Web 标准”。
请看以下例子:
当网页设计人员谈沦起与 Web 标准有关的话题时, XHTML (可扩展的超文本标记语言)和 Css (层叠样式表)通常占据着核心地位。不过,由 W3C (万维网联盟)批准并由所有与标准相兼容的 web 浏览器支持的第三方技术称为 DOM (文档对象模型)。我们可以利用 DOM 去改善文档的可交互性,就像我们可以利用 CSS 给文档添加各种样式一样。
在开始学习 DOM 之前,我们先回顾一下使网页具备可交互性的程序设计语言。这种语言就是 JavaScript ,它已经诞生相当长的时间了。
JavaScript 是 Netscape 公司与 sun 公司合作开发的。在 JavaScript 出现之前, Web 浏览器不过是一种能够显示超文本文档的软件的基本部分。而在 JavaScript 出现之后,网页的内容不再局限于枯燥的文本,它们的可交互性得到了显著的改善。 JavaScript 的第一个版本,即 JavaScript 1.0版本,出现在 1995 年推出的 Netscape Navigator 2 浏览器中。
在 JavaScript 1.0 发布时, Netscape Navigator 主宰着浏览器市场,微软的 IE 浏览器则扮演着追赶者的角色。微软在推出 IE3 的时候发布了自己的 VBScript 语言并以 Jscript 为名发布了 JavaScript 的一个版本,以此很快跟上了 Netscape 的步伐。
面对微软公司的竟争, Netscape 和 Sun 公司联合 ECMA (欧洲计算机制造商协会)对 JavaScript 语言进行了标准化。其结果就是 ECMAScript 语言,这使得同一种语言又多了一个名字。虽说 ECMAScript 这个名字没有流行开来,但人们现在谈论的 JavaScript 实际上就是 ECMAScript 。
到了 1996 年, JavaScript 、 ECMAScript 、 JScript ― 随便你们怎么称呼它,己经站稳了脚跟。 Netscape 和微软公司在它们各自的第 3 版浏览器中都不同程度地提供了对 JavaScript 1.1 语言的支持。
这里必须指出的是, JavaScript 与 sun 公司开发的 Java 程序语言没有任何联系。人们最初给 JavaScript 起的名字是 LiveScript ,后来选择“ JavaScript ”作为其正式名称的原因,大概是想让它听起来有系出名门的感觉,但令人遗憾的是,这一选择反而史容易让人们把这两种语言混为一谈,而这种混淆又因为各种 Web 浏览器确实具备这样或那样的 Java 客户端支持功能的事实被进一步放大和加剧。事实上,虽说 Java 在理论上几乎可以部署在任何环境中,但 JavaScript 却只局限于 Web 浏览器。
JavaScript 是一种脚本语言, JavaScript 脚本通常只能通过 Web 浏览器去完成某种操作而不是像普通意义上的程序那样可以独立运行。因为需要由 Web 浏览器进行解释和执行,所以 JavaScript 脚本不像 Java 和 C++ 等编译型程序设计语言那样用途广泛。不过,这种相对的简单性也正是 JavaScript 的长处:因为比较容易学习和掌握,所以 JavaScript 很受那些本身不是程序员,但希望能够通过简单的剪贴操作把脚本嵌入他们的现有网页中的普通用户们的欢迎。
JavaScript 还向程序员提供了一种操控 Web 浏览器的手段。例如, JavaScript 语言可以用来调整 Web 浏览器窗口的高度、宽度和屏显位置等属性。以这种办法给出 Web 浏览器本身的属性可以看做是 BOM (浏览器对象模型)。 JavaScript 的早期版本还提供了一种初级的 DOM (文档对象模型)。
浏览器之争
Netscape Navigator4 (NN4)浏览器发布于 1997 年 6 月, IE4 浏览器发布于同年的 10 月。这两种浏览器都对它们的早期版本进行了许多改进,使用得到极大扩展的 DOM ,可以通过 JavaScript 完成的功能大大增加,而网页设计人员也开始熟悉一个新的名词:DHTML。
u DHTML
DHTML 是“Dynamic HTML”(动态 HTML )的简称。严格地说, DHTML 并不是一项单一的新技术,而是 HTML 、 CSS 和 JavaScript 这三种技术相结合的产物. DHTML 背后的含义是:
* 利用 HTML 把网页标记为各种元素;
* 利用 CSS 设计各有关元素的排版样式并确定它们在窗口中的显示位置;
* 利用 JavaScript 实时地操控和改变各有关样式。
DHTML 指的是上述三项技术的相互结合。利用 DHTML ,复杂的动画效果一下子变得非常容易实现。例如,可以先用 HTML 标记一个如下所示的页面元素:
<div id="myelement">This is my element</div>
然后,可以用 CSS 为这个页面元素定义如下所示的位置样式:
#myelement {
position:absolute;
left: 50px;
top: 100px;
}
接下来,只需利用 JavaScript 改变 myelement 元素的 left 和 top 样式,就可以让它在页面上随意移动。不过,这种简单性只停留在理论上——因为 NN4 和 IE4 浏览器使用的是不同的且不兼容的 DOM ,所以要想实际获得这种效果还需要程序员做很多工作。换句话说,虽然浏览器制造商的目标是一样的,但他们在解决 DOM 问题时采用的办法却完全不同。
u 制订标准
就在浏览器的制造商们为了压倒竞争对手而以 DOM 为武器展开一场营销大战的同时, W3C 不事声张地推出了一个标准化的 DOM 。令人欣慰的是, Netscape 、微软和其他一些浏览器制造商们还能抛开彼此的敌意而与 W3C 携手制定新的标准,并于 1998 年 10 月完成了“第 1 级 DOM " ( DOM Level l )。 回到刚才的例子,我们一起看看新的标准化 DOM 是如何解决同样的问题的。我们己经用 <div> 标签定义了一个 ID 为 myelement 的页面元素,现在需要找出它的 left 位置并把这个值保存到变量 xpos 中。下面是需要用到的语法:
var xpos = document.getElementByld ("myelement" ).style.left
乍看起来,这与刚才那两种非标准化的专有 DOM 相比并没有明显的改进。但事实上,标准化的 DOM 有着非常远大的抱负。浏览器制造商们感兴趣的只不过是一些通过 JavaScript 操控网页的具体办法,但 W3C 推出的标准化 DOM 却可以让任何一种程序设计语言对使用任何一种标记语言编写出来的任何一份文档进行操控。
DOM 是一种 API (应用编程接口)。简单地说,API 就是一组己经得到有关各方共同认可的基本约定。在现实世界中,相当于 API 的例子包括(但不限于):
* 摩尔斯码
* 国际时区
* 化学元素周期表
以上这些都是不同学科领域中的标准,它们使得人们能够更方便地进行交流与合作。如果没有这样的标准,事情往往会演变成为一场灾难。别忘了,英制度量衡与公制度量衡之间的差异至少导致过一次火星探测任务的失败。
在软件编程领域中,虽然存在着多种不同的语言,但很多任务却是相同或相似的。这也正是人们需要 API 的原因.一旦掌握了某个标准,就可以把它应用在许多不同的环境中。虽然有关的语法会因为使用的程序设计语言而有所变化,但这些约定却总是保持不变的。因此,在学完关于如何通过 JavaScript 使用 DOM 的书之后,你们获得的关于 DOM 的新知识对你们今后的工作——例如,需要使用诸如 PHP 或 ASP.NET 之类的程序设计语言去解析一份 XML 文档的时候,也会有很大的帮助。 W3C 对 DOM 的定义是:“一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态地对文档的内容、结构和样式进行访问和修改。”
W3C 推出的标准化 DOM ,在独立性和适用范围等诸多方面,都远远超出了各自为战的浏览器制造商们推出的各种专有 DOM 。我们知道,浏览器市场份额大战的赢家是微软公司,但具有讽刺意味的是,专有的 DOM 和 HTML 标记对这个最终结果并无影响。 IE 浏览器之所以能击败其他对手,其主要原因不过是有运行着 Windows 操作系统的个人电脑都预装了它而己。受浏览器之争影响最重的人群是那些网站和网页设计人员。需要同时支持多种浏览器的软件开发工作,曾经是程序员们的噩梦。除了刚才提到的那些在 JavaScript 实现方面的差异之外 Netscape Navigator 和 IE 这两种浏览器在对 CSS 的支持方面也有许多非常不同的地方。有不少程序员都把编写那些可以同时工作在这两种浏览器环境下的样式表和脚本的工作视为一种黑色艺术。
为了打破浏览器制造商们筑起的专利壁垒,一群志同道合的程序员建立了名为 Web 标准计划(简称 WASP , http: //webstandards.org/ )的小组。 WaSP 小组采取的第一个行动就是,鼓励浏览器制造商们接受 W3C 制定和推荐的各项标准―也就是在浏览器制造商们的帮助下得以起草和完善的那些标准。或许是因为来自 WaSP 小组的压力,又或许是因为企业的内部决策,浏览器制造商后来推出的下一代浏览器产品对 Web 标准的支持得到了极大的改善。微软公司在正 IE 8 浏览器中内建了对 W3C 制定的标准化 DOM 的支持,但同时继续支持其专有的 Microsoft DOM。
目前使用的 95%以上的浏览器都具备对 DOM 的内建支持。发生在 20 世纪 90 年代后期的浏览器大战已经离我们越来越遥远。虽说还没有一种浏览器能够提供对 W3C DOM 的完美支持,但现代的浏览器都至少实现了 W3C 相关标准中 95%的规范,而这意味着在编写 JavaScript 代码时几乎不需要考虑它们将运行在何种浏览器环境下了。虽然 IE 浏览器的开发工作停顿了下来,但网页设计人员的日子已经不像过去那么困难了。过去,程序员在编写 JavaScript 脚本时往往不得不增加一些代码去探测在客户端运行的是哪种浏览器:现在,程序员只需编写一次代码就几乎可以把它们应用在所有的场合了。只要遵守 DOM 标准,程序员就可以相当有把握地确信,自己编写的脚本几乎在所有的环境下都可以正常工作。
u 小结
在前面对 JavaScript 发展简史的介绍中,特别提到,不同的浏览器采用了不同的办法来完成同样的任务。这一无法回避的事实不仅主宰着如何编写 JavaScript 脚本代码,还影响着 JavaScript 教科书的编写方式。
JavaScript 教科书的作者往往会提供大量的示例代码以演示这种脚本语言的使用方法,而完成同一项任务的示例脚本往往需要为不同的浏览器编写两次或更多次。就像你们在绝大多数网站上查到的代码一样,在绝大多数 JavaScript 教科书的示例脚本中往往充斥着大量的浏览器检测代码和分支调用结构。类似地,在 JavaScript 技术参考文献中,函数和方法的清单也往往是一式多份——至少需要标明哪种浏览器支持哪些函数和方法。
如今这种情况己经有所改变。多亏了标准化的 DOM ,不同的浏览器在完成同样的任务时采用的细节做法己经非常一致了。因此在本书中,当演示如何使用 JavaScript 和 DOM 完成某项任务时,将不再需要撇开主题去探讨如何对付不同的浏览器。如果无特殊的必要,我们将尽量避免涉及任何一种特定的浏览器.。此外,我们在后面的内容中将不再使用“DHTML”这个术语,因为我们认为这个术语与其说是一个技术性词汇,不如说是一个市场营销嘘头。首先,它听起来很像是 HTML 或 XHTML 语言的另一种扩展,因而很容易造成误解或混淆;其次,这个术语容易勾起一些痛苦的回忆―如果你向 20 世纪 90 年代后期的程序员们提起“ DHTML " ,你将很难让他们相信它现在己经变成一种简单、易用的标准化技术。
DHTML 是 HTML/XHTML 、CSS 和 JavaScript 相结合的产物,但把这些东西真正凝聚在一起的是 DOM 。如果真的需要有个词汇来描述这一过程的话,我们就应该使用一个更精确的词汇。用 DHTML 来称呼与浏览器有关的编程工作并不是不可以,但用它来描述基于有关标准的代码编写工作就不那么恰当了.在探讨如何使用 W3C DOM 来处理文档和样式表时,我们认为“ DOM 脚本程序设计”是一种更精确的说法。DHTML 只适用于 Web 文档,“DOM 脚本程序设计”则涵盖了使用任何一种支持 DOM API 的程序设计语言去处理任何一种标记文档的所有情况。具体到 web 文档, JavaScript 语言的特点使它成为了 DOM 脚本程序设计的最佳选择。
在正式介绍 DOM 脚本程序设计技巧之前,我们将在下一节先向大家简要地介绍一下 JavaScript 的语法。
3. JavaScript的语法
在网页中加入 JavaScript ,要在你的网页中使用 JavaScript ,你首先必须要知道该将它放在哪儿。其实很简单,只要在你的网页(HTML文件)中插入 <SCRIPT> 和 </SCRIPT> 标记对,你就可以在这两个标记队之间插入你的 JavaScript 代码了:
<script>
alert("Hello world!");
</script>
另外,你也可以将 JavaScript 代码放在另一个单独的文件里,然后在网页(HTML文件)中使用 “SRC= 此单独文件的路径/地址(URL)”来使用此单独文件里的 JavaScript 程序代码。一般将这个单独的文件保存为扩展名为 .JS 的文件:
<script src="mycode.js"></script>
你可以在一个 HTML 文件中使用 <SCRIPT> </SCRIPT> 标记对任意多次。虽然在通常情况下你都会将所有代码放在 HTML 文件的某一处,但有些时候为了保证你的JavaScript程序能够正确运行,你不得不将它们分散地放在 HTML 文件的多个地方。
不管你是在 HTML 文件中直接插入代码还是通过外部的单独的文件来使用 JavaScript ,通常都是将 <SCRIPT> </SCRIPT> 标记对放在 <HEAD> 和 </HEAD> 标记对之间。这样能够保证在你的网页被下载到客户端后开始执行 JavaScript 的时候你的 JavaScript 代码也已经被下载到客户端了。这同时也是放置你的 JavaScript 函数的好地方,如果你想要某些代码在你的网页显示出来之后才执行的话,你最好将这些代码放在函数里,等网页显示以后再通过调用函数来执行它们。
4. JavaScript 语法基础
在你开始编写代码之前,你必须知道一些基本的 JavaScript 语法和结构。 JavaScript 语法与 C/C++、Java 的语法很相似,如果你想要了解非常详尽的语法,可以参考 Microsoft\'s JScript Reference ,在那里你可以看到很多关于 JavaScript 语句、运算符、内建函数等等的内容列表,而我们这里只是讲一些在你开始学习 JavaScript 的时候需要掌握的一些基础语法知识!
注释
JavaScript解释器并不要求JavaScript脚本中的每条语句都必须是可执行的。有时,需要在脚本中写出一些仅供参考或提示性的信息,但并不希望JavaScript解释器真的去执行这样的语句。这种语句称为注释(comment)。
注释语句非常有用,它们可以让你把编写代码时的一些想法和考虑记载下来供今后参考,还可以帮助你追踪有关代码的执行流程。类似于日常生活中的便条,注释语句可以帮助程序员跟踪和追查在脚本中发生的事情。
有多种在JavaScript脚本中插入注释的具体做法。例如,如果使用了两个斜杠作为一行的开头,这一行就将被解释为一条注释:
// Note to self: comments are good.
如果使用这种记号方式,就必须在每行注释的开头加上两个斜杠。也就是说,像下面这样的做法是有问题的——第2行将不会被解释为一条注释:
// Note to self:
comments are good.
如果你想写出两行注释,就必须把它们写成如下所示的样子:
// Note to self:
// comments are good.
一条跨越多行的注释还可以用下面这个方式来给出:在整段注释内容的开头加上一个“/*”,在整段注释内容的末尾加上一个“*/”。下面是一个多行注释的例子:
/* Note to self:
comments are good. */
这种记号方式在需要插入跨越多行的大段注释内容时很有用,它可以提高整个脚本的可读性。
还可以使用HTML风格的注释,但这种做法仅适用于单行注释。换句话说,JavaScript解释器对“<!-”的处理与对“//”的处理是一样的:
<!- This is a comment in JavaScript.-->
如果是在HTML文档中,还需要以“->”来结束这种注释语句,如下所示:
<!- This is a comment in HTML ->
但JavaScript不要求这样做,它会把“->”视为注释内容的一部分。
请注意,HTML允许上面这样的注释跨越多个行,但JavaScript要求这种注释的每行都必须在开头加上“<!-”来作为标志。
因为JavaScript解释器在处理这种风格的注释时与大家所熟悉的HTML做法不同,为避免发生混淆,笔者建议大家最好不要在JavaScript脚本中使用HTML风格的注释。如果没有特别的理由,用“//”记号给出单行注释、用“/*”记号给出多行注释。
变量
在日常生活里,有些东西是固定不变的,有些东西则会发生变化。例如,人的姓名和生日是固定不变的,但心情和年龄却会随着时间的推移而发生变化。在谈论程序设计语言时,人们把那些会发生变化的东西称为变量(variable)。
我们的心情会随着我的切身感受而变化。假设我有一个变量mood(意思是“心情”),我可以把此时此刻的心情存放到这个变量中。不管这个变量的值是“happy”还是“sad”,它的名字始终是mood。我们可以随时改变这个值。
类似地,假设我现在的年龄是33岁。一年之后,我的年龄就是34岁。我可以使用变量age来存放我的年龄并在生日那天改变这个值。当我现在去查看age变量时,它的值是33;但一年之后,它的值将变成34。
把值存入变量的操作称为赋值(assignment)。我把变量mood赋值为“happy”,把变量age赋值为33。
下面是在JavaScript中对这些变量进行赋值的语法:
mood = "happy";
age = 33;
把值赋值给变量后,我们就可以说该变量包含这个值。例如,变量mood现在包含值“happy”,变量age现在包含值33。我们可以用如下所示的语句把这两个变量的值显示在一个弹出式警告窗口中:
alert(mood);
alert(age);
请注意,JavaScript允许程序员直接对变量进行赋值而无需提前对它们做出声明。这在许多程序设计语言中都是不允许的。有相当一部分程序设计语言要求在使用变量之前必须先对它做出“介绍”——术语称之为声明(declare)。
在JavaScript脚本中,如果程序员在对某个变量进行赋值之前未对其做出声明,赋值操作将自动声明该变量。虽然JavaScript没有要求程序员必须这么做,但提前对变量做出声明仍是一种良好的编程习惯。下面的语句对变量mood和age做出了声明:
var mood;
var age;
每次只声明一个变量的做法并不是绝对的,JavaScript也允许程序员用一条语句声明多个变量,如下所示:
var mood, age;
JavaScript甚至允许程序员把声明变量和对该变量进行赋值的这两项操作合起来一次完成:
var mood = "happy";
var age = 33;
我们甚至还可以像下面这样做:
var mood = "happy", age = 33;
像上面这样声明和赋值各有关变量是最有效率的做法,这条语句的效果相当于下面这些语句的总和:
var mood, age;
mood = "happy";
age = 33;
在JavaScript语言里,变量和其他语法元素的名字都是区分字母大小写的。名字是mood的变量与名字是Mood、MOOD或mOOd的变量没有任何关系,它们不是同一个变量。下面的语句是在对两个不同的变量进行赋值:
var mood = "happy";
MOOD = "sad";
age = 33;
JavaScript语法不允许变量的名字中包含空格或标点符号(但美元符号“$”例外)。下面这条语句将导致语法错误:
var my mood = "happy";
JavaScript变量名允许包含字母、数字、美元符号和下划线字符。为了让比较长的变量名有更好的可读性,可以在变量名中的适当位置插入一个下划线字符,就像下面这样:
var my_mood = "happy";
在上面这条语句中,单词“happy”是JavaScript语言中的一个字面量(literal),也就是可以在JavaScript代码中直接写出来的数据内容。字面量除了它本身所给出的内容外无任何附加含义,用大力水手Popeye的话来说:“它就是它!”与此形成对照的是,单词“var”是 JavaScript语言中的一个关键字,my_mood是一个变量的名字;它们都有自身内容以外的含义。
变量mood的值是一个字符串类型的字面量,变量age的值则是一个数值类型的字面量。虽然它们是两种不同的数据类型,但在JavaScript脚本中为它们做出声明和进行赋
请发表评论