2.2 HTML5简介
本书将创建可通过Web浏览器查看的HTML5文件。HTML5是最新一代HTML(Hyper Text Markup Language超文本标记语言),该语言用于将内容结构化为有组织的层次并展现在万维网上。HTML元素是创建网页的基石。在本书编撰期间,HTML5规范仍在制定阶段,不过许多功能已趋于稳定并可随时运用到产品上,例如,canvas元素。HTML5加入了一些新元素并为多媒体内容(例如,音频与视频)提供了更好的支持,从而进一步完善了在1997被制定为标准的HTML4。由于这些新的并在语义上有意义的元素暴露了一系列可在HTML文件中访问的属性以及控件,因此可以通过JavaScript用编程方式操作它们,这赋予了我们创建并控制媒体的有效手段。
HTML5是一系列独立功能的集合。当谈及一个特定浏览器是否支持HTML5时,这不是一个全有全无的问题,合理的做法是测试该浏览器是否支持规范中定义的某个特定功能。不同的浏览器可能对不同的功能有不同程度的支持。不过这使得开发者很难决定是否采用某个HTML5元素,因为他猜不到用户会使用何种浏览器查看文件。随着各个浏览器的不断改进,跨越各个平台的HTML5功能检测变得越来越容易,目前开发者应该总是检测用户的Web浏览器是否支持某个HTML5功能并为之提供备用方案,即便备用方案只是一句委婉地提示用户升级浏览器的消息。
2.2.1 对canvas的支持
一个至少对本书而言有利的好消息是所有主流的浏览器厂商都提供了对 canvas 元素的支持。这意味着,只要用户将他的浏览器升级到了最新的版本,他就可以看到我们创建的动画。游戏和动画对推动用户升级他们的浏览器是一种有利的刺激,因为大多数的人在经历过近十年的视频游戏的发展后很容易理解顶尖的图像效果需要最新的软硬件支持。至少说服用户升级浏览器比让他买一个全新的游戏主机要容易多了。
万一某个Web浏览器不支持canvas元素,在HTML文件中,开发者仍可以在canvas标签中提供如下备用内容:
<canvas width="400" height="400">
<p>This browser does not support the<code>canvas</code> element.</p>
</canvas>
该警告消息仅在浏览器无法识别canvas标签时才会显示。如果浏览器支持该标签,它会呈现canvas元素并忽略其中内嵌的
元素。
还可以在HTML文件中加入以下JavaScript代码,以编程方式测试浏览器是否支持canvas元素:
if (document.createElement('canvas').getContext) {
console.log("Success! The canvas element is supported.");
}
以上代码创建了一个新的canvas元素并测试getContext属性是否存在,而我们知道一个有效的HTML5 canvas元素是包含该属性的。因此,如果浏览器确实支持canvas元素,你将会在调试控制台上看到成功的消息。
表2-1列出了最流行的Web浏览器以及它们开始支持canvas元素的最小版本号。
2.2.2 性能
编程图形一直并且在可预见的将来也是一项计算量很大的操作。原因很简单,你能做的越多,你想要做的也越多,同时对系统的性能要求也越高。视频游戏过去25年的历史是一段令人惊叹的技术发展之旅,从游乐场游戏机中的块状角色发展到了今天运行在游戏主机上的让人身临其境的3D世界。不过,我们还是想做得更好。我们时常拿计算机动画与现实世界中的一些特效做对比:例如,人物的真实感、光影特效与物理效果。令人惊叹的是,这些模拟竟经得起人们的审视,而且不止一两个例子如此。我们目前还处在计算机动画的起步阶段,随着计算机不断地变快(得益于摩尔定律),开发人员不断改善技术,人类在视觉创造上的能力将永无止境。
不过使用canvas元素在Web上绘制动画还处在它的孵化期,现在这只是被视为使用诸如Adobe Flash这样的浏览器插件实现动画的一种替代方式。最近几年,开发者在Web浏览器以及JavaScript引擎中的速度和性能上取得了突破性的发展,鉴于此领域竞争异常激烈,我们可以预见到将来会有更多的优化和提升。
本书中编写的示例可以在近期的电脑和Web浏览器上获得流畅以及合理的性能表现。不过读者的电脑配置可能与作者有差异,所以当你在实验本书中的源代码时,尽可以调整某些参数的设定以获得更加流畅的体验。而且尝试不同的参数值并观察结果的变化也是一种学习公式工作原理的更好途径。
不过,在你对外分享任何动画前,请在尽可能多的设备上加以测试。因为越来越多的人开始使用移动电话与平板电脑而不是传统的台式机来访问Web,开发者需要兼顾到各种不同设备上的性能差异。针对各种不同平台的测试和度量是确保代码能够表现良好的唯一手段。
2.2.3 HTML5基本文档
Web开发的一个非常大的优势在于创建和查看文件非常容易,你所需的仅仅是一个文本编辑器和Web浏览器。下面这个简单的代码片段提供本书中所有示例的初始设置。以下是开发者将使用的一份基本的HTML5文件,在介绍完这些元素的结构后,为清晰起见,我们会做一些小的补充:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
window.onload = function () {
//Our code here...
};
</script>
</body>
</html>
将该文件另存为01-skeleton.html并在Web浏览器中打开它。因为这是一份空白的文件,所以在浏览器中你不会看到任何内容,不过该页面确实已载入并且它还是一份完全有效的HTML5文件(可以通过在浏览器中查看源代码确认网页中包含特定内容)。
现在逐步介绍文件中所涉及的每个元素。第一行只是简单地声明了本文件类型为HTML5。如果你接触过HTML4的各种文件类型的话,你会发现HTML5的声明是多么简单:
<!doctype html>
接下来,声明作为根节点的HTML元素以及header元素:
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
在head元素中,首先将文件的字符编码方式设置为utf-8。UTF-8是Unicode的一种编码方式,它是一种通用字符集,其中定义了世界上大多数语言所用到的字符。浏览器使用该编码方式读取文件中的字符并将它们以格式化的文本显示出来。这些文件以一系列的字节存储在某个服务器的文件中,它们通过网络传输,然后在用户的电脑上重新组装并显示在Web浏览器中。字符编码方式告诉浏览器如何将一系列字节转换为一串字符,这些字符经过处理并显示为一张网页。如果不在文件中声明编码格式,浏览器将试图(错误地)猜测文件的编码格式,或(错误地)使用一个默认的设置,而这可能导致页面显示出错。开发者最好在文件中显式指定字符编码格式以避免潜在的困惑。
所有有效的HTML5文件都包含一个也内嵌在header中的title元素,由于用到了CSS样式表,因此在实例中创建了一个指向外部文件的link元素。外部文件会包含文件中所用的样式定义,稍后再对style.css文件做进一步介绍。
在设置好header元素后,让我们来看看文件的剩余部分:
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
window.onload = function () {
//Our code here...
};
</script>
</body>
</html>
在body元素中放置了一个canvas元素。这是我们画动画以及脚本中将引用的地方。为了让我们可以在浏览器中看到它,这里为canvas设定了height与width,同时通过指定id,我们可以通过DOM接口访问该元素。
在canvas元素后,加入了一个script标签,其中将包含每个示例的JavaScript代码。为了确保不要在加载文件中其他元素前执行脚本,我们将script标签放在其他元素之后,末尾的body标签之前。这样做还有一个好处在于当脚本来自另一个文件,甚至有可能是另一个服务器上的文件时,可以避免等待下载该文件时无法并行加载文件的其他内容。这有助于加快加载速度和文件响应速度。
框架脚本非常简单并且实际上没做什么事情。window对象是Document Object Model(文件对象模型)中的顶层对象,通过它可以访问DOM。当文件加载完毕后,window对象会执行与之onload属性关联的函数。
<script>
window.onload = function () {
//Our code here...
};
</script>
本书中的示例代码将放置在window.onload的回调函数中。由于该方法在文件中的所有元素加载完成后才会执行,因此可以确保canvas元素在调用代码的时候可以正确访问。不过随之而来了的问题是如果文件中包含大量的内嵌数据,比如大图片,window.onload方法就不得不等待相当长得时间才能被执行到。此时,最好使用JavaScript加载那些耗时的资源,在第四章将会介绍如何做到这一点。
最终,随着我们关闭script、body以及html标签,一个基本但是完全有效的HTML5文件创建完毕。
2.2.4 CSS样式表
在文件的header元素中,创建了一个link指向CSS样式表。现在,让我们看看那个样式表文件。本书用到的样式定义刻意简化了,只声明了文件中body与canvas元素的背景色。canvas默认的背景色是透明的,这个颜色可能是你想要的,不过为了让你看清楚canvas元素在文件中的确切位置,把背景色改成了白色。下面是style.css文件的样式表定义:
body {
background-color: #bbb;
}
#canvas {
background-color: #fff;
}
这里假设文件中包含一个id为canvas的元素。样式表的复杂程度将随着文件的复杂程度而变化。HTML文件定义了文件的结构,CSS样式表则定义了元素的样式或外观。一般来说,最好将文件的内容、样式和脚本分布在不同的文件中。
2.2.5 额外的脚本
当示例变得更加复杂时,可能需要重用部分代码,此时为了更加清晰,将代码分离到不同的文件中则成为一种方便的做法。当新声明的类将用于多个练习时,当函数的繁杂实现会分散我们对当前话题的注意力时,我们会把它们放入另一个文件中。
在本书中,我们会将那些工具函数放在一个名为utils.js的文件加以维护。该脚本包含了为示例创建样板代码的函数,从而让我们更关注于本质的动画原理。因为我们会在引入每个函数的时候加以解释,所以这个脚本文件对你来说不会是一个黑盒子。
在该文件中,许多工具函数会作为属性添加到一个名为utils的JavaScript全局对象中。这样做可以避免在全局名称空间中堆满许多函数。为此,确保在utils.js文件中最开始的地方像下面这样声明一个空对象:
var utils = {};
为了把该文件或其他脚本导入文件中,需要创建一个script元素并设置它的src属性为脚本文件的地址。为了确保每个函数在试图使用前加载,请在示例代码前引入该元素:
<script src="utils.js"></script>
<script>
window.onload = function () {
//Our code here...
};
</script>
2.2.6 调试
编写代码的一个最重要的方面就是调试代码。在Web开发的早期,调试代码意味不断弹出警告窗口。值得庆幸的是,Web浏览器现在提供了越来越高级的调试工具用于代码审查和性能分析。因为这些工具使得你可以单步调试一个正在运行的程序并与之交互,所以你可以确切地了解代码在某一特定时刻在做什么。
可以肯定地说,每一个支持HTML5的浏览器都有内置的开发工具以及一个用于输入JavaScript语句并输出结果的控制台。你可能需要仔细查看应用程序的菜单,不过这些功能肯定存在于某个地方。
例如,在Chromium Web浏览器中,单击右上角的扳手图标,下拉至工具菜单项再单击JavaScript控制台。日志消息将输出在此窗口中。图2-1显示了一个在Chromium 浏览器中运行的调试会话。Firefox Web浏览器也有类似的功能:在“文件”菜单中,单击“工具”菜单,再选择“Web控制台”。IE9和Opera都有各自的开发环境。你最好能够轻松地使用这些主流浏览器中的工具,因为为了兼容各个浏览器,你需要在所有这些浏览器中调试代码。如果你无法找到这个浏览器的Web开发工具,请务必查看它们的帮助文件。
当打开一个Web开发者控制台后,可以直接在浏览器中输入JavaScript表达式并获得计算结果,试着输入以下代码:
console.log("Hello, World!");
2 + 2
在控制台中,还可以访问DOM元素以及脚本变量来查看它们的值(确保它们处在恰当的作用域中),这样可以方便地推算出程序运行的情况。通过这种方式,可以在将小段代码合并到一个大程序前更好地测试与调试它们,从而尽早地发现bug!