第 1 章 JavaScript简史

第 1 章 JavaScript简史

本章内容

  • JavaScript的起源
  • 浏览器战争
  • DOM的演变史

本书第1版面世的时候,做一名Web设计师是件很让人很兴奋的事。5个年头过去了,这个职业依然保持着强大的吸引力。特别是JavaScript,经历了从被人误解到万众瞩目的巨大转变。Web开发呢,也已从混乱无序的状态,发展成一门需要严格训练才能从事的正规职业。无论设计师还是开发人员,在创建网站的过程中都积极地采用标准技术,Web标准已经深入人心。

当网页设计人员谈论起与Web标准有关的话题时,HTML(超文本标记语言)和CSS(层叠样式表)通常占据着核心地位。不过,W3C(万维网联盟)已批准另一项技术,所有与标准相兼容的Web浏览器都支持它,这就是DOM(文档对象模型)。我们可以利用DOM给文档增加交互能力,就像利用CSS给文档添加各种样式一样。

在开始学习DOM之前,我们先检视一下使网页具备交互能力的程序设计语言。这种语言就是JavaScript,它已经诞生相当长的时间了。

1.1 JavaScript的起源

JavaScript是Netscape公司与Sun公司合作开发的。在JavaScript出现之前,Web浏览器不过是一种能够显示超文本文档的简单的软件。而在JavaScript出现之后,网页的内容不再局限于枯燥的文本,它们的可交互性得到了显著的改善。JavaScript的第一个版本,即JavaScript 1.0版本,出现在1995年推出的Netscape Navigator 2浏览器中。

在JavaScript 1.0发布时,Netscape Navigator主宰着浏览器市场,微软的IE浏览器则扮演着追赶者的角色。微软在推出IE 3的时候发布了自己的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是一种脚本语言,通常只能通过Web浏览器去完成一些操作而不能像普通意义上的程序那样独立运行。因为需要由Web浏览器进行解释和执行,所以JavaScript脚本不像Java和C++等编译型程序设计语言那样用途广泛。不过,这种相对的简单性也正是JavaScript的长处:比较容易学习和掌握,所以那些本身不是程序员,但希望通过简单的剪贴操作把脚本嵌入现有网页的普通用户很快就接受了JavaScript。

JavaScript还向程序员提供了一些操控Web浏览器的手段。例如,JavaScript语言可以用来调整Web浏览器窗口的高度、宽度和位置等属性。这种设定浏览器属性的办法可以看做是BOM(浏览器对象模型)。JavaScript的早期版本还提供了一种初级的DOM。

1.2 DOM

什么是DOM?简单地说,DOM是一套对文档的内容进行抽象和概念化的方法。

在现实世界里,人们对所谓的“世界对象模型”都不会陌生。例如,当用“汽车”、“房子”和“树”等名词来称呼日常生活环境里的事物时,我们可以百分之百地肯定对方知道我们说的是什么,这是因为人们对这些名词所代表的东西有着同样的认识。于是,当对别人说“汽车停在了车库里”时,可以断定他们不会理解为“小鸟关在了壁橱里”。

我们的“世界对象模型”不仅可以用来描述客观存在的事物,还可以用来描述抽象概念。例如,假设有个人向我问路,而我给出的答案是“左边第三栋房子”。这个答案有没有意义将取决于那个人能否理解“第三”和“左边”的含义。如果他不会数数或者分不清左右,则不管他是否理解这几个概念,我的回答对他都不会有任何帮助。在现实世界里,正是因为大家对抽象的世界对象模型有着基本的共识,人们才能用非常简单的话表达出复杂的含义并得到对方的理解。具体到这里的例子,你可以相当有把握地断定,其他人对“第三”和“左边”的理解和我完全一样。

这个道理对网页也同样适用。JavaScript的早期版本向程序员提供了查询和操控Web文档某些实际内容(主要是图像和表单)的手段。因为JavaScript预先定义了“images”和“forms”等术语,我们才能像下面这样在JavaScript脚本里引用“文档中的第三个图像”或“文档中名为‘details’的表单”:

document.images[2]
document.forms['details']

现在的人们通常把这种试验性质的初级DOM称为“第0级DOM”(DOM Level 0)。在还未形成统一标准的初期阶段,“第0级DOM”的常见用途是翻转图片和验证表单数据。Netscape和微软公司各自推出第四代浏览器产品以后,DOM开始遇到麻烦,陷入困境。

1.3 浏览器战争

Netscape Navigator 4发布于1997年6月,IE 4发布于同年10月。这两种浏览器都对它们的早期版本进行了许多改进,大幅扩展了DOM,使能够通过JavaScript完成的功能大大增加。而网页设计人员也开始接触到一个新名词:DHTML。

1.3.1 DHTML

DHTML是“Dynamic HTML”(动态HTML)的简称。DHTML并不是一项新技术,而是描述HTML、CSS和JavaScript技术组合的术语。DHTML背后的含义是:

  • 利用HTML把网页标记为各种元素;
  • 利用CSS设置元素样式和它们的显示位置;
  • 利用JavaScript实时地操控页面和改变样式。

利用DHTML,复杂的动画效果一下子变得非常容易实现。例如,用HTML标记一个页面元素:

<div id="myelement">This is my element</div>

然后用CSS为这个页面元素定义如下位置样式:

#myelement {
  position: absolute;
  left: 50px;
  top: 100px;
}

接下来,只需利用JavaScript改变myelement元素的lefttop样式,就可以让它在页面上随意移动。不过,这只是理论而已。

不幸的是,NN 4和IE 4浏览器使用的是两种不兼容的DOM。换句话说,虽然浏览器制造商的目标一样,但他们在解决DOM问题时采用的办法却完全不同。

1.3.2 浏览器之间的冲突

Netscape公司的DOM使用了专有元素,这些元素称为(layer)。层有唯一的ID,JavaScript代码需要像下面这样引用它们:

document.layers['myelement']

而在微软公司的DOM中这个元素必须像下面这样引用:

document.all['myelement']

这两种DOM的差异并不止这一点。假设你想找出myelement元素的left位置并把它赋值给变量xpos,那么在Netscape Navigator 4浏览器里必须这样做:

var xpos = document.layers['myelement'].left;

而在IE 4浏览器中,需要使用如下所示的语句才能完成同样的工作:

var xpos = document.all['myelement'].leftpos;

这就导致了一种很可笑的局面:程序员在编写DOM脚本代码时必须知道它们将运行在哪种浏览器环境里,所以在实际工作中,许多脚本都不得不编写两次,一次为Netscape Navigator,另一次为IE。同时,为了确保能够正确地向不同的浏览器提供与之相应的脚本,程序员还必须编写一些代码去探查在客户端运行的浏览器到底是哪一种。

DHTML打开了一个充满机会的新世界,但想要进入其中的人们却发现这是个充满苦难的世界。因此,没多久,DHTML就从一个大热门变成了一个人们不愿提起的名词,而对这种技术的评价也很快地变成了“宣传噱头”和“难以实现”。

1.4 制定标准

就在浏览器制造商以DOM为武器展开营销大战的同时,W3C不事声张地结合大家的优点推出了一个标准化的DOM。令人欣慰的是,Netscape、微软和其他一些浏览器制造商们还能抛开彼此的敌意而与W3C携手制定新的标准,并于1998年10月完成了“第1级DOM”(DOM Level 1)。

回到刚才的例子,我们已经用<div>标签定义了一个ID为myelement的页面元素,现在需要找出它的left位置并把这个值保存到变量xpos中。下面是使用新的标准化DOM时需要用到的语法:

var xpos = document.getElementById('myelement').style.left

乍看起来,这与刚才那两种非标准化的专有DOM相比并没有明显的改进。但事实上,标准化的DOM有着非常远大的抱负。

浏览器制造商们感兴趣的只不过是通过JavaScript操控网页的具体办法,但W3C推出的标准化DOM却可以让任何一种程序设计语言对使用任何一种标记语言编写出来的任何一份文档进行操控。

1.4.1 浏览器以外的考虑

DOM是一种API(应用编程接口)。简单地说,API就是一组已经得到有关各方共同认可的基本约定。在现实世界中,相当于API的例子包括(但不限于)摩尔斯码、国际时区、化学元素周期表。以上这些都是不同学科领域中的标准,它们使得人们能够更方便地交流与合作。如果没有一个统一的标准,事情往往会演变成为一场灾难。别忘了,因混淆英制度量衡与公制度量衡至少导致过一次火星探测任务的失败。

在软件编程领域中,虽然存在着多种不同的语言,但很多任务却是相同或相似的。这也正是人们需要API的原因。一旦掌握了某个标准,就可以把它应用在许多不同的环境中。虽然语法会因为使用的程序设计语言而有所变化,但这些约定却总是保持不变的。

因此,虽然本书的重点是教会你如何通过JavaScript使用DOM,当你需要使用诸如PHP或Python之类的程序设计语言去解析XML文档的时候,你获得的DOM新知识将会有很大的帮助。

W3C对DOM的定义是:“一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态地访问和修改文档的内容、结构和样式。”W3C推出的标准化DOM,在独立性和适用范围等诸多方面,都远远超出了各自为战的浏览器制造商们推出的各种专有DOM。

1.4.2 浏览器战争的结局

我们知道,浏览器市场份额大战中微软公司战胜了Netscape,具有讽刺意味的是,专有的DOM和HTML标记对这个最终结果几乎没有产生影响。IE浏览器注定能击败其他对手,不过是因为所有运行Windows操作系统的个人电脑都预装了它。

受浏览器战争影响最重的人群是那些网站设计人员。跨浏览器开发曾经是他们的噩梦。除了刚才提到的那些在JavaScript实现方面的差异之外,Netscape Navigator和IE这两种浏览器在对CSS的支持方面也有许多非常不同的地方。而编写那些可以同时支持这两种浏览器的样式表和脚本的工作也成了一种黑色艺术。

浏览器制造商的自私姿态遭到人们的激烈反对,一个名为Web标准计划(简称WaSP,http://webstandards.org/)的小组应运而生。WaSP小组采取的第一个行动就是,鼓励浏览器制造商们采用W3C制定和推荐的各项标准,也就是在浏览器制造商们的帮助下得以起草和完善的那些标准。

或许是因为来自WaSP小组的压力,又或许是因为企业的内部决策,下一代浏览器产品对Web标准的支持得到了极大的改善。

1.4.3 崭新的起点

早期浏览器大战至今,浏览器市场已经发生了巨大的变化,而且到了今天,这一切也几乎每天都有变化。有的浏览器,比如Netscape Navigator,差不多已经从人们的视野中消失了,而新一代浏览器则陆续登台亮相。苹果公司在2003年首次发布了它的Safari浏览器(基于WebKit),它从一开始就坚定不移地遵循DOM标准。今天,包括Firefox、Chrome、Opera和IE,以及一些基于WebKit的其他浏览器都对DOM有着良好的支持。很多最潮的智能手机浏览器都在使用WebKit渲染引擎,推动着手持浏览器开发不断向前,让手机上网的体验甚至好过了使用某些桌面浏览器。

注意 WebKit(http://webkit.org)是Safari和Chrome采用的一个开源Web浏览器引擎。以WebKit和Gecko(Firefox的核心,https://developer.mozilla.org/en/Gecko)为代表的开源引擎,在促进微软的Trident(IE的核心)等专有浏览器引擎逐步向Web标准靠拢方面起到特别积极的作用。

今天,几乎所有的浏览器都内置了对DOM的支持。20世纪90年代后期的浏览器大战的硝烟已经散尽。现在的浏览器厂商无一不在争先恐后地实现最新规范。我们已经目睹了由异步数据传输技术(Ajax)所引发的学习DOM脚本编程的热潮,而HTML5 DOM的众多新特性,怎能不让人对Web的未来浮想联翩?HTML5极大地改进了标记的语义,让我们通过<audio><video>得以控制各种媒体,<canvas>元素具备了完善的绘图能力,浏览器本地存储超越了cookie限制,更有内置的拖放支持,等等。

Web设计师的日子已经今非昔比。尽管还没有一款浏览器完美无瑕地实现W3C DOM,但所有现代浏览器对DOM特性的覆盖率都基本达到了95%,而且每款浏览器都几乎会在第一时间实现最新的特性。这意味着什么?意味着大量的任务都不必依靠分支代码了。以前,为了探查浏览器,我们不得不编写大量分支判断脚本,现在,终于可以实现“编写一次,随处运行”的梦想了。只要遵循DOM标准,就可以放心大胆地去做,因为你的脚本无论在哪里都不会遇到问题。

1.5 小结

在前面对JavaScript发展简史的介绍中,笔者特别提到,不同的浏览器采用了不同的办法来完成同样的任务。这一无法回避的事实不仅主宰着如何编写JavaScript脚本代码,还影响着JavaScript教科书的编写方式。

JavaScript教科书往往会提供大量的示例代码以演示这种脚本语言的使用方法,而完成同一项任务的示例脚本往往需要为不同的浏览器编写两次或更多次。就像你在绝大多数网站上查到的代码一样,在绝大多数JavaScript教科书的示例脚本中往往充斥着大量的浏览器探查代码和分支调用结构。类似地,在JavaScript技术文档中,函数和方法的清单也往往是一式多份——至少需要标明哪种浏览器支持哪些函数和方法。

如今这种情况已经有所改变。多亏了标准化的DOM,不同的浏览器在完成同样的任务时采用的做法已经非常一致了。因此,在本书中,当演示如何使用JavaScript和DOM完成某项任务时,将不再需要撇开主题去探讨如何对付不同的浏览器。如果无特殊的必要,本书将尽量避免涉及任何一种特定的浏览器。

此外,我们在本书后面的内容中将不再使用“DHTML”这个术语,因为这个术语与其说是一个技术性词语,不如说是一个市场营销噱头。首先,它听起来很像是HTML或XHTML语言的另一种扩展,因而很容易造成误解或混淆;其次,这个术语容易勾起一些痛苦的回忆——如果你向20世纪90年代后期的程序员们提起“DHTML”,你将很难让他们相信它现在已经变成了一种简单、易用的标准化技术。

DHTML曾被认为是HTML/XHTML、CSS和JavaScript相结合的产物,就像今天的HTML5那样,但把这些东西真正凝聚在一起的是DOM。如果真的需要来描述这一过程的话,“DOM脚本程序设计”更精确,它表示使用W3C DOM来处理文档和样式表。DHTML只适用于Web文档,“DOM脚本程序设计”则涵盖了使用任何一种支持DOM API的程序设计语言去处理任何一种标记文档的情况。具体到Web文档,JavaScript的无所不在使它成为了DOM脚本程序设计的最佳选择。

在正式介绍DOM脚本程序设计技巧之前,我们将在下一章先简要地复习一下JavaScript的语法。

目录