HTML5-视频操作手册-全-

HTML5 视频操作手册(全)

原文:zh.annas-archive.org/md5/E8CC40620B67F5E68B6D72199B86F6A9

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

HTML5 多媒体开发食谱将向您展示如何像专业人士一样使用最新的前端 Web 技术。您将了解 HTML5 与以往所有版本的量子飞跃差异以及其重要性。无论您是经验丰富的专业人士还是完全新手,本书都为您提供了下一步的路线图。

从 HTML5 的新特性概述开始,我们迅速转向实际示例。从那里,我们继续探索,一直到最前沿的实验。关于新的 HTML5 规范有很多要了解的地方。本书审查了规范摘录,并将其与当前使用的示例相关联。本书融合了丰富的理论、实用性、代码示例、屏幕截图、商业智慧和其他资源的链接,这将使热心的开发人员一次又一次地回到这本书中。HTML5 多媒体开发食谱是最新前端 Web 开发技术的必备指南。

这本书涵盖了什么

在第一章,为丰富媒体应用程序进行结构化,我们将通过分析浏览器支持来开始检查 HTML5 的就绪状态。然后我们将奠定如何成功使用 HTML5 的新元素的基础。

第二章,支持内容,让我们重新思考开发人员用来创建容纳各种类型内容的通用容器的方法。

第三章,使用 CSS 进行样式设置,演示了如何使用 CSS3 来支持 HTML5。我们还将看看现代与传统浏览器中的样式设置以及预期的效果。

第四章,创建可访问体验,不是典型的 508 节的重复。相反,我们将使用一些最新的技术来支持我们的在线体验。

第五章,学会喜爱表单,我们将仔细研究新的 HTML5 输入类型。还包括分析哪些浏览器支持每种新类型。

第六章,使用 Canvas 开发丰富媒体应用程序,是整本书中最具前瞻性的章节。讨论将集中在如何为这种新型交互开发,并包括一些令人惊讶的浏览器支持统计数据。

第七章,使用 JavaScript 进行交互,充满了扩展新的 HTML5 音频和视频元素的示例。为这个做好准备!

第八章,拥抱音频和视频,我们深入探讨核心的 HTML 音频和视频体验。我们将构建自己的播放器,同时支持可访问性。

第九章,数据存储,详细介绍了 HTML5 的一个独特方面以及如何使用它。示例包括使用 JSON、SQL 和 GeoLocation。

你需要为这本书做好准备

这本书的要求很简单:您真正需要的只是一台连接互联网的计算机、一个网络浏览器和一个代码编辑器。耐心和幽默感也不会有害。

这本书适合谁

HTML5 已成为最受欢迎的新工作关键词。无论您是在找新工作还是只是想在当前组织中迈出下一步,了解如何使用这项新技术将给您带来优势。

约定

在本书中,您将找到一些区分不同类型信息的文本样式。以下是一些这些样式的示例,以及它们的含义解释。

文本中的代码示例如下所示:“新的<header>通常用于存储诸如标志、公司口号和通常与骑头相关的其他类型的品牌。”

代码块设置如下:

<div id="search-form">
<form role="search" method="get" id="searchform" action="http://devinsheaven.com/" >
<div>
<label for="s">Search for:</label>
<input type="text" value="" name="s" id="s" />
<input type="submit" id="searchsubmit" value="Search" />
</div>
</form>
</div>

当我们希望引起您对代码块的特定部分的注意时,相关行或项目会以粗体显示:

<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav role="navigation">
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
</ul>
</nav>
</body>

新术语重要单词会以粗体显示。您在屏幕上看到的单词,比如菜单或对话框中的单词,会以这样的方式出现在文本中:“从 Vimeo 主菜单中选择工具 | 嵌入此视频。”

注意

警告或重要提示会显示在这样的框中。

提示

提示和技巧会显示为这样。

第一章:为丰富媒体应用程序进行结构化

在本章中,我们将涵盖:

  • 设置 HTML5 测试区域

  • 使用header标签来放置标志和网站标题

  • 使用nav标签创建目录

  • 使用section标签来结构化页面的区域

  • 使用aside标签对齐图形

  • 使用aside标签显示多个侧边栏

  • 实现footer标签

  • 应用outline算法

  • 在 HTML5 中创建时尚的推广页面

介绍

“谁敢,谁赢。”- 未知

不要听信那些否定者:HTML5 的许多方面已经准备就绪,等待我们使用。尽管一些人可能认为,没有一个遥远的日期可以开始使用这一系列新技术。事实上,下一代网络标记并不是遥远的梦想,它已经在这里,准备探索和使用。

没有网站可以在没有至少一些简单的超文本标记语言的情况下存在。这种开放技术非常重要。如果你多年来一直在使用 HTML 来创建和发布网站和应用程序,你可能会觉得自己现在已经掌握了这种语言。你已经知道语义标记、内容、表现和行为的分离以及无障碍问题的好处。事情可能会感到有点乏味。你已经准备好迎接新的挑战了。

或者你可能是一位年轻的开发者,正在建立你的第一个网站,需要了解如何使用最新和最伟大的技术,并对未来的网络开发有所了解。

无论哪种方式,你的道路是清晰的:在你现有的 HTML 和相关技术编码能力的基础上,这本书将推动你的技能到下一个水平,并迅速让你创造出以前 HTML 无法做到的惊人的东西。

如果你感到自满,请继续阅读。事实上,现在是成为网络开发人员最激动人心的时刻。更丰富的界面、互联网的普及以及移动设备的兴起正是你正在寻找的新挑战。

幸运的是,HTML5、大量的层叠样式表和一点 JavaScript 可以迎接这些新挑战。网络开发的最新创新使得这是在线出版商的新黄金时代。对于我们许多人来说,经历了一段低迷之后,我们现在迅速发现,为网络开发是有趣的!毕竟,HTML5 代表了进化,而不是革命。

在几个成功的知名客户项目中,我使用了一种自定义的 JavaScript 方法来部署 HTML5 的方面,并仍然支持包括微软 Internet Explorer 6 在内的旧版浏览器。

在这些食谱中,你将学习这种强大的方法以及如何在真实的、实时的生产环境中使用许多仍在发展中的 HTML5 标准和功能。

当我们使用 HTML5 开发时,我们将语义命名的基本原则(将事物命名为它们是什么,而不是它们看起来是什么)提升到一个全新的水平。这是使 HTML5 与其所有前身不同的关键因素。在本书的过程中,你会发现自己重新思考和优化许多你的代码命名约定。

尽管来自 Web 超文本应用技术工作组(WHATWG)的 HTML5 建议推荐计划要到 2022 年才全面实施,但由于前瞻性的浏览器制造商,现在就开始使用它并获得更好的语义命名、增强的可访问性等好处是完全没有问题的。

所以让我们开始吧!

在本章中,我们将向你展示如何设置你的开发环境,包括使用适当的DOCTYPE和要使用的浏览器,以及如何使用特定的新标签,包括:

  • <header> - 一组介绍性或导航性的辅助工具

  • <nav> - 用于导航列表

  • <section> - 用于区分页面的不同区域

  • <aside> - 用于对齐特定元素

  • <footer> - 页面或部分的底部信息

最后,我们将把所有这些元素放在一起,用 HTML5 创建一个时尚的专业宣传页面。

设置 HTML5 测试区域

如果我们要使用 HTML5 构建新的令人兴奋的项目,我们需要为成功做好准备。毕竟,我们希望确保我们构建的内容对我们自己和我们的客户来说能够以可预测的方式显示和行为。让我们用一个代码编辑器和至少一个网络浏览器来构建一个测试套件。

准备工作

我们需要一些东西才能开始。至少,我们都需要一个代码编辑器和一个浏览器来查看我们的工作。经验丰富的专业人士知道我们确实需要一系列反映我们受众使用情况的浏览器。我们想要以他们的方式看到事物。我们需要以他们的方式看到事物。

如何做...

许多网络开发人员说他们能够使用像 Notepad(适用于 Microsoft Windows)或 TextEdit(适用于 Mac OSX)这样的纯文本软件编写代码。这很好,但尽管有这样的吹嘘,我们不知道有哪个网络开发人员实际上每天都这样工作。

大多数人使用一些开发应用程序,比如 Adobe Dreamweaver(适用于 Windows 和 Mac)或 Aptana Studio(适用于 Windows、Mac 和 Linux)或 Coda(我个人偏好,只适用于 Mac)或 TextMate(同样只适用于 Mac)。

让我们开始下载至少一个这些应用程序:

这里显示了最常见的网络编辑器的应用程序图标:

如何做...

它是如何工作的...

为了让我们创建的代码正确显示,我们需要一个网络浏览器——可能不止一个。并非所有的浏览器都是一样的。正如我们将看到的,一些浏览器需要一些额外的帮助来显示一些 HTML5 标签。以下是我们至少会使用的浏览器。

如果你在 Mac 上使用 OSX,Apple Safari 已经安装。如果你是微软 Windows 用户,Internet Explorer 已经安装。

如果你使用 iPhone 或 Android 等现代移动设备进行开发,它已经安装了至少一个浏览器。

由于我们将在桌面上进行实际编码,让我们从以下位置下载一些浏览器开始。注意:Microsoft Internet Explorer 仅适用于 PC。

这里显示了最常见的桌面网络浏览器的应用程序图标:

它是如何工作的...

还有更多...

为什么我们需要不止一个浏览器?有两个原因:

  • 这些应用程序有不同的渲染引擎,并以稍微不同的方式解释我们的代码。这意味着无论我们的代码多么有效或出于良好意图,有时浏览器的行为是不可预测的。我们必须为此做好计划并保持灵活。

  • 我们无法总是预测我们的受众会安装哪个浏览器以及在哪个设备上,所以作为开发者,我们需要超前一步来最好地满足他们的需求以及我们自己的需求。

WebKit 渲染引擎

幸运的是,Safari 和 Chrome 使用相同的 WebKit 渲染引擎。iPhone 和 iPad 的移动 Safari,以及 Android 移动设备的网络浏览器,都使用 WebKit 渲染引擎的一个版本。

Gecko 渲染引擎

Firefox 及其移动版本都使用 Gecko 渲染引擎。

Trident 渲染引擎

我只是想告诉你我的感受。必须让你明白:微软已经多次改变和更新了它的 Internet Explorer 渲染引擎 Trident,这让我们作为开发人员的生活相当困难。我们经常感觉自己在瞄准一个移动的目标。随着 Internet Explorer 10 的到来,似乎这种情况不会很快改变。

另请参见

Camino(仅限 Mac)和 Opera(适用于 Microsoft Windows,Apple OSX,Linux 和移动设备)都是出色的替代浏览器,支持 HTML5 的许多功能。考虑将这些浏览器添加到您的测试套件中。

这里显示了 Camino 和 Opera 网页浏览器的应用程序图标:

另请参见测试区,HTML5Trident 渲染引擎

既然我们有了开发环境和不止一个浏览器,让我们创建一些代码吧!

提示

渐进增强

我们将使用渐进增强的概念构建我们的页面,这意味着从普通的 HTML 标记开始,然后添加 CSS 进行呈现,最后添加一点 JavaScript 进行行为。我们听到的最好的类比之一是,基本的 HTML 就像黑白电视。添加 CSS 就像添加颜色,添加 JavaScript 有点像添加高清。

使用标题标签用于标识和网站标题

<header>元素表示一组介绍性或导航性的辅助信息。<header>元素通常包含该部分的标题(<h1> - <h6>元素或<hgroup>元素),但这不是必需的。<header>元素还可以用于包装部分的目录、搜索表单或任何相关的标识。” - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备就绪

你会注意到 HTML5 的第一件事是DOCTYPE。如果你是网页开发的老手,你会很高兴地知道我们不再需要使用这样冗长复杂的DOCTYPE了:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

或者:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

或者:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

HTML5 消除了 Strict,Transitional 和 Frameset DOCTYPEs的需要。实际上,它完全消除了DOCTYPES的需要。没有DOCTYPES,较旧版本的 Internet Explorer 会进入 Quirks 模式,没有人想要那样。相反,我们可以使用简单的:

<!DOCTYPE html>

最后,一个DOCTYPE统治它们所有。

让我们从一个基本的页面结构开始,这是我们都应该熟悉的:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
</body>
</html>

引号是为了创建有效的 XHTML 而必需的,但由于 HTML5 不与 XML 耦合,这些在 HTML5 规范中是可选的。然而,作者建议尽可能使用引号引用属性。

敏锐的眼睛还会注意到<meta name="viewport" content="width=device-width, initial-scale=1.0">。目前它对我们来说还没有太大作用,但在移动设备上预览您的工作时将是至关重要的。

关闭标签也是可选的。虽然这是一个好习惯,但您应该权衡它是否值得开发时间和增加的页面权重。

你还会注意到一个条件注释,检查用户是否在使用 Internet Explorer。如果是的话,我们告诉浏览器执行 Remy Sharp 的"HTML5 Shiv"脚本,简单地告诉 IE 要表现良好:<article>, <aside>, <audio>, <canvas>, <command>, <datalist>, <details>, <embed>, <figcaption>, <figure>, <footer>, <header>, <hgroup>, <keygen>, <mark>, <meter>, <nav>, <output>, <progress>, <rp>, <ruby>, <section>, <source>, <summary>, <time>, <video>, <wbr>

该死的 Internet Explorer。它缺乏纪律。

如何做...

我们将为一位名叫 Roxane 的年轻开发人员创建一个单页专业网页作品集。假设 Roxane 是一位有才华的网页开发人员,就像你一样。她值得拥有一个与她的才华相称的专业单页作品集网站,你也一样。请随意在以下示例中用你的信息替换她的信息。

让我们首先使用第一个新的<header>标签来定义我们整个页面的最顶部区域。

顺便说一句,我们将在新的<header>标签中使用新的<hgroup>标签来包含标题。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
</body>
</html>

"<hgroup>元素表示一个部分的标题。当标题具有多个级别时,例如副标题、替代标题或标语时,该元素用于对一组<h1> - <h6>元素进行分组。" - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

工作原理...

新的<header>通常用于存储诸如标志、公司口号和通常与页眉相关的其他类型的品牌。它通常是 HTML5 页面上的第一个块级元素,并且通常用于像<h1>, <h2>等标题。结果是一个更具语义的代码基础,可以构建更多内容。

还有更多...

在 HTML5 之前,浏览器软件以及谷歌、雅虎和必应等主要搜索引擎都会给所有的<div>赋予相同的权重。但是我们知道,<div id="header">的意图并不像新的<header>那样明显。相反,HTML5 规范更倾向于用事物的实际名称来命名事物。现在,HTML5 认识到并不是所有的<div>都是一样的,它用更语义化的术语来替换一些<div>,比如新的<header><nav><footer>,以获得更多的数据丰富性。

在其他地方使用

有趣的是,页眉不是唯一可以使用新的<header>标签的地方。在 HTML5 中,将新的<header>标签放在几乎任何块级元素内也是完全可以接受的。

内容,而不是位置

新的<header>标签通常出现在网页顶部,但并不总是必须出现在那里。请记住,从语义上讲,新的<header>标签是由其内容而不是其位置来定义的。

语义化命名

语义化的命名也使我们作为网页开发人员的工作更加容易。像新的<footer>标签这样的东西的意图,如果像模糊的<div id="belowleft">那样标记,就会更加明显。

提示

语义化命名的关键

以事物的本质来命名,而不是它们的外观。

另请参阅

我们将继续参考 WHATWG 的 HTML5 草案标准,网址为whatwg.org/specs/web-apps/current-work/multipage,因为它是 HTML5 演变的重要指南。

使用 nav 标签创建目录

"<nav>元素表示一个导航部分,只有由主要导航块组成的部分才适合使用<nav>元素。" - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

就像新的<header>标签取代了过时的命名约定<div id="header">一样,我们也可以用简单的新的<nav>标签来取代<div id="nav">。这样更有意义,不是吗?我们也这么认为。

准备工作

我们将添加主要导航栏,就像我们经常在网页上看到的那样。这使用户可以轻松地从页面到页面,或者在这种情况下,从同一页面到另一页面。Roxane 想要展示她的个人简历信息、工作样本和联系方式,所以我们将使用这些作为我们的锚点。

如何做...

让我们使用两个最典型的元素来创建我们的导航栏:

  1. 一个无序列表

  2. 附带的超文本链接

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav>
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
<li><a href="#Contact">Contact</a></li>
</ul>
</nav>
</body>
</html>

工作原理...

以前,我们可能会使用类似<div id="nav">这样的东西来存储我们的导航列表。但是在 HTML5 中,新的<nav>标签就足够了。

当我们应用 CSS 时,我们会浮动这些列表项,并使它们看起来更像传统的网页导航栏。

还有更多...

更语义化地命名事物的美妙之处在于,现在我们页面的部分确实做到了我们认为它们应该做的事情——<header>包含标题信息,<nav>包含导航辅助信息,等等。避免混淆。

在其他地方使用<nav>

<header><nav>可以出现在页面的多个位置。

更语义化=更好

还要记住,更语义化的命名通常会导致更短、更精简的代码。毕竟,<nav>肯定比常见的<div id="nav">更短。而且对人类和机器来说更有意义。这意味着我们需要写的东西更少,这节省了我们的时间。这也意味着浏览器需要解释和显示的代码更少,这节省了下载和渲染时间。它还为内容赋予了意义和结构,类似于大纲为研究论文赋予了意义和结构。每个人都受益。

仍在发展

最初,新的<nav>元素只用于“主要”导航块。然而,HTML5 的主要推动者 Ian Hickson 更新了规范,改为“重要”导航块。

另请参阅

由于它仍在不断发展,鼓励您为 HTML5 的发展做出贡献,帮助塑造这种语言。加入 WHATWG 的<help@whatwg.org>邮件列表,提出建议和提问。注册说明请参见:whatwg.org/mailing-list#help

使用 section 标签来结构化页面的区域

<section>元素表示一个通用的文档内容块或应用程序块。在这种情况下,<section>是内容的主题分组,通常带有一个标题。”- WHATWG 的 HTML5 草案标准 - http://whatwg.org/html5

准备工作

让我们为 Roxane 的单页面作品集网站的每个主要区域添加新的<section>标签。这些<section>将被用作容器,每个都有一个标题和通用内容,其中包含她的个人简介信息、作品示例和联系方式。

如何做...

使用新的<section>标签可能会有些棘手。有一些它不是的东西,但只有一些它是的东西。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav>
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
<li><a href="#Contact">Contact</a></li>
</ul>
</nav>
<section id="About">
<h3>About</h3>
<p>I'm a front-end developer who's really passionate about making ideas into simply dashing websites.</p>
<p>I love practical, clean design, web standards give me joyful chills, and good usability tickles the butterflies in my stomach.</p>
</section>
<section id="Work">
<h3>Work</h3>
<p>sample 1</p>
<p>sample 2</p>
<p>sample 3</p>
</section>
<section id="Contact">
<h3>Contact</h3>
<p>email</p>
<p>phone</p>
<p>address</p>
</section>
</body>
</html>

如何做...

我们使用新的<section>标签不是作为<div>的通用替代,而是以语义上正确的方式作为一个相关的分组,通常包含一个标题。

还有更多...

如果内容分组没有关联,那么它可能不应该是一个<section>。考虑使用<div>代替。

Section 不等于 div

记住:如果没有<header>,那可能就不需要<section>。使用<section>对内容进行分组,但对于纯粹出于样式原因对项目进行分组时使用<div>

部分指南

仍然不确定是否使用<section>是正确的标签?请记住以下准则:

  • 您是单纯用于样式或脚本吗?那就是一个<div>

  • 如果有其他更合适的标签,请使用它。

  • 只有在内容开头有一个标题时才使用它。

仍在发展

HTML5 是一个不断发展的标准集。WHATWG 最新的指导建议:

“鼓励作者在有意义地对元素的内容进行合成时,使用<article>元素而不是<section>元素。”

发布关于页面?那可能是一个很好的<section>候选。

另请参阅

新的<section>标签也可以支持引用属性以进行引用。

使用 aside 标签对齐图形

<aside>元素表示页面的一个部分,其中包含与<aside>元素周围的内容有间接关系的内容,并且可以被视为与该内容分开。”- WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备工作

让我们以一种常见的方式使用新的<aside>标签:创建一个侧边栏,其中列出了 Roxane 最近阅读的缩略图图像。

如何做...

在过去,我们将图像或列表浮动到文本的右侧或左侧。这仍然有效,但现在我们可以更好地利用 HTML5 中改进的语义,通过使用新的<aside>标签来实现类似的视觉效果。让我们使用:

  • 有序列表

  • 缩略图

  • 书名

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav>
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
<li><a href="#Contact">Contact</a></li>
</ul>
</nav>
<section id="About">
<h3>About</h3>
<p>I'm a front-end developer who's really passionate about making ideas into simply dashing websites.</p>
<p>I love practical, clean design, web standards give me joyful chills, and good usability tickles the butterflies in my stomach.</p>
</section>
<section id="Work">
<h3>Work</h3>
<p>sample 1</p>
<p>sample 2</p>
<p>sample 3</p>
</section>
<section id="Contact">
<h3>Contact</h3>
<p>email</p>
<p>phone</p>
<p>address</p>
</section>
<aside>
<h4>What I'm Reading</h4>
<ul>
<li><img src="img/2688OS_MockupCover.jpg" alt="Inkscape 0.48 Essentials for Web Designers"> Inkscape 0.48 Essentials for Web Designers</li>
<li><img src="img/0042_MockupCover_0.jpg" alt="jQuery 1.4 Reference Guide"> jQuery 1.4 Reference Guide</li>
<li><img src="img/9881OS_MockupCover.jpg" alt="Blender 2.5 Lighting and Rendering"> Blender 2.5 Lighting and Rendering</li>
<li><img src="img/9881OS_MockupCover.jpg" alt="Blender 2.5 Lighting and Rendering"> Blender 2.5 Lighting and Rendering</li>
</ul>
</aside>
</body>
</html>

注意:在这种情况下,ALT 标签周围需要引号以确保有效性。

它是如何工作的...

<aside>标签有效地用于放置诸如图像和文本之类的项目,这些项目通常比主要页面内容不太重要。

还有更多...

从语义上讲,<aside>类似于侧边栏。这并不一定指的是位置,而是指与内容有关的内容。

并非所有的
都是一样的

虽然<section>是一块相关内容,但是将<header>, <nav>, <footer><aside>视为<section>的专门类型。

记住的提示

内容可以在没有<aside>标签的情况下存在,但<aside>标签不能没有内容。

除了<aside>之外

<aside>标签的定义已经扩展,不仅包括与其相关的<article>的信息,还包括与网站本身相关的信息,如博客列表。

另请参阅

Jeremy Keith 撰写了出色的《HTML5 For Web Designers》,被认为是您需要了解新技术的最少知识。在这里找到它:books.alistapart.com/products/html5-for-web-designers

使用<aside>标签显示多个侧边栏

"<aside>元素代表页面的一部分,其中包含与<aside>元素周围的内容有关的内容,可以被视为与该内容分开的内容。" - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备工作

似乎每个博客和许多其他类型的网站都有侧边栏,其中包含各种信息。在这里,我们将使用新的<aside>标签为 Roxane 的单页面作品集网站添加一个额外的侧边栏。

如何做...

Roxane 想让人们知道她还可以在哪里联系到她,你也是。让我们使用<aside>标签创建一个侧边栏,并吸引人们关注她的网站:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav>
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
<li><a href="#Contact">Contact</a></li>
</ul>
</nav>
<section id="About">
<h3>About</h3>
<p>I'm a front-end developer who's really passionate about making ideas into simply dashing websites.</p>
<p>I love practical, clean design, web standards give me joyful chills, and good usability tickles the butterflies in my stomach.</p>
</section>
<section id="Work">
<h3>Work</h3>
<p>sample 1</p>
<p>sample 2</p>
<p>sample 3</p>
</section>
<section id="Contact">
<h3>Contact</h3>
<p>email</p>
<p>phone</p>
<p>address</p>
</section>
<aside>
<h4>What I'm Reading</h4>
<ul>
<li><img src="img/2688OS_MockupCover.jpg" alt="Inkscape 0.48 Essentials for Web Designers"> Inkscape 0.48 Essentials for Web Designers</li>
<li><img src="img/0042_MockupCover_0.jpg" alt="jQuery 1.4 Reference Guide"> jQuery 1.4 Reference Guide</li>
<li><img src="img/9881OS_MockupCover.jpg" alt="Blender 2.5 Lighting and Rendering"> Blender 2.5 Lighting and Rendering</li>
</ul>
</aside>
<aside>
<h4>Elsewhere</h4>
<p>You can also find me at:</p>
<ul>
<li><a href="http://linkedin.com/in/">LinkedIn</a></li>
<li><a href="http://twitter.com/">Twitter</a></li>
<li><a href="http://facebook.com/">Facebook</a></li>
</ul>
</aside>
</body>
</html>

它是如何工作的...

在我们之前成功使用<aside>标签的基础上,我们再次使用它来对齐主要信息之后的信息。

还有更多...

只是因为设计需要侧边栏,并不意味着自动使用<aside>标签。在考虑位置之前,请仔细考虑您的内容。

引用适合<aside>

引用在新闻文章中很常见,因此是包含在<aside>标签中的主要候选项。

记住验证

我们需要在这些锚点周围添加引号以使它们有效。

另请参阅

Bruce Lawson 和 Remy Sharp 共同撰写了出色的Introducing HTML5参考资料,网址为:peachpit.com/store/product.aspx?isbn=0321687299

实施页脚标签

"<footer>元素代表已完成文档或其最近祖先分段内容的页脚。" - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备工作

我们都在网页上使用页脚 - 通常用于次要导航等。这包含了通常在页面底部看到的所有信息,如版权声明、隐私政策、使用条款等。与新的<header>标签一样,新的<footer>标签可以出现在多个位置。

如何做...

在这种情况下,我们将使用新的<footer>标签将 Roxane 的版权信息放在页面底部。

提示

这是一个可以增长的

记住:版权并不意味着您有权复制它!

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav>
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
<li><a href="#Contact">Contact</a></li>
</ul>
</nav>
<section id="About">
<h3>About</h3>
<p>I'm a front-end developer who's really passionate about making ideas into simply dashing websites.</p>
<p>I love practical, clean design, web standards give me joyful chills, and good usability tickles the butterflies in my stomach.</p>
</section>
<section id="Work">
<h3>Work</h3>
<p>sample 1</p>
<p>sample 2</p>
<p>sample 3</p>
</section>
<section id="Contact">
<h3>Contact</h3>
<p>email</p>
<p>phone</p>
<p>address</p>
</section>
<aside>
<h4>What I'm Reading</h4>
<ul>
<li><img src="img/2688OS_MockupCover.jpg" alt="Inkscape 0.48 Essentials for Web Designers"> Inkscape 0.48 Essentials for Web Designers</li>
<li><img src="img/0042_MockupCover_0.jpg" alt="jQuery 1.4 Reference Guide"> jQuery 1.4 Reference Guide</li>
<li><img src="img/9881OS_MockupCover.jpg" alt="Blender 2.5 Lighting and Rendering"> Blender 2.5 Lighting and Rendering</li>
<footer> tagimplementing</ul>
</aside>
<aside>
<h4>Elsewhere</h4>
<p>You can also find me at:</p>
<ul>
<li><a href="http://linkedin.com/in/">LinkedIn</a></li>
<li><a href="http://twitter.com/">Twitter</a></li>
<li><a href="http://facebook.com/">Facebook</a></li>
</ul>
</aside>
<footer>
<h5>All rights reserved. Copyright Roxane.</h5>
</footer>
</body>
</html>

它是如何工作的...

尽管这个<footer>位于 Roxane 的单页面作品集网站的底部,但它也可以在页面的其他位置使用,比如放在<section>标签的底部,用来包含作者、发布日期等信息。这样做比以前的<div id="footer">更灵活。在这种情况和许多其他情况下,HTML5 的新标签允许我们根据内容而不是布局的需要来放置适当的标签。

还有更多...

HTML5 规范建议作者信息包含在新的<footer>标签中,无论<footer><section><article>的一部分,甚至在页面底部都是如此。

这通常发生

绝大多数情况下,您会在文档顶部使用<header>标签,在底部使用<footer>标签,在侧边使用<aside>标签。

灵活的页脚内容

<footer>元素包含整个部分时,它们代表附录、索引、长的版权声明、冗长的许可协议等内容。

更灵活的页脚内容

新的<footer>标签也可以包含作者归属、相关文档的链接、版权等信息。

另请参阅

Mark Pilgrim 创建了一个很棒的免费在线 HTML5 参考资料Dive Into HTML5,网址是:diveintohtml5.org

应用大纲算法

幸运的是,HTML5 现在可以在浏览器中组装页面的大纲,因此搜索引擎以及辅助技术可以更好地理解它们。我们将使用 HTML5 大纲工具:gsnedders.html5.org/outliner

准备就绪

要使用 HTML5 大纲工具,我们可以使用存储在本地计算机上的 HTML 或通过 URL 可见的代码。确保在本地保存我们一直在创建的代码,或者将其上传到一个公共可访问的 Web 服务器以进行此步骤。

如何做...

让我们确保将此文档保存在本地硬盘或远程服务器上。我们将访问gsnedders.html5.org/outliner来创建我们的大纲。

使用我们之前的代码示例,我们可以生成以下代码大纲:

  1. Roxane 是我的名字。

  2. 无标题部分

  3. 关于

  4. 工作

  5. 联系方式

  6. 我在读什么

  7. 其他地方

  8. 保留所有权。版权 Roxane。

它是如何工作的...

"它是根据 DOM 树的节点遍历来定义的,按照树的顺序,每个节点在遍历期间被访问时都会被进入退出。" - WHATWG

还有更多...

假设任何标题后面的内容都与该标题相关。因此,我们可以使用许多新的 HTML5 标签,如<section>,明确地展示相关内容的开始和结束。

你确定吗?

如果 HTML5 大纲工具显示"无标题部分"之类的消息,您应该重新考虑如何使用每个标签,并确保您的方法符合规范的意图。

一个例外

"无标题部分"的消息应该被视为警告而不是错误。虽然<section>和其他新的 HTML5 标签需要一个标题标签,但在<nav>区域没有标题标签也是完全有效的。

记住辅助功能

创建的大纲确保我们创建的代码符合 W3C 的标记标准,以及 WAI-ARIA 等辅助需求的高级技术。

提示

良好的辅助功能设计是良好的网页设计。

另请参阅

html5doctor.com网站是一个由七位思想领袖撰写的出色的互动参考资料,包括 Rich Clark、Bruce Lawson、Jack Osborne、Mike Robinson、Remy Sharp、Tom Leadbetter 和 Oli Studholme。

在 HTML5 中创建时尚的推广页面

我们的朋友 Roxane 的单页面作品集网站已经使用了许多新的 HTML5 元素。她准备向世界展示她是一位有远见的网页开发人员,准备应对高级项目。

准备就绪

我们已经通过组装单页面作品集网站的大部分内容做好了准备。虽然现在还不太时尚,但当我们在其上添加 CSS 时,这将真正地融合在一起,并且会变得和我们的想象一样时尚。

如何做到这一点...

到目前为止,这是我们拥有的代码。它符合万维网联盟的 HTML5 和第 508 条款的可访问性测试。这个未经样式化的代码应该可以在任何现代 Web 浏览器上轻松查看,无论是在桌面上还是移动设备上。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav>
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
<li><a href="#Contact">Contact</a></li>
</ul>
</nav>
<section id="About">
<h3>About</h3>
<p>I'm a front-end developer who's really passionate about making ideas into simply dashing websites.</p>
<p>I love practical, clean design, web standards give me joyful chills, and good usability tickles the butterflies in my stomach.</p>
</section>
<section id="Work">
<h3>Work</h3>
<p>sample 1</p>
<p>sample 2</p>
<p>sample 3</p>
</section>
<section id="Contact">
<h3>Contact</h3>
<p>email</p>
<p>phone</p>
<p>address</p>
</section>
<aside>
<h4>What I'm Reading</h4>
<ul>
<li><img src="img/2688OS_MockupCover.jpg" alt="Inkscape 0.48 Essentials for Web Designers"> Inkscape 0.48 Essentials for Web Designers</li>
<li><img src="img/0042_MockupCover_0.jpg" alt="jQuery 1.4 Reference Guide"> jQuery 1.4 Reference Guide</li>
<li><img src="img/9881OS_MockupCover.jpg" alt="Blender 2.5 Lighting and Rendering"> Blender 2.5 Lighting and Rendering</li>
</ul>
</aside>
<aside>
<h4>Elsewhere</h4>
<p>You can also find me at:</p>
<ul>
<li><a href="http://linkedin.com/in/">LinkedIn</a></li>
<li><a href="http://twitter.com/">Twitter</a></li>
<li><a href="http://facebook.com/">Facebook</a></li>
</ul>
</aside>
<footer>
<h5>All rights reserved. Copyright Roxane.</h5>
</footer>
</body>
</html>

它是如何工作的...

对于开发人员或设计师来说,单页面作品集网站非常合理,因为所有信息都可以快速地展示给招聘职位的人员,比如人力资源团队或招聘人员。

还有更多...

这正是 Roxane 需要展示她是一个有远见的开发人员,学会运用下一代 Web 标准的专业单页面作品集网站。

尝试不使用 shiv

作为一个实验,在代码中关闭“HTML5 Shiv”JavaScript 引用,看看各个版本的 Internet Explorer 如何处理我们的新 HTML5 标签。

移动优先

在创建这个和其他网站时,请记得考虑移动显示。几乎没有理由阻止整个群体的人看到您的内容。

IE 邪恶?

在过去的 15 年左右,我们花了很多时间和精力抨击微软的 Internet Explorer,因为它缺乏标准支持,对盒模型的解释也有 bug。即将推出的 IE10 使我们更接近一个更统一的 Web 开发世界,但我们仍然需要数年的时间才能摆脱对 IE 的诅咒。

另请参阅

要获取大量单页面作品集和其他网站的灵感,请访问onepagelove.com画廊。

未经样式化的单页面作品集在大多数主流现代桌面 Web 浏览器上的显示:

另请参阅

第二章:支持内容

在本章中,我们将涵盖:

  • 构建博客article

  • 使用mark元素突出显示文本

  • 使用time元素

  • 指定articlepubdate

  • 使用article元素显示评论块

  • 使用@font-face 动态添加字体

  • 向字体添加阴影效果

  • 对字体应用渐变效果

  • 使用figure标签注释视觉元素

介绍

“在网络上,一个人不应该被他的肤色所判断,而应该被他的内容所判断。”- 互联网迷因

HTML5 和以往所有版本的 HTML 之间最重要的区别之一是,在以前,我们构建了通用的<div>和其他这样的通用容器,而对其中的内容知之甚少。随着 HTML5 的出现,这一切都结束了。为了根据规范语义化地正确,我们需要知道内容是什么,这样我们才能用最合适的新元素标签将其包裹起来。虽然这可能意味着我们开发者需要以不同的方式思考,但新的挑战正是我们在这里的原因。在本章中,我们将通过使用 HTML5 的几个新元素来看一些例子,来看如何做到这一点。

“在冲突的情况下,考虑用户优先于作者优先于实施者优先于规范制定者优先于理论纯度。”- 代表团的优先级

在本章中,我们将向您展示如何使用新的<article>元素来标记博客文章和评论,向<article>添加有意义的发布日期,使用新的<mark>元素来突出显示文本,以及如何使用新的<figure>元素注释视觉元素。然后,我们将转向一些使用字体替换技术对文本进行新样式处理的方法,以及向文本添加阴影和渐变。

构建博客文章

<article>元素代表文档、页面、应用程序或站点中的一个独立的组成部分,原则上是独立可分发或可重用的,例如在联合中。这可以是一个论坛帖子,一篇杂志或报纸文章,一篇博客条目,一个用户提交的评论,一个交互式小部件或小工具,或任何其他独立的内容项。”- WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备就绪

博客条目是新的<article>元素的完美候选对象,它专为联合内容而设计。

对于这个配方,让我们从识别博客<article>的主要元素开始:通常有一个标题,以标题标签的形式,博客条目本身包括几个段落,也许还有一个或多个图片,通常还包括作者的姓名和其他相关的元数据。请注意,这是所有自包含的相关内容。

如何做...

我们将继续使用新的 HTML5<header><footer>元素。标题、条目和元信息应该分别包含在它们自己独特的标签中,比如<h2>、多个<p>和新的<footer>

让我们从一个与上一章非常相似的基础开始,并两次添加我们的新<article>元素:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog Title</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<article>
<header>
<h2>Headline</h2>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
<article>
<header>
<h2>Headline</h2>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
</body>
</html>

让你的代码减肥?

准备好受惊吓了吗?想要大开眼界吗?在 HTML5 规范中,<html><head><body>标签(以及它们的闭合标签)现在是可选的。当然,你可以把它们留在那里,你的页面也会验证通过,但为什么我们要这样做呢?如果从之前的代码中移除它们,我们就得到了简约的:

<!DOCTYPE html>
<meta charset="UTF-8">
<title>Blog Title</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<article>
<header>
<h2>Headline</h2>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
<article>
<header>
<h2>Headline</h2>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>

不相信?将该代码通过万维网联盟的验证器运行:validator.w3.org,你会看到它在浏览器中正确显示。

好吧,别那么快。问题在于删除这些元素会破坏我们的屏幕阅读器代码。哦哦。第一次打击。此外,删除<body>标签会破坏我们为 Internet Explorer 启用的新 HTML5 JavaScript。第二次打击。你猜怎么着?你能看到它来了,对吧?是的,删除<html>标签会删除页面的语言。就是这样:第三次打击。

那么,让我们把这些元素加回去,好吗?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog Title</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<article>
<header>
<h2>Headline</h2>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
<article>
<header>
<h2>Headline</h2>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
</body>
</html>

好了,这样就好多了。

它是如何工作的...

记住,新的<article>元素是一个相关信息的集合,旨在通过 RSS 或其他方式进行合成。

还有更多...

更丰富、更有意义的语义可能是 HTML5 最重要的目标。这对机器更好,对作者更好,最重要的是,对我们的观众更好。

验证作为一种辅助,而不是一种支撑

正如我们之前看到的,删除<html><head><body>标签会呈现一个仍然有效的页面。这就引出了验证器的有效性问题。与 XML 世界不同,HTML5 可以使用不正确的语法,但仍然可以正常呈现。

作者在可能的情况下会尽力验证他的代码。不必对验证器盲目追求,但这总是一个很好的质量控制检查。而且,您的代码越接近有效,浏览器显示您的工作的机会就越大。

Eric Meyer 的有趣之处

作者喜欢 CSS 大师 Eric Meyer 对验证器的看法:

Eric Meyer 的有趣之处

在哪里找到验证器

您可以在以下位置充分利用代码验证器:

另请参阅

Kristina Halvorson 的书《网络内容策略》(contentstrategy.com)自发布以来就成为了经典之作。在这本书中,明尼阿波利斯公司 Brain Traffic 的首席执行官 Halvorson 清楚地定义了如何为在线观众创建和提供有用和可用的内容的过程。

使用标记元素突出显示文本

<mark>元素代表文档中标记或突出显示的一段文本,用于参考目的,因为它在另一个上下文中具有相关性。当在引文或其他文本块中使用时,它表示原本不存在的但已经添加以引起读者注意的突出显示,这在原始作者编写文本块时可能并未被认为重要,但现在却受到了以前意想不到的审查。当在文档的主要文本中使用时,它表示由于其可能与用户当前活动相关而被突出显示的文档的一部分。”- WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备就绪

在查看搜索结果时,您经常会发现您搜索的术语被突出显示。我们现在可以使用更有意义的<mark>元素,而不是依赖于语义上毫无意义的标签。

如何做...

在这个示例中,您将看到HTML5doctor.com有一个如何使用新的<mark>元素突出显示搜索结果术语的示例。这不仅为样式提供了有用的语义钩子,也为跟踪结果的机器提供了语义钩子。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>716,000,000 search results for the query "<mark>HTML5</mark>"</h1>
<section id="search-results">
<article>
<h2><a href="http://en.wikipedia.org/wiki/HTML_5"> <mark>HTML5</mark> - Wikipedia, the free encyclopedia</a></h2>
<p><mark>HTML5</mark> is the next major revision of <mark>HTML</mark> ("hypertext markup language"), the core markup language of the World Wide Web. The WHATWG started work on the ... <a href="http://en.wikipedia.org/wiki/HTML_5"> Read more</a></p>
</article>
<article>
<h2><a href="http://dev.w3.org/html5/spec/Overview.html"> <mark>HTML5</mark></a></h2>
<p>A vocabulary and associated APIs for <mark>HTML</mark> and XHTML. Editor's Draft 16 August 2009\. Latest Published Version: http://w3.org/TR/<mark>html5</mark>/; Latest Editor's ... <a href="http://dev.w3.org/html5/spec/Overview.html"> Read more</a></p>
</article>
</section>
</body>
</html>

添加一个简单的样式声明,比如:

<style type="text/css">
mark {background-color: yellow; font-weight: bold;}
</style>

<head>部分帮助我们呈现这些突出显示的文本:

如何做...

它是如何工作的...

新的<mark>元素只是简单地突出显示一个词或短语,以吸引读者的注意。要做到这一点,只需在相应的层叠样式表中指定<mark>为粗体、斜体或以某种方式突出显示。

还有更多...

当然,您可以标记和样式搜索结果页面,使用<b><i>甚至<span>标签来指示搜索是为哪个术语进行的,但是这些标签只影响呈现层。它们缺乏含义。新的<mark>元素可以实现相同的视觉效果,同时为您的标记添加额外的含义。事实上,新的<mark>元素非常有用。

长寿繁荣

新的<mark>元素的另一个很好的用途是突出显示日历选择器中的日期,正如我们经常在任何基于日期的预订系统网站上看到的Priceline.com

Priceline.com在预订行程时默认突出显示当前日期。与使用语义上毫无意义的标签来实现这一点不同,新的<mark>元素可能是一个完美的选择。

长寿繁荣

等待浏览器

在撰写本文时,新的<mark>元素尚未得到任何网络浏览器的全面支持。尽管额外的语义含义可能对机器读者来说并不明显,我们仍然可以将新的<mark>元素作为样式上的“钩子”使用,直到有一天它的含义得到各种浏览器的全面支持。

“未来证明”是一个词吗?

请记住,HTML5 的新元素试图为我们的标记添加额外的含义。目标绝不是剥夺含义或破坏页面。有了这个想法,我们就更容易接受像新的<mark>元素这样的尚未被浏览器完全实现的新元素。即使它的含义机器尚未完全理解,将其添加到我们的页面中并使其“未来证明”绝对不会有害。

另请参阅

2001 年,Carrie Bickner 为纽约公共图书馆的分支机构准备了“纽约公共图书馆在线样式指南”(legacy.www.nypl.org/styleguide),用于更新他们的网站。在这本开创性的出版物中,Bickner 通过将内容(标记)、呈现(层叠样式表)和行为(JavaScript)分开,为 Web 标准提出了理由。这本出版物在当时非常具有前瞻性,并且在许多年内都在使用中。

使用时间元素

"<time>元素表示 24 小时制的时间,或者是普通公历日历中的精确日期,可选地包括时间和时区偏移。" - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备就绪

新的<time>元素是显示时间或特定日期的强大方式。

如何做到...

在这个示例中,我们将显示对人类和机器都可读的日期和时间。让我们看看四个例子。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<article>
<header>
<h2>Headline</h2>
<time datetime="2010-11-29">November 29, 2010</time>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
<article>
<header>
<h2>Headline</h2>
<time datetime="2010-11-29">Nov. 29</time>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
<article>
<header>
<h2>Headline</h2>
<time datetime="2010-11-29">the date this was written</time>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
<article>
<header>
<h2>Headline</h2>
<time datetime="2010-11-29T11:34">the date and time this was written</time>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer>Meta information.</footer>
</article>
</body>
</html>

它是如何工作的...

我们可以使用新的<time>元素来指示特定的日期、时间或两者兼而有之。

还有更多...

新的<time>元素指定了一个确切的时间点,而不是一个时间段。

奇怪的规则

新的<time>元素的一个有趣方面是,您不能使用公元前的日期。您也不能使用像“2010 年 11 月”这样的日期。我们指定的日期必须是一个正的、具体的日期,而不是一个相对的日期。HTML5 工作组继续解决这一看似武断的限制。

浏览器显示新的<time>元素,但目前并没有对其进行任何特殊处理。

永远记住 SEO

时间。我们为什么如此着迷?在网络上关注时间和日期的一个非常有效的原因是搜索引擎优化。SEO 曾经被视为一种只有黑帽巫师才能理解的神秘巫术,现在已经成为每个人在网上的责任。您花时间编写良好的代码,并期望作者创作值得阅读的内容。现在再进一步,确保您的目标受众实际上可以找到您花时间创建的内容。新的<time>元素只是搜索引擎吸引注意力到最新内容的方式之一。

另请参阅

新的 HTML5<time>元素是微格式运动的一个可能的补充。微格式承诺为我们的标记添加额外的语义含义。虽然它还不是官方标准,但微格式正在逐渐得到 Web 开发社区的接受。在Microformats.org了解更多。

指定文章的发布日期

"pubdate属性是一个布尔属性。如果指定了,它表示元素给出的日期和时间是最近祖先<article>元素的发布日期和时间,或者,如果元素没有祖先<article>元素,则是整个文档的发布日期和时间。" - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备好了

当新的<time>元素存在于新的<article>元素中时,新的pubdate是新的<time>元素的属性。它允许我们在呈现发布日期和时间时更加精确。

如何做...

在这个配方中,我们将在上一个配方中介绍的新的<time>元素的基础上,添加新的可选的pubdate属性来显示我们的发布日期。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<article>
<header>
<h2>Headline</h2>
<p>Published on <time datetime="2010-11-29" pubdate> November 29, 2010</time> in the something category.</p>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer></footer>
</article>
<article>
<header>
<h2>Headline</h2>
<p>Published on <time datetime="2010-11-28" pubdate> November 28, 2010</time> in the something category.</p>
</header>
<p>First paragraph</p>
<p>Second paragraph</p>
<footer></footer>
</article>
</body>
</html>

它是如何工作的...

Pubdate只是一个二进制变量,或者布尔属性,用来表示某事的发布时间。

还有更多...

您可以将pubdate视为向已经提供额外信息的元素(<time>)添加额外信息。这就像圣代上的樱桃。谁不喜欢圣代上的樱桃呢?

仍在等待浏览器

通过包括新元素<mark>, <time>pubdate,我们正在变得非常前瞻性,因为没有一个浏览器完全支持它们 - 但是

仍在等待浏览器

像 Firefox 这样的现代浏览器可以原生显示新的<time>元素和pubdate属性,无需样式。

额外学分

如果您想符合 XML 语法,可以将新的pubdate布尔属性编码为<time datetime="2010-11-29" pubdate="pubdate">

让我们结束混淆

尽管 HTML5 仍然很新,但对于新的pubdate布尔属性已经存在一些混淆。有些人认为它应该根据您的计算机时钟或服务器生成发布日期。这不是它的作用。它的作用是生成一个机器可读的发布日期,无论您在其后放置什么文本,都是有用的。

参见

Tantek Celik 在favelets.com创建了一个非常有用的网站,其中包含各种"书签"或浏览器 JavaScript 命令。使用这些命令可以在同一个窗口中验证 HTML5、CSS 和锚点等。非常有帮助!

使用文章元素显示评论块

"<article>元素表示文档、页面、应用程序或站点中的独立组成部分,原则上是独立可分发或可重用的,例如在联合传播中。这可以是论坛帖子、杂志或报纸文章、博客条目、用户提交的评论、交互式小部件或小工具,或任何其他独立的内容项。" - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备好了

我们当然可以提出使用新的<article>元素来标记博客评论的理由。在这个配方中,我们将这样做。

如何做...

让我们使用新的<article>元素来标记一块博客评论。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<article>
<header>
<h3>Comment by: <a href="http://dalejcruse.com">Dale J Cruse</a></h3>
<p>On <time datetime="2010-11-29">November 29, 2010</time></p>
</header>
<p>The is the first paragraph of my comment</p>
<p>The is the second paragraph of my comment</p>
<footer>
<p><small>Creative Commons Attribution-ShareAlike License</small></p>
</footer>
</article>
<article>
<header>
<article element> usedsteps<h3>Comment by: <a href="http://dalejcruse.com">Dale J Cruse</a></h3>
<p>On <time datetime="2010-11-29">November 29, 2010</time></p>
</header>
<p>The is the first paragraph of my comment</p>
<p>The is the second paragraph of my comment</p>
<footer>
<p><small>Creative Commons Attribution-ShareAlike License</small></p>
</footer>
</article>
</body>
</html>

它是如何工作的...

"等一下,"你在想。"一个博客评论不是一个<article>!"你大喊道。别那么快,伙计。如果我们分析一下博客评论的组成部分,我们会发现与其他<article>相同的元素。

还有更多...

顺便说一句,让我们看看以前的<footer>中的新<small>元素。以前,<small>是一个表示小号文本的表现元素。不再是这样了!现在<small>已经重新定义为这样使用:

<small>元素代表所谓的‘小字体’,如法律声明和警告。” - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

博客评论

由于博客评论及其评论源可以用于联合,更有理由使用新的<article>元素。

值得注意的是

评论。几乎每个值得一读的博客都有评论。无论是我们自己的网站还是我们自己的博客内容管理系统,我们都应该像对待博客文章本身一样细心对待评论的代码。

机会在你手中

Disqus.com是最广泛使用的博客评论插件的在线主页。发布者可以轻松地将其整合到他们的网站中,而无需太多编程工作。那么,这对我们意味着什么呢?无论您使用 Disqus 还是其他任何评论系统,都需要有人开发那些代码,对吧?那么最好是你自己!

另请参阅

Josh Duck 创建了巧妙而有用的 HTML5 元素周期表,网址是:joshduck.com/periodic-table.html。在那里,Josh 巧妙地将类似的新元素分组,如根元素、文本级语义、文档部分等等!

使用@font-face 动态添加字体

不久以前,我们设计师和开发人员只能选择少数“网页安全”字体来显示文本。如果我们想要以不被认为“安全”的字体显示文本,我们就会将其制作成图片。这很愚蠢,但我们别无选择。现在我们有了选择。字体终于在网页上得到了解放。

良好的排版对于任何设计都是必不可少的,而新的@font-face 功能让我们嵌入字体供浏览器使用。虽然技术上不属于 HTML5 的一部分,但这个 CSS3 属性太重要了,不容忽视。

做好准备

对于这个配方,让我们找一个有趣的字体,并将其嵌入为一个简单的标志。下面是一些寻找免费和付费字体的好网站的链接。例如,让我们看看作者个人作品集的早期版本,网址是dalejcruse.com

如何做...

在网页上显示自定义字体有几种方法,但我们将检查并使用一种能够在现代、传统甚至移动浏览器中运行的可靠方法。

让我们前往@Font-Face 生成器fontsquirrel.com/fontface/generator

如何做...

使用@font-face Kit 生成器向导,我们可以上传字体(这里是“League Gothic”),并确保您使用的字体已经被授权合法使用。

上传后,生成器将把您的字体转换为多种文件格式。下载所有这些文件,并保存到您希望它们显示的服务器上。所需的只是两个样式:

  1. 引用@font-face 文件

  2. 将新字体分配给我们想要使用的元素。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
@font-face {font-family: 'LeagueGothic'; src: url('fonts/league_gothic-webfont.eot'); src: local(''), url('fonts/league_gothic-webfont.woff') format('woff'), url('fonts/league_gothic-webfont.ttf') format('truetype'), url('fonts/league_gothic-webfont.svg#webfontdrbhz05x') format('svg');
h1 {font-family: 'LeagueGothic'; font-size: 124px; line-height: 124px; margin: 355px 0 -25px 0; text-transform: uppercase;}
</style>
</head>
<body>
<h1>Dale J Cruse</h1>
</body>
</html>

如何做...

然后炸丨药爆炸了。

它是如何工作的...

新的@font-face 功能允许我们在网页服务器上保存各种格式的字体文件,并使用 CSS 引用它们进行显示。这样,字体文件就成为了另一个资产,就像图片一样。

还有更多...

浏览器在网页上显示时使用自己专有的字体文件。通过下载和引用每种可能的格式,我们确保现代浏览器如 Firefox、Chrome 和 Safari,以及传统浏览器如 Internet Explorer 和甚至移动浏览器都能显示我们想要的字体。

不要偷

确保您使用的字体已经被授权在网上显示。偷东西不酷。

火狐浏览器提示

记得将想要使用的字体存储在与您的唯一域名相同的服务器上。一些浏览器(我在说你,Firefox)不喜欢您尝试跨域引用字体。

Paul Irish 很棒

为了给予应有的赞扬,我们使用的 CSS 方法来调用各种本地存储的字体文件是由 Paul Irish 在他的帖子"Bulletproof @font-face Implementation Syntax"中开发的:paulirish.com/2009/bulletproof-font-face-implementation-syntax

另请参阅

有一些很棒的资源可以在网上找到免费和付费字体,包括:

向字体添加投影效果

很久以前,似乎网络设计师和开发人员给每个可视元素都添加了投影效果。几乎就像他们是按照投影效果的数量来获得报酬一样。幸运的是,那个时代已经过去了。今天,只有最时尚的设计师和开发人员知道要非常节制地添加投影效果。让我们看看如何只使用 CSS 来做到这一点。

准备工作

要开始,让我们使用之前的例子,并简单地为作者的投影效果添加一个非常微妙的投影效果,来自作者之前版本的作品集网站 dalejcruse.com

如何做...

在这个示例中,我们将使用一些小心的样式来为我们的一些文本添加一个有品味的投影效果。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script
src=http://html5shiv.googlecode.com/svn/trunk/html5.js>
</script>[endif]-->
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<style>
@font-face {
font-family: 'LeagueGothic';
src: url('fonts/league_gothic-webfont.eot');
src: local(''), url('fonts/league_gothic-webfont.woff')
format('woff'), url('fonts/league_gothic-webfont.ttf')
format('truetype'), url('fonts/league_gothic-
webfont.svg#webfontdrbhz05x') format('svg');
}
h1 {font-family: 'LeagueGothic'; font-size: 124px;
line-height: 124px; margin: 355px 0 -25px 0;
text-transform: uppercase; text-shadow: black 1px 1px 0;}
</style>
</head>
<body>
<h1>Dale J Cruse</h1>
</body>
</html>

它是如何工作的...

text-shadow CSS 属性在现代浏览器中显示一个微妙的黑色投影效果,向右和向下各一个像素。虽然在作者的作品集网站上非常微妙,但如果我们将背景和字体颜色都设置为白色,效果会更加明显。

当背景和文本颜色都设置为白色时,我们在这里看到的只是黑色的投影效果,向右和向下各一个像素。由于 IE 不支持 text-shadow,这在该浏览器中将呈现为纯白色。这可能不是你想要的。

它是如何工作的...字体投影效果,添加

还有更多...

除了"黑色"这样的绝对颜色值,我们还可以使用十六进制值如"#000",甚至是带有半透明 alpha 通道的 RGBA 值。

浏览器支持

像 Chrome 2+、Firefox 3.1+、Opera 9.5+ 和 Safari 1.1+ 这样的现代浏览器都支持 text-shadow CSS 属性。这首歌现在已经很老了,但可以说 Internet Explorer 不支持它。

伴随着巨大的力量...

尽管只使用 CSS 就能够为文本添加投影效果,但不要认为这是一种滥用的许可。我们不想回到网络上到处都是投影效果的丑陋时代。相反,要善用你的力量。

对所有读者的请求

为了可读性起见,考虑只将投影效果应用于标题或页眉字体。将其应用于正文文字会变得乏味和不可读。你不想成为因过度使用和滥用投影效果而臭名昭著的人。

另请参阅

Google 发布了 WebFont Loader 开源 JavaScript 库,以更好地控制浏览器加载网络字体的方式。查看超简单的实现方法:code.google.com/apis/webfonts/docs/webfont_loader.html

将渐变效果应用于字体

让我们拿出之前的例子,并再添加一层:一个微妙的渐变效果。

准备工作

我们唯一需要的额外东西是一个便携式网络图形图像,我们可以通过 CSS 引用。

如何做...

在这个示例中,我们将添加一个 .png 图像文件,具有 alpha 透明度,以在我们的标题上创建一个时髦的渐变效果。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
@font-face {font-family: 'LeagueGothic'; src: url('fonts/league_gothic-webfont.eot'); src: local(''), url('fonts/league_gothic-webfont.woff') format('woff'), url('fonts/league_gothic-webfont.ttf') format('truetype'), url('fonts/league_gothic-webfont.svg#webfontdrbhz05x') format('svg');
}
h1 {font-family: 'LeagueGothic'; font-size: 124px; line-height: 124px; margin: 355px 0 -25px 0; text-transform: uppercase; text-shadow: black 1px 1px 0; position: relative;}
h1 span {background: url(gradient.png) repeat-x; display: block; height: 124px; position: absolute; width: 100%;}
</style>
</head>
<body>
<h1><span></span>Dale J Cruse</h1>
</body>
</html>

注意我们<h1>标签中额外的<span>。这就是我们放置图像的地方。

它是如何工作的...

通过简单地在文本上叠加一些透明度的图像,我们已经微妙地改变了文本的外观,使其呈现出渐变效果。

还有更多...

你的想象力是这种效果的唯一限制。你可以创建淡入淡出、金属效果、垂直或水平条纹,甚至斑马条纹!

提示

小心

记住:仅仅因为你可以,不代表你应该。请谨慎使用文本渐变效果。

另请参阅

要了解一个美丽的渐变效果覆盖在字体上的例子,请查看 Alex Clarke 关于土星的卫星土卫二的大学项目的标题:hagablog.co.uk/demos/enceladus/index.html。当你欣赏视觉设计时,不要忘记查看源代码,看看 Alex 非常详细记录的 HTML5 代码。

使用 figure 和 figcaption 标签注释视觉元素

<figure>元素表示一些流内容,可选地带有标题,它是自包含的,通常作为文档主流的单个单元引用。因此,该元素可用于注释插图、图表、照片、代码清单等,这些内容是从文档的主要内容中引用的,但是可以在不影响文档流的情况下,移动到主要内容之外,例如页面的侧边,专用页面或附录。” - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

“元素的第一个<figcaption>子元素(如果有的话)表示<figure>元素内容的标题。如果没有子<figcaption>元素,则没有标题。” - WHATWG 的 HTML5 草案标准 - whatwg.org/html5

准备工作

你已经看过无数次了:一张图片下面有某种文本标题。通常它在页面的一侧。以前,我们只是将其标记为一张图片,下面有某种文本容器。现在,我们有更富语义的新的<figure>元素来处理它。让我们看看如何做到。

如何做...

有两种方法可以实现这个效果:

  1. 没有标题

  2. 带标题

首先让我们尝试没有标题的情况:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<figure>
<img src="img/2688OS_MockupCover.jpg" alt="Inkscape 0.48 for Web Designers">
</figure>
</body>
</html>

现在让我们添加标题:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js>
</script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<figure>
<img src="img/2688OS_MockupCover.jpg" alt="Inkscape 0.48 for Web Designers">
<figcaption>Inkscape 0.48 for Web Designers</figcaption>
</figure>
</body>
</html>

为多个图像添加一个标题也很容易。注意多个img标签和只有一个<figcaption>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<figure> elementvisual elements, annotating<figure>
<img src="img/2688OS_MockupCover.jpg" alt="Inkscape 0.48 for Web Designers">
<img src="img/0042_MockupCover_0.jpg" alt="jQuery 1.4 Reference Guide">
<figcaption>Recent bestsellers from Packt Publishing</figcaption>
</figure>
</body>
</html>

它是如何工作...

一些样式使得<figcaption>显示在新的<figure>元素中的图像下方。

它是如何工作的...

还有更多...

记住,新的<figure>元素用于你想要显示在其相应主文本旁边的内联内容。

分组是好的

新的<figure>元素可以包含文本、图像、音频、视频、插图、图表、代码清单,以及除了主要内容之外几乎任何值得被分组在一起的东西。

语义也很重要

带标题的内联内容在书籍、报纸和杂志中经常出现。自网络早期以来,我们一直能够做到同样的事情,但现在新的<figure>元素给了我们一个更有语义的“钩子”来进行样式设置,而不是诉诸于类名。

vs

那么<figure><aside>之间有什么区别?我们应该使用新的<figure>元素来放置位置不重要的基本内容。然而,新的<aside>元素是用于相关但不是必要的内容。我们在挑刺吗?也许。但你是那种对细节苛刻的网页开发者,对吧?

另请参阅

要了解 HTML5 与所有以前版本的 HTML 有何不同的更详细描述,请参阅维基百科条目:en.wikipedia.org/wiki/HTML5

第三章:使用 CSS 进行样式设置

在本章中,我们将涵盖:

  • 将元素设置为display:block

  • 设置nav块元素的样式

  • 使用 background-size 控制背景外观

  • 使用border-radius添加圆角

  • 包括多个背景图像

  • 为图像添加阴影

  • 为 Internet Explorer 浏览器设计样式

介绍

“谢谢你带来的美好时光,IE6。在@Mix 上见,我们将展示 IE 天堂的一小部分。-微软的 Internet Explorer 团队”-来自ie6funeral.com上线上看到的 IE6 葬礼的挽歌。

你已经接受了以不同的方式思考 HTML 的挑战。接下来,你将被挑战扩展你的层叠样式表知识。除此之外,我们还将挑战一些关于跨浏览器显示的假设。如果你——和你的客户——认为网站在每个浏览器中应该看起来一样,我们将改变一些人的想法。但如果你已经知道跨浏览器显示的谬误,你将成为帮助改变其他人想法的人。

在我们做任何这些事情之前,我们需要问自己和我们的客户一个简单的问题:网站在每个浏览器中需要看起来完全一样吗?需要吗?对于简洁的一字答案,请访问dowebsitesneedtolookexactlythesameineverybrowser.com 在 Chrome、Firefox、Opera 或 Safari 等现代浏览器中。

介绍

还要检查像 Internet Explorer 6 这样的旧版浏览器:

介绍

我的朋友们,这就是一个已经过时的浏览器。看着某物死去并不是很美观,是吗?

很明显,网站在不同的浏览器上显示不同。问题是:那又怎样?那有关系吗?应该吗?为什么?

我们很少有人在无菌实验室里工作,我们对我们创造的东西的显示有 100%的创造控制。甚至更少的人有时间或意愿为每个浏览器创建单独的定制体验。肯定有一个中间的方法。这里有一句作者真的很喜欢的老话:

“真相在中间。”- Avadhoot Patwardhan

在这种情况下,事实是你将不得不与你的客户合作,无论他们是业务所有者、项目经理,还是任何付钱让你为他们创建网站的人。但是,坐视不管,听着这些人告诉我们如何做我们的工作的日子已经结束了。如果你知道有更好、更快、更有效的开发方式,你必须说出来。这是你的责任。如果你不这样做,没有人会为你说话。这对你不利,对你的客户不利,对行业也不利。不要成为那个人。

相反,你将不得不向你的客户解释为什么一些浏览器显示的东西略有不同,以及为什么这是完全可以接受的。以下是作者在实际业务情况中使用过的一些策略:

  1. 向客户证明为旧版浏览器(特别是 IE6)提供支持将需要更长的时间。准备好证明为该浏览器开发可能需要你时间的四分之一。打击客户的痛处(钱包),那个人通常会让步。

  2. 强调用户体验即使 IE 没有其他浏览器拥有的每个圆角或过渡效果,也可以保持完全相同。

提示

用户体验始终胜过花里胡哨的外观。

CSS 并不是 HTML5 规范的正式部分。事实上,它值得有自己的书。但在这一章中,作者将向你展示真实世界的例子,说明其他人如何使用 CSS 通过将元素显示为块级、模拟导航栏、使用多个背景图像、应用圆角以及高级样式,如添加阴影,并为 Internet Explorer 浏览器设计样式。

让我们开始吧!

将元素设置为 display:block

默认情况下,现代浏览器将新的 HTML5 元素分配为display:block。但是默认情况下,旧版浏览器和大多数版本的 Internet Explorer 会自动回退到display:inline。如果您之前使用过 CSS,您可以提前看到问题。我们要做的第一件事是在问题出现之前解决它。

做好准备

首先,让我们识别 HTML5 中的所有新元素。这些包括:

  • <article>

  • <aside>

  • <audio>

  • <canvas>

  • <command>

  • <datalist>

  • <details>

  • <embed> - 不是一个新标签,但它最终在 HTML5 中验证了

  • <figcaption>

  • <figure>

  • <footer>

  • <header>

  • <hgroup>

  • <keygen>

  • <mark>

  • <meter>

  • <nav>

  • <output>

  • <progress>

  • <rp>

  • <rt>

  • <ruby>

  • <section>

  • <source>

  • <summary>

  • <time>

  • <video>

  • <wbr>

如何做...

我们将从我们通常的页面框架开始,并添加一个样式,使所有这些新元素都display:block

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog Title</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<style>
article, aside, audio, canvas, command, datalist, details, embed, figcaption, figure, footer, header, hgroup, keygen, mark, meter, nav, output, progress, rp, rt, ruby, section, source, summary, time, video, wbr {display:block;}
</style>
</head>
<body>
</body>
</html>

好了。这并不难。事实上,这些也可以包含在 CSS 重置文件中。

它是如何工作的...

使用 CSS,我们将所有新的 HTML5 元素设置为块级元素,确保更可预测的浏览器行为。

还有更多...

尽管现代浏览器已经将这些新的 HTML5 标签显示为块级元素,但在我们的样式表中再次声明它们为display:block并不会有任何问题。在这里,小心总比后悔好。

没有必要重复和重复和重复和重复和重复

注意:我们应该在每个页面上引用的外部样式表中包含这个简短的样式,而不是在每个页面的顶部内联显示它。最好只声明一次,让它在您网站的其余部分中生效,而不是一遍又一遍地重复。

只需一次样式

使用这个简单的样式声明一次,我们可以确保我们的现代、传统和移动浏览器在显示新的 HTML5 元素时行为更加可预测。

过去的回声

出于某种原因,一些开发人员不想学习 HTML5。你会听到他们说一些关于规范还没有准备好,在所有浏览器中还没有完全支持,以及你需要像 CSS 或 JavaScript 这样的“黑客”来使其工作的无稽之谈。这都是无稽之谈。不要理会他们的抱怨。你真正听到的是恐龙灭绝的声音。如果恐龙决心通过自己的不作为将自己灭绝,那就让它灭绝吧。只有强者才能生存。

有助于记住,进化是分阶段进行的。并非所有生物都会突然一起进化。与恐龙不同,你可以决定你是想现在、以后还是根本不想进化。你可以决定你想站在历史的哪一边。

另见

我们没有引发火灾。它一直在燃烧。自世界开始转动以来。杰弗里·泽尔德曼的《与糟糕的浏览器说再见》一文于 2001 年发表后,在 Web 开发世界引起了轰动。在这篇文章中,泽尔德曼,现在被广泛认为是 Web 标准运动的奠基人,激励了一代 Web 设计师和开发人员使用 CSS 进行 Web 呈现,并抛弃破损的传统浏览器。阅读这篇开创性的宣言:alistapart.com/articles/tohell

样式化导航块元素

在创建 HTML5 规范时,进行了分析,并确定最常用的元素之一是<div id="nav"><div id="navigation">。在 HTML5 中不再需要这样做。相反,我们有了语义丰富的<nav>。现在让我们开始为其添加样式。

做好准备

让我们看看css3maker.com网站如何使用新的语义丰富的<nav>元素。

准备好的元素

如何做...

如果我们查看主页的源代码,我们会找到这段代码:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CSS3.0 Maker | CSS3.0 Generator | CSS 3.0 Generator </title>
<link href="style/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="img/CreateHTML5Elements.js"></script>
</head>
<body>
<div class="main_wrapper">
<nav> elementstyling<div id="wrapper">
<nav class="clearfix">
<ul>
<li class="frest"><a href="index.html" title="CSS 3.0 Maker" class="active">Home</a></li>
<li><a href="border-radius.html" title="Border Radius"> Border Radius</a></li>
<li><a href="css-gradient.html" title="Gradient">Gradient</a></li>
<li><a href="css3-transform.html" title="CSS 3.0 Transform">CSS Transform</a></li>
<li><a href="css3-animation.html" title="CSS 3.0 Animation">CSS Animation</a></li>
<li><a href="css3-transition.html" title="CSS 3.0 Transition">CSS Transition</a></li>
<li><a href="css-3-rgba.html" title="CSS 3.0 RGBA">RGBA</a></li>
<li><a href="text-shadow.html" title="Text Shadow">Text Shadow</a></li>
<li><a href="box-shadow.html" title="Box Shadow">Box Shadow</a></li>
<li><a href="text-rotation.html" title="Text Rotation">Text Rotation</a></li>
<li><a href="font-face.html" title="@Font Face">@Font Face</a></li>
</ul>
</nav>
</div>
</div>
</body>
</html>

请注意,到目前为止,HTML 标记非常简单。css3maker.com团队创建了一个页面包装器,然后使用了新的<nav>元素来包含具有所有典型导航元素的无序列表。简单吧?接下来让我们关注他们是如何进行样式设置的。

<style>
nav {
background: url("../images/box_bg.png") repeat scroll 0 0 transparent;
border-radius: 5px;
margin-bottom: 8px;
margin-right: 5px;
}
<nav> elementstylingnav ul {
display: block;
list-style: none outside none;
margin: 0;
padding: 0 0 0 5px;
}
nav ul li.frest {
border-left-width: 0;
}
nav ul li {
border-right: 1px solid #1D1C1C;
display: inline;
float: left;
margin: 0;
padding: 0;
}
nav ul li a {
color: #000;
display: inline;
float: left;
font-size: 13px;
height: 35px;
line-height: 35px;
padding: 0 10px;
text-shadow: 0 -1px 2px #737373;
-webkit-transition: All 0.50s ease;
-moz-transition: All 1s ease;
-o-transition: All 1s ease;
}
</style>

它是如何工作的...

新的<nav>元素不仅成为我们无序列表的容器,还为 Web 浏览器提供了额外的含义和可访问性增强。通过浮动<nav>元素并显示我们的无序列表而不带列表样式,这使我们能够水平显示我们的导航栏。

还有更多...

我们还看到了新的 CSS3 transition属性的使用。简单地说,这是一个新的浏览器鼠标悬停效果,以前只能用 Flash 或 JavaScript 实现。现在,CSS 可以改变元素的外观,当鼠标移动到它上面时。

由于transition属性在浏览器制造商中只有实验性支持,你会看到以单破折号为前缀的供应商特定前缀,比如:

  • -webkit(对 Safari 和 Chrome)

  • -moz(对于 Firefox)

  • -o(对 Opera)

此外,Internet Explorer 有自己的供应商前缀,即-ms。令人费解的是,Chrome 既可以处理-webkit前缀,也可以处理自己的-chrome前缀。

这些破折号只是表示浏览器制造商正在进行支持的工作。请记住,HTML5 和 CSS3 是不断发展的规范。我们现在可以开始使用它们的元素,但完全支持还没有到位。就像我们在为未来做饭一样。

浏览器支持

支持新的<nav>元素的 Web 浏览器:

浏览器支持

文本阴影很酷

在前面的代码示例中,你还会注意到对我们在上一章中深入讨论的新 CSS3 text-shadow属性的巧妙使用。

另请参阅

cSS3maker.com网站是任何需要这些新 CSS 属性的浏览器特定前缀的 CSS3 开发人员的绝佳资源:

  • 边框半径

  • 渐变

  • CSS 变换

  • CSS 动画

  • CSS 过渡

  • RGBA

  • 文本阴影

  • 盒阴影

  • 文本旋转

  • @font-face

使用 background-size 控制背景外观

使用 CSS3,我们现在有一种方法来指定背景图像的大小。我们可以用像素、宽度和高度或百分比来指定这个大小。当你把大小指定为百分比时,大小是相对于我们使用 background-origin 指定的区域的宽度或高度的。

使用 background-size 控制背景外观

准备就绪

让我们看一个真实世界的例子,miessociety.org,这是一个由设计师 Scott Thomas 创建的 Simple Honest Work 代理机构的美丽网站,致力于保护建筑师路德维希·密斯·凡德罗的遗产。

如何做...

如果我们查看样式表的源代码,我们会看到作者为body创建了一个规则,然后指定任何使用的背景图像都会覆盖整个body

作者还为每个页面指定了一个背景图像,通过给每个body元素附加一个ID

它是如何工作的...

在这里,我们看到创作者们使用了一些简单的样式,包括新的background-size属性,来拉伸一个大的背景图像横跨整个页面,无论您的显示器大小或分辨率如何。

<style>
background appearance controlbackground-size property, workingbody {
background: transparent no-repeat scroll 50% 50%;
background-repeat: no-repeat;
background-size: cover;
margin: 0px;
padding: 0px;
}
body#body_home {
background-attachment: inherit;
background-image: url(http://miessociety.org/site_media/library/ img/crownhall_index.jpg);
background-position: 50% 0%;
}
</style>

还有更多...

新的background-size元素通常以像素、宽度和高度或百分比来指定。在密斯·凡德罗协会网站的例子中,我们看到作者使用了术语"cover",这使背景图像能够拉伸以"覆盖"整个画布。聪明。

浏览器支持

支持新的background-size属性的 Web 浏览器:

浏览器支持 background-size 属性 about

在 IE 中可接受

那么,当我们在不支持的浏览器中查看使用background-size的网站时会发生什么?在这里,我们可以看到 Internet Explorer 10 之前的版本无法拉伸背景图像,而是简单地用黑色填充了剩下的画布。这是一个完美的例子,即使在每个浏览器中看起来都不一样,但仍然提供了完全令人满意的用户体验。没有一个网站浏览者——即使是使用 IE6 的人——可以合理地抱怨他们没有按照作者的意图体验网站。

IE 中可接受

Simple Scott 简直太棒了

在这一部分,我们使用了 Mies van der Rohe Society 网站的真实示例,使用了新的 CSS3 background-size属性,并注意到网站作者如何巧妙地适应了旧浏览器的使用。

另请参阅

html5rocks.com网站提供交互式演示、代码播放器、示例和逐步教程,以开发和磨练您的新技术技能。有趣的是,该网站是一个您可以贡献的开源项目。学习它,分享它,回报社会!

使用border-radius添加圆角

border-radius很可能会成为 CSS3 中最常用的新属性。由于 Web 上使用了许多按钮和包含元素的圆角,border-radius使得通过 CSS 轻松实现,而不是依赖于图像。以下是如何做到的。

准备好了

让我们来看看devinsheaven.com,这是 iPhone 应用设计师和开发者 Devin Ross 的作品和著作。具体来说,我们将研究 Devin 如何设计他的搜索字段。

准备好 border-radiusabout

如何做...

查看 Devin 的代码源,我们看到简单、直接的表单标记,包括所有典型的元素:包装器、表单、标签和两个输入。

<div id="search-form">
<form role="search" method="get" id="searchform" action="http://devinsheaven.com/" >
<div>
<label for="s">Search for:</label>
<input type="text" value="" name="s" id="s" />
<input type="submit" id="searchsubmit" value="Search" />
</div>
</form>
</div>

但是,Devin 在他的样式表中接下来做的事情实现了现代浏览器中的圆角:

<style>
#navigation-bar #search-form {
background: none repeat scroll 0 0 white;
border-radius: 4px;
margin-left: 180px;
margin-top: 12px;
padding: 2px 6px;
position: absolute;
width: 250px;
}
</style>

它是如何工作的...

Devin 为搜索表单ID指定了四像素的border-radius,这样可以使其所有四个角都按相同的量变圆。也可以分别指定每个角的border-radius

还有更多...

有趣的是,Opera 浏览器将支持新的 CSS3 border-radius属性,而无需浏览器特定前缀。干得好,Opera!谢谢!

浏览器支持

支持新的border-radius样式的 Web 浏览器:

浏览器支持

IE 中可接受

那么,当在不支持的浏览器中查看 Devin 设计精美的网站时会发生什么?Internet Explorer 8 及更早版本简单地忽略了border-radius属性,并使角变成了方形。再次强调,这是完全可以接受的,但通常需要您向客户解释为什么像素完美并不总是一个现实的目标。

在 Internet Explorer 8 中查看 Devin 的天堂网站。请注意方形搜索表单边框。

IE 中可接受

Devin 的天堂到 11

在这一部分,我们演示了devinsheaven.com如何使用新的 CSS3 border-radius属性微妙地使搜索字段的角变圆。我们还看了作者对浏览器特定前缀的使用,以及作者选择如何处理像 Internet Explorer 8 及更早版本这样的旧浏览器。

另请参阅

要了解更多关于新的 CSS3 border-radius属性的出色用法,请访问houseofbuttons.tumblr.com。它包括许多设计和开发灵感。

包括多个背景图像

benthebodyguard.com在 2010 年 12 月首次亮相时,引起了互联网的轰动。作者使用单页面布局讲述了一个名叫 Ben 的虚构法国保镖的互动故事。当滚动浏览这个长页面时,多个背景帮助讲述了即将发布的 iPhone 应用的故事。

准备好了

让我们查看benthebodyguard.com,并滚动浏览动画。

准备就绪

如何做到的...

让我们专注于源代码的一部分,看看网站作者如何利用多个背景。

<!doctype html>
<html class="" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Ben the Bodyguard. Coming soon to iPhone® and iPod touch®</title>
<meta name="author" content="Ben the Bodyguard">
<link rel="stylesheet" href="css/style.php?v=1">
</head>
<body class="index">
<div id="container">
<div id="hide-wrapper">
<header>
<img id="comingDecember" alt="Ben the Bodyguard is coming for iPhone and iPod touch in january 2011" src="img/red_stamp.png">
<h1>A Frenchman <br>protecting your secrets.<br> Yes, seriously.</h1>
<h3>Ben the Bodyguard</h3>
<p>Protecting your passwords, photos, contacts<br> and other sensitive stuff on your iPhone or iPod touch</p>
</header>
<div id="ben">
<div id="speechBubbleWrapper">
<div id='speechBubble'></div>
</div>
<div id="ben-img"></div>
</div>
<div id="hotel">
<div id="hotelanimation"></div>
</div>
<div id="bridge"></div>
<div id="train"></div>
<div id="hideBenInBeginning"></div>
<div id="city">
<div id="thief"></div>
<div id="stolen"></div>
<div id="yakuza"></div>
</div>
</div>
</div>
</body>
</html>

到目前为止,除了几个空的divs之外,没有什么特别的。这些是作者用来讲故事的多个背景图像的容器。您的容器可以包括文本、图像、视频等。

它是如何工作的...

通过为每个div指定背景图像,网站作者使用了多个 PNG 文件背景图像,以创建一个无缝交互式的在线体验。

还有更多...

Mighty 的朋友们创建了一系列迷你网站,以展示我们在上一章中谈到的一些新的排版可能性。Frank Chimero 在lostworldsfairs.com/atlantis创建了一个单页网站,它的工作方式与http://benthebodyguard.com网站的多个背景相似。当您滚动浏览这个长页面时,您的头像会下降到亚特兰蒂斯失落的城市。

还有更多...

内容在哪里?

查看 Atlantis Lost Worlds Fair 迷你网站的源代码,我们看到了类似的方法,其中包含了多个空的divs

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<title>Atlantis World's Fair</title>
<meta name="Author" content="Friends of Mighty">
<link rel="stylesheet" href="css/all.min.css">
</head>
<body>
<div id="back_to"><a href="http://lostworldsfairs.com">Lost World's Fairs</a></div>
<div id="header">
<div id="img_doc"></div>
<div id="img_ship"></div>
<div class="container">
<p id="txt_below">Below</p>
</div>
<div id="backwave"></div>
<div id="frontwave"></div>
</div>
<div id="tube">
<div class="tube_container">
<div id="tube_dude" class="tube_container"></div>
</div>
<div class="tube_container">
<div id="tube_overlay"></div>
<div id="tube_backtop"></div>
<div id="tube_back"></div>
<div id="tube_fronttop"></div>
<div id="tube_frontbottom"></div>
<div id="tube_front"></div>
</div>
</div>
<div id="depthfinder"><span id="depth-o-meter">0</span> <span id="txt_k">k</span> Leagues</div>
<div id="depthscale"></div>
<div id="content">
<section id="depth1">
<div class="container">
<div id="welcomesign" class="bringFront">
<header>
<h1><span id="txt_date">1962</span> <span id="txt_atlantis">Atlantis</span> <span id="txt_worldsfair">Worlds Fair</span></h1>
<p id="txt_taglines"><span id="txt_worldsfaircircle">The World's Fair</span> <span id="txt_imaginationflag">The Depths Of Imagination</span></p>
</header>
</div>
<aside id="info_1" class="dyk-right">
<div class="didyouknow">
<img src="img/dyk-info.png" alt="info" height="30" width="30"/>
<h4>Did You Know</h4>
<p>Atlantis was<br/> originally built on<br/> the floor of the<br/> sea in 722 BCE<br/> by amphibious<br/> herbivores</p>
</div>
</aside>
</div>
</section>
</div>
</body>
</html>

让我们坦率一点

Chimero 使用了与benthebodyguard.com网站类似的方法,为这些本来是空的divs指定了背景图像,以创建一种无缝的体验。

另请参阅

HTML5 中有很多新东西,就像是最好的技术圣诞节一样。通过访问html5test.com来跟踪您的浏览器支持哪些元素。通过多种浏览器访问该网站会产生令人警醒的结果。

为图像添加阴影

以前,像图像下方或周围的阴影这样的视觉效果只能通过使用第二个图像来实现阴影,或者将阴影本身作为图像的一部分来实现。问题在于,如果您想要调整阴影,您必须重新裁剪它。让我们看看使用 CSS3 的现代智能方法。

准备就绪

查看thebox.maxvoltar.com上的视觉元素周围迷人而微妙的阴影。作者 Tim Van Damme 已经应用了新的 CSS3 box-shadow属性。

准备就绪

如何做到的...

让我们检查样式,看看 Tim 是如何实现这种美观简单的效果的:

<style>
section {
background: none repeat scroll 0 0 #EAEEF1;
border: 1px solid #FFFFFF;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
margin: 0 auto;
padding: 49px;
position: relative;
width: 300px;
z-index: 50;
}
</style>

除了其他样式之外,我们可以清楚地看到box-shadow属性指定了阴影的颜色和扩散距离。

它是如何工作的...

新的 CSS3 box-shadow属性的语法与text-shadow属性相同。也就是说,网站作者在照片周围应用了一个阴影,该阴影在右侧有两个像素,在底部有十个像素,透明度为 50%。

浏览器支持

支持新的box-shadow样式的 Web 浏览器。

浏览器支持

无知是福

不支持新的 CSS box-shadow属性的浏览器只会忽略该规则,不会显示阴影。外观略有改变,但用户体验不会受到影响。没有伤害,也没有犯规。

The Box 的 Box-shadow

在本节中,我们演示了作者 Tim Van Damme 如何使用新的 CSS3 box-shadow属性在他的采访网站周围创建微妙的阴影效果。

另请参阅

在为自己的项目创建样式表时,您可以完全控制创建一个 CSS 来统治它们所有,或者为移动和/或打印机友好页面创建单独的定制体验。但是当您没有完全控制时会发生什么?那么知道我们有像printfriendly.com这样的工具来为我们完成这项工作就很好。

为 Internet Explorer 浏览器设置样式

现在作者强烈主张为现代浏览器提供最佳的 CSS3 体验,让旧版本的 IE 随心所欲。如果在旧浏览器中某个元素缺少圆角或阴影,作者并不在乎。但事实上,你的客户可能在乎。让我们打开潘多拉魔盒,谈谈如何适应过时的浏览器。

准备工作

我们将研究一系列特定的方法,以使 IE 在使用新的 CSS3 属性时表现正常,比如border-radius, box-shadowtext-shadow

Border-radius

在旧版本的 IE 中可以实现圆角。让我们访问htmlremix.com/css/curved-corner-border-radius-cross-browser来了解如何做到这一点。在那里,我们将学习如何在样式表中包含.htc行为:

<style>
.curved {
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
behavior: url(border-radius.htc);
}
<style>

注意,.htc文件是代码膨胀,这种行为会导致你的 CSS 无法验证。

Box-shadow

我们可以通过使用专有的滤镜来强制 IE 显示box-shadows

<style>
.box-shadow {
-moz-box-shadow: 2px 2px 2px #000;
-webkit-box-shadow: 2px 2px 2px #000;
filter: progid:DXImageTransform.Microsoft.Shadow(color='#000', Direction=145, Strength=3);
}
</style>

不幸的是,你必须调整那个滤镜才能实现阴影的方向和深浅。请注意,这个滤镜不如新的 CSS3 box-shadow属性强大。

Text-shadow

似乎在 IE 9 之前的版本中使text-shadow生效的唯一方法是使用像scriptandstyle.com/submissions/text-shadow-in-ie-with-jquery-2这样的 jQuery 插件通过 JavaScript 来实现。请注意,强制 JavaScript 执行 CSS 的工作永远不是一个好方法,这种技术只会导致代码膨胀。

注意

虽然在旧版本的 IE 中可能实现几种类似 CSS3 的效果,但并不推荐。每一种都需要额外的开发类型,并且可能影响浏览器性能。使用时要谨慎。

另请参阅

Kyle Weems 创建了一个令人捧腹的周漫画系列,讽刺了 Web 标准世界中的一切,网址是cssquirrel.com。HTML5,CSS3,Twitter,可访问性以及在这些领域中具有重要影响力的人物都成了 Kyle 经常扭曲幽默感的对象。

另请参阅

第四章:创建可访问的体验

在本章中,我们将涵盖:

  • 测试浏览器支持

  • 添加跳转导航

  • 添加元标记

  • 使用标签中的语义描述供屏幕阅读器使用

  • 提供备用站点视图

  • 使用hgroup创建可访问的标题区域

  • 为不支持的浏览器显示备用内容

  • 使用 WAI-ARIA

介绍

“良好的可访问性设计是良好的网页设计。”

到目前为止,我们已经讨论了很多关于语义网页编码的内容,以及 HTML5 允许我们将这种命名方法提升到一个以前无法达到的新水平。我们的讨论大部分集中在语义网页编码如何使我们作为网页开发人员的工作更容易、更快速和更有意义。

在本章中,我们将关注语义网页编码如何改善我们的受众在网上的体验。现在,应用语义标签——有意义的标签而不仅仅是表现性的标签——对于屏幕阅读器以及依赖它们来浏览我们创建的网站、应用程序和界面的人来说变得更加重要。

如果您曾经为军方、学术机构或从美国联邦政府获得资金的任何人编写过网站、应用程序或界面,您一定听说过第 508 条。

与 HTML 或 CSS 验证不同,第 508 条验证的工作方式不同。在 HTML 或 CSS 中,代码要么有效,要么无效。这是二进制的。但在第 508 条中不是这样。在这种情况下,有三种不同级别的验证,每一级别都更难达到。

在本章中,我们将讨论如何使用 HTML5 来测试浏览器支持,添加跳转导航和元标记,使用标签中的语义描述来供屏幕阅读器使用,提供备用站点视图,使用新的 HTML5 hgroup元素来创建可访问的标题区域,为不支持的浏览器显示备用内容,并使用 WAI-ARIA。

现在,让我们开始吧!

测试浏览器支持

让我们从使用由 Faruk Ates 和 Paul Irish 开发的开源 Modernizr 项目开始:modernizr.com。根据该网站,Modernizr 使用特性检测来测试当前浏览器对即将推出的特性的支持情况。

提示

Modernizr 概念旨在进行特性检测,而不是浏览器检测。这是一个微妙但重要的区别。与其做出广泛的假设,Modernizr 方法检测浏览器支持的特性。

测试浏览器支持

如何做…

下载 Modernizr JavaScript 文件并在您的标记的head部分引用它。然后将“no-js”类添加到您的body元素中,就像这样:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<script src="img/modernizr-1.6.min.js"></script>
</head>
<body class="no-js">
</body>
</html>

它是如何工作的…

在您的标记中包含该脚本和简单的 body 类,使 Modernizr 能够检测 Web 浏览器支持以下哪些项目。然后它将添加类和 JavaScript API 来检测对某些特性的支持。如果给定浏览器不支持这些特性,Modernizr 就不会添加它们。

  • @font-face

  • Canvas

  • Canvas 文本

  • HTML5 音频

  • HTML5 视频

  • rgba()

  • hsla()

  • border-image:

  • border-radius:

  • box-shadow:

  • text-shadow:

  • 不透明度:

  • 多重背景

  • 灵活的盒模型

  • CSS 动画

  • CSS 列

  • CSS 渐变

  • CSS 反射

  • CSS 2d 转换

  • CSS 3d 转换

  • CSS 过渡

  • 地理位置 API

  • localStorage

  • sessionStorage

  • SVG

  • SMIL

  • SVG 裁剪

  • 内联 SVG

  • 拖放

  • hashchange

  • X 窗口消息

  • 历史管理

  • applicationCache

  • 触摸事件

  • Web 套接字

  • Web Workers

  • Web SQL 数据库

  • WebGL

  • IndexedDB

  • 输入类型

  • 输入属性

还有更多…

现代化 2 Beta 中的新功能是能够自定义 JavaScript 下载。所以现在,如果您不关心特定功能(比如拖放),您可以取消选择它,而不让 Modernizr 检查它。在这里阅读更多信息:modernizr.github.com/Modernizr/2.0-beta

展望未来

来自网站:

"Modernizr 是一个小巧简单的 JavaScript 库,它可以帮助你利用新兴的 Web 技术(CSS3、HTML5),同时仍然对尚未支持这些新技术的旧浏览器保持精细的控制。"

Modernizr 的真正作用

Modernizr 不会添加或启用浏览器中原生不存在的功能。例如,如果你的浏览器不支持输入属性,Modernizr 不会自动为你的浏览器添加这个功能。这是不可能的。它只是让你作为开发者知道你可以使用什么。

出于正确的原因

有些网页开发者使用 Modernizr 是因为他们在某篇文章中读到他们应该使用它。这没问题,但你比他们聪明。你看到了在浏览器中检测这些功能如何更好地告诉你如何提供无障碍体验,如果浏览器不原生支持某些属性。你真聪明,也很帅!

另请参阅

作者 Gil Fink 为微软写了简单而简洁的文章"使用 Modernizr 检测 HTML5 功能" HTML5 Features Using Modernizr",供进一步阅读,网址为blogs.microsoft.co.il/blogs/gilf/archive/2011/01/09/detecting-html5-features-using-modernizr.aspx

添加跳过导航

跳过重复元素如导航对使用屏幕阅读器的人是有益的。想象一下,当访问一个网站时,你需要读完每一个导航元素才能继续查看主要内容。那会很烦人,不是吗?对于使用屏幕阅读器的人来说也是一样。让我们看看如何不让我们的一部分受众感到烦恼的简单方法。

准备工作

在这个例子中,我们要做的是创建一个简单但特殊的不可见锚点,这样我们的屏幕阅读器朋友就可以选择跳过我们的导航,直接进入我们的网站内容。

如何做...

如果你在 HTML 方面有一段时间了,你肯定曾经创建过跳过导航。它可能看起来像这样:

<a class="skip" href="#content">Skipnav</a>

你的 CSS 可能包括这样的内容来使锚点不可见:

.skip {display: none}

包含主要内容的第一个div然后包含了另一个看起来像这样的不可见锚点:

<h2><a name="content"></a></h2>

多年来一切都很顺利。它一直工作得很好。在 HTML5 中也应该工作,对吧?嗯,猜猜看?它不工作。让我们看看为什么。

它是如何工作的...

在 HTML5 中,锚点标签的name属性不再有效。还记得我在第一章中说的关于创建 HTML5 规范的方法是“铺平牛路”的吗?嗯,这次不是。这次牛路已经被移除了。所以现在我们要做的是:

我们将保留最初的标记:

<a class="skip" href="#content">Skipnav</a>

我们将保留隐藏锚点的 CSS 代码:

.skip {display: none}

但这次我们在第二部分标记中要做的不同:

<h2 id="content"></h2>

当我们移除了锚点时,我们将其name属性从ID重命名并添加到h2中。现在它有效,并符合 HTML5 规范。很简单!

还有更多...

跳过导航的能力是我们开发者可以做的最常见的事情之一,也是最容易实现的,以支持我们不同能力的受众。考虑重新访问你开发过的旧网站,更新(或添加)跳过导航,将DOCTYPE切换到 HTML5,你就可以使用最新的技术,同时支持无障碍。

完整的浏览器支持

跳过导航是所有主要网页浏览器都支持的一个变化。作者在这本书中很少有机会这样说,所以这真是一种解脱!

少即是多

在不久的将来,当屏幕阅读器得到更新时,我们将能够使用 Web 可访问性倡议-可访问丰富互联网应用程序角色,并使用新的nav元素来实现跳过导航的功能。更少的标记等于更好的!

webstandards.org网站采用了一种有趣的方法,只有在视力用户悬停在上面时才显示跳过nav

Less equals more

另请参阅

html5accessibility.com是一个很棒的资源,提供有关新的 HTML5 元素在 Web 浏览器中的可访问支持以及为使用辅助技术的人提供信息。

添加元标签

“语言标签标识了人类为了向其他人传达信息而说、写或以其他方式传达的自然语言。计算机语言明确排除在外。HTTP 在 Accept-Language 和 Content-Language 字段中使用语言标签。”- 万维网联盟的超文本传输协议规范

准备工作

如果您正在考虑您或您客户网站的可访问性(您应该考虑!),您将希望确保使用屏幕阅读器的人能够以您打算的语言阅读到您的信息。我们将看看如何做到这一点。

如何做...

首先,确定您希望网站阅读的语言。它可以是英语、法语、克林贡语或任何组合。请参阅最受欢迎的内容语言列表:devfiles.myopera.com/articles/554/httpheaders-contentlang-url.htm

它是如何工作的...

我们已经在我们的通用模板中有一个英语内容语言元标签:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
<script src="img/modernizr-1.6.min.js"></script>
</head>
<body class="no-js">
</body>
</html>

简单的<html lang="en">就是我们需要确保我们的网站将以英语阅读。将其更改为其他语言可能没有那么简单。对于法语,请使用<html lang="fr>,如果您是《星际迷航》的忠实粉丝,请使用<html lang="x-klingon">。请注意,克林贡语示例中的x-前缀表示实验性语言。

还有更多...

您还可以使用类似<html lang="en, fr">的方式指定多种语言,用于英语和法语。请注意在值周围使用引号,因为我们引用了多个值。

你在说什么?

注意:“如果未指定 Content-Language,则默认情况下内容适用于所有语言受众。这可能意味着发件人不认为它是特定于任何自然语言,或者发件人不知道它是为哪种语言而设计的。”- 万维网联盟的超文本传输协议规范

一切都归结为 SEO

指定内容语言对搜索引擎也有益,使它们能够解析我们打算使用的语言的内容。我们中谁不需要更多的搜索引擎优化呢?

我做到了吗?

如果您没有指定元语言,最糟糕的情况会是什么?什么都不会发生,对吗?错。事实证明,如果我们没有指定元语言,我们的宿敌 Internet Explorer 的旧版本将尝试猜测您的意图是什么语言。正如我们已经看到的,有时 IE 的猜测是错误的。根据这篇文章,无害的用户输入可能会变成活动的 HTML 并执行,导致安全漏洞:code.google.com/p/doctype/wiki/ArticleUtf7

另请参阅

section508.gov是美国法典第 508 条规定的官方网站。尽管我们网页开发人员主要关注第 508 条如何适用于网络,但实际上它是一套更广泛的法律,定义了我们美利坚合众国如何适应那些在虚拟世界和现实世界中具有不同能力的人。

在标签中使用语义化描述供屏幕阅读器使用

语义网页开发的方法不仅对于我们这些开发网站、应用程序和界面的人有意义,对于那些使用和互动我们创建的体验的人也有意义。

准备好了

让我们回顾一些 HTML5 规范中的新的更语义化的标签。

如何做...

新的 HTML5 标签包括:

  • <article>

  • <aside>

  • <audio>

  • <canvas>

  • <datalist>

  • <details>

  • <embed> - 不是一个新标签,但它最终在 HTML5 中验证了

  • <figcaption>

  • <figure>

  • <footer>

  • <header>

  • <hgroup>

  • <keygen>

  • <mark>

  • <meter>

  • <nav>

  • <output>

  • <progress>

  • <rp>

  • <rt>

  • <ruby>

  • <section>

  • <source>

  • <summary>

  • <time>

  • <video>

  • <wbr>

它是如何工作的...

在那个列表中,以下新标签可以支持文本:

  • <article>

  • <aside>

  • <datalist>

  • <details>

  • <figcaption>

  • <figure>

  • <footer>

  • <header>

  • <hgroup>

  • <keygen>

  • <mark>

  • <nav>

  • <output>

  • <section>

  • <source>

  • <summary>

  • <time>

  • <wbr>

该列表代表了绝大多数新的 HTML5 标签。使用这些更语义化的标签将为屏幕阅读器增加额外的含义和智能。

还有更多...

以下新标签还为我们提供了创造更丰富和更语义化的体验的机会:

  • <audio>

  • <embed>

  • <progress>

  • <video>

始终改进

调查一下您已经发布的具有辅助功能要求的项目。如果您仍然能够更新它们,这是一个重温它们并添加更多语义上有意义的标记的绝佳机会。记住:一个网站或应用程序或界面已经发布并不意味着您不能以后再次访问它。如果一个项目在发布时是一个失败,那么现在是更新它然后重新发布的绝佳时机。谁知道呢?它可能会变成一个完美的作品,让您得到另一份工作!得分!

良好的 SEO 语义

使用越来越多的语义化和有意义的标签不仅对使用屏幕阅读器的人有益,而且对搜索引擎优化也有益,因为搜索引擎将能够更智能地解析和理解您的代码。

Greg 终于学会了

语义网页开发对其他开发人员也有好处。如果您在一个<nav>标签中编写了一个区域,那么当前在您团队上的另一个开发人员或将来在您项目上工作的开发人员将立即理解您的意图。作者曾经与一个开发人员合作,他使用了毫无意义的命名,比如<div id="banana">,而这与香蕉毫无关系。那个开发人员认为这是一种通过成为唯一知道某些标签含义的工作保障。不幸的是,当他在几年后编辑他以前创建的东西时,这种方法对他来说变得痛苦,因为他记不起它的含义。教训是什么?不要惹自己以后生气!

另请参阅

caniuse.com 提供了 HTML5、CSS3、SVG 等在桌面和移动浏览器中的兼容性表。该网站是一个宝贵的辅助工具,可以帮助理解哪些新标签可以被支持。它不断更新,不仅值得收藏,还值得反复参考。

提供备用网站视图

驻剑桥马萨诸塞州的网站开发者 Ethan Marcotte 创建了一种他称之为“响应式网页设计”的方法,以支持具有不同尺寸显示屏的台式电脑以及移动设备 - 所有这些只需一个代码库。虽然这种方法并非必需,但可以视为朝着创建可访问体验的另一步。让我们更仔细地看看他的方法。

准备好了

Marcotte 在 2010 年 5 月 25 日的 A List Apart 期刊上发表了这篇文章:alistapart.com/articles/responsive-web-design。阅读这篇文章将让您提前了解本节的其余内容。

如何做...

让我们仔细观察 Jon Hicks 的作品集hicksdesign.co.uk,这是 Marcotte 方法的一个出色示例。

在 27 英寸显示器上以全宽度查看 Hicks 的作品集。

如何做...

调整窗口大小会导致网站从四列变为三列:

如何做...

进一步调整窗口大小会导致网站从三列变为两列:

如何做...

进一步调整窗口大小会导致网站从两列变为一列:

如何做...

它是如何工作的...

通过在样式表中使用灵活网格以及min-widthmax-width值,Hicks 创建了一个可以轻松适应不同显示尺寸的体验。让我们看看它是如何实现的。

还有更多...

这种新的灵活前端网页开发方式使我们能够创建不受设备分辨率限制的体验。多亏了 Marcotte,我们不再被迫为每个设备创建单独的体验。当前状态:一次编码,到处展示。

我们从一个可以适应任何屏幕空间的流体网格开始,灵活的图像,以及让媒体查询根据分辨率和视口提供独特样式表的方式。

这是一个样本媒体查询:

@media screen and (max-width: 600px) {
body {
font-size: 80%;
}
#content-main {float: none; width: 100%;}
}

你可以很容易地看到,当设备的最大宽度为 600 像素时,我们告诉body以 80%的高度显示字体。我们还指定 content-main div将成为 100%宽度的单列。如果设备的最大宽度为 601 像素或更多,这些规则将被忽略。请注意,由于这个媒体查询指定了屏幕,如果用户打印页面,这些规则也将被忽略。

最小宽度

正如你可以想象的那样,如果我们能够为窄宽度指定样式,你也可以为更宽的宽度指定其他样式,比如:

@media screen and (min-width: 1024px)

请注意,我们仍然在媒体查询中针对屏幕进行定位,但现在我们说只有在视口大于1024 像素时才应用一些样式。

我的数学老师是对的

那些习惯于使用像 Grid960 这样的刚性固定网格布局系统的人可能会发现使用灵活网格一开始是一种心理挑战。正如 Marcotte 所解释的:

"网格的每个方面——以及放置在其上的元素——都可以相对于其容器表达为一个比例。"

我们可以将基于像素的宽度转换为百分比,以保持我们的比例不变,无论显示的大小如何。让我们从一个简单的例子开始:假设我们的header宽度为 600 像素,我们想在一个宽度为 1200 像素的设备上显示它。如果方程式是目标 ÷ 上下文 = 结果,那么 600 ÷ 1200 = .5。我们的 CSS 会是这样的:

header {width: 50%; /* 600px / 1200px = .5 */}

这很容易。但是如果你想在 960 像素宽度上显示一个不同的header,那怎么办呢?简单的除法运算得出:510 ÷ 960 = .53125。我们可以这样调整我们的 CSS:

header {width: 53.125%; /* 510px / 960px = .53125 */}

通过将每个宽度定义为整体的一部分来重复这个过程,你将很快实现对多种设备的响应式显示。

更大总是更好吗?

流体图像甚至更容易,因为不需要进行数学计算。相反,只需包括:

img {max-width: 100%;}

在你的样式表中,这些图片将永远不会超出你的显示屏或设备的宽度。

将这三种技术结合在一起,可以为多个平台、浏览器甚至屏幕阅读器上的用户创造几乎无缝的网站体验。

另请参阅

2011 年,Marcotte 在books.alistapart.com/products/responsive-web-design上出版了关于响应式网页设计的权威书籍。

使用 hgroup 创建可访问的页眉区域

记得hgroups吗?当然记得。在前一章中,我们将其作为一种逻辑上组合相关标题标签的方式进行了讨论。现在,我们将看看这个新的 HTML5 元素如何带来额外的可访问性益处。

准备工作

之前,我们以 Roxane 的作品集为例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
</body>
</html>

在过去,我们可能会这样编写她网站的主体区域:

<body>
<div>
<div>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</div>
</div>
</body>

如何做...

对于屏幕阅读器来说,过时的第二个例子在语义上毫无意义。它不知道那些标题标签除了在同一个div中之外还有其他任何相关性。

它是如何工作的...

现在,由于 WHATWG 的 HTML5 草案标准在whatwg.org/html5,我们和屏幕阅读器都知道hgroup是相关标题的分组。那又怎样?如果你不能依靠视觉来知道这些标题是相关的,你难道不希望有其他机制 - 比如屏幕阅读器 - 来让你知道它们是相关的吗?

另请参阅

diveintoaccessibility.org是一个了解 508 部分和可访问性标准的绝妙的 30 天逐步资源。作者 Mark Pilgrim(也是diveintohtml5.orgDive Into HTML5的作者)提供了易于理解的提示,按照人员、残疾、设计原则、Web 浏览器和发布工具分类。该网站已经存在几年了,但由于多年来可访问性标准并没有发生太大变化,因此仍然是一种宝贵的免费资源。

为不支持的浏览器显示替代内容

一些新的 HTML5 元素是如此新,以至于并非所有桌面浏览器都支持它们。那么我们怎么能假设所有屏幕阅读器都会支持它们呢?

准备就绪

幸运的是,我们可以放心地知道屏幕阅读器将支持常见的文本标签,比如:

  • <h1>

  • <h2>

  • <h3>

  • <h4>

  • <h5>

  • <h6>

  • <p>

  • <ul>

  • <ol>

  • <li>

  • <dl>

  • <dt>

  • <dd>

以及其他预期的内容。但是对于那些新的 HTML5 元素,比如:

  • <文章>

  • <旁白>

  • <音频>

  • <画布>

  • <数据列表>

  • <详情>

  • <说明>

  • <图>

  • <页脚>

  • <头>

  • <hgroup>

  • <标记>

  • <表计>

  • <导航>

  • <输出>

  • <进度>

  • <部分>

  • <摘要>

  • <时间>

  • <视频>

这些是否会向用户传达我们的意思?如果是,那太棒了。但如果不是,用户会得到什么信息?这是否有意义?我们肯定会同意,我们最不希望的是通过我们的新标签提供更少的含义。即使盲人也能看到这将是一个史诗般的失败。

如何做...

在撰写本文时,许多 HTML5 元素至少提供了与屏幕阅读器相同数量的语义信息。让我们更具体地看看每个新元素:

  • <文章> - 与div具有相同的语义信息。

  • <旁白> - 与div具有相同的语义信息。

  • <详情> - 与div具有相同的语义信息。

  • <说明> - 与div具有相同的语义信息。

  • <图> - 与div具有相同的语义信息。

  • <页脚> - 与div具有相同的语义信息。

  • <头> - 与div具有相同的语义信息。

  • <hgroup> - 与div具有相同的语义信息。

  • <表计> - 与div具有相同的语义信息。

  • <导航> - 与div具有相同的语义信息。

  • <输出> - 与div具有相同的语义信息。

  • <进度> - 与div具有相同的语义信息。

  • <部分> - 与div具有相同的语义信息。

  • <摘要> - 与div具有相同的语义信息。

然而,对于其他新的 HTML5 元素,它们对屏幕阅读器的含义并不那么清晰:

  • <音频> - 语义信息似乎是一致的,但是火狐浏览器在内置滑块控件上有问题,IE 9 只有部分播放/暂停支持,Opera 有良好的键盘支持,但没有实际的辅助技术支持。

  • <画布> - 对辅助技术几乎没有可用的语义信息。任何依赖新的 HTML <canvas>元素传达信息的人都必须极度谨慎。有意使用它会让观众无法进入。

  • <数据列表> - 仅在 Opera 中可通过键盘访问。

  • <标记> - 不提供额外的语义信息。

  • <时间> - 仅在 Opera 中存在键盘访问的 bug。

  • <video>-语义信息似乎是一致的,但 Firefox 在内置滑块控件上有问题,Internet Explorer 9 只有部分播放/暂停支持,Opera 具有良好的键盘支持,但没有实际的辅助技术支持。

它是如何工作的...

目前,直到屏幕阅读器能够跟上所有新的 HTML5 元素,我们在决定使用哪些新标签以及我们打算用它们传达什么含义给使用辅助技术的人时,必须谨慎。

另请参阅

Emily Lewis 对 HTML 和 CSS 以及可用性、语义和可访问性都感到兴奋。她是我们需要更多的对前端 Web 开发世界充满热情的倡导者。请参阅她出色的“Web 可访问性和 WAI-ARIA 入门”了解如何开始思考可访问性的未来,网址为msdn.microsoft.com/en-us/scriptjunkie/ff743762.aspx

使用 WAI-ARIA

通过使用技术,我们已经开发出了在浏览器窗口中动态更新信息的方法,而无需手动从服务器刷新页面。对于有视力的人来说,这是一个福音,可以更快地检索信息并以更有用的方式呈现。但是当一个人看不见时会发生什么?他们如何知道页面上的信息已经以任何方式更新,而无需刷新页面,重新显示其内容,并让辅助技术再次完整地读给他们听?

准备就绪

可访问的丰富互联网应用程序(WAI-ARIA)是一项新兴的技术规范,就像 HTML5 的许多新语义标签一样,它迫使我们真正思考我们的内容以及我们想要如何向我们的受众呈现它。我们可以使用 WAI-ARIA 来定义角色、属性和状态,以帮助我们定义我们的元素应该做什么。

WAI-ARIA 概述位于w3.org/WAI/intro/aria,基于 Marcotte 的响应式 Web 设计方法。

准备就绪

如何做到这一点...

还记得我们在 Roxane 的作品集中包含了新的 HTML5 nav元素吗?以下是我们如何使用 WAI-ARIA 添加额外的含义:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roxane</title>
<!--[if lt IE 9]><script src="img/html5.js"> </script>[endif]-->
</head>
<body>
<header>
<hgroup>
<h1>Roxane is my name.</h1>
<h2>Developing websites is my game.</h2>
</hgroup>
</header>
<nav role="navigation">
<ul>
<li><a href="#About">About</a></li>
<li><a href="#Work">Work</a></li>
<li><a href="#Contact">Contact</a></li>
</ul>
</nav>
</body>
</html>

因为并非每个浏览器都理解nav标签,也并非每个浏览器都理解它的角色。WAI-ARIA 为我们提供了这样做的方法。role="navigation"被称为“地标角色”,对于无视力的人来说,它就像现实世界中的实际地标一样:它让他们知道自己在哪里。

它是如何工作的...

现在,即使没有视力的人也可以通过这些地标角色意识到页面上的变化。WAI-ARIA 通过“监视”更新来通知用户这些动态页面变化。与其重新阅读整个屏幕,只呈现新信息。

还有更多...

WAI-ARIA 允许我们创建复杂的、数据驱动的对象,如下拉菜单、选项卡、滑块、文件树等,这些是多年来有视力的用户已经习惯的,并且通过使用这些角色,即使那些无法看到内容更新的人也会被通知它已经这样做了。

仍在等待浏览器支持

总是有一个陷阱,对吧?在这种情况下,陷阱是,就像本书中描述的许多其他 HTML5 功能一样,WAI-ARIA 并不是所有辅助技术浏览器完全支持的。无论我们作为开发人员多么勤奋和善意,如果我们的目标受众没有具有 WAI-ARIA 支持的最新浏览器,他们将无法获得我们希望他们获得的信息。

这就是我的作用

还有一个问题:错误使用 WAI-ARIA 实际上可能会使情况变得更糟。如果比你水平低的开发人员将role="navigation"分配给一些经常更新但允许用户跳过导航的内容,那么用户将永远不会知道信息正在更新。幸运的是,这可能永远不会发生在你身上,因为你会在同行代码审查中发现这个错误。伟大的力量伴随着巨大的责任。

优先考虑无障碍

如果您正在开发网站,并且必须支持残疾人士,那么从最初的启动会议开始,必须非常小心,以确保满足他们的需求。最成功的无障碍项目是从一开始就考虑到人们的需求。试图在最后添加一系列功能只会让自己和项目失败。我们要么让人们和项目成功,要么让它们失败。你会选择哪一个?

另请参阅

有关如何使用 WAI-ARIA 构建更易访问的网络的更多阅读,请参阅 Scott Gilbertson 的这篇出色的 WebMonkey 文章:webmonkey.com/2010/11/can-wai-aria-build-a-more-accessible-web

后来,Gilbertson 又撰写了一篇关于使用 ARIA 角色为网站设计样式的绝佳资源:webmonkey.com/2011/01/styling-webpages-with-arias-landmark-roles

第五章:学会喜欢表单

在本章中,我们将涵盖:

  • 显示占位符文本

  • 为表单字段添加自动对焦

  • 使用 HTML5 和 CSS3 对表单进行样式设置

  • 使用电子邮件输入类型

  • 使用 URL 输入类型添加 URL

  • 使用数字标签

  • 使用范围标签

  • 创建搜索字段

  • 创建一个选择器来显示日期和时间

介绍

"我们已经遇到了敌人,他就是我们自己。" - Pogo

无聊。乏味。无聊。为什么当网页用户在网上看到交互式表单时,他们的眼睛会发直,头脑会麻木?这位作者认为,问题至少部分在于安排表单字段的信息架构师,而在较小程度上在于编码的前端开发人员。

诚然,表单并不性感。但是如果你是一个网页开发人员(如果你正在阅读这篇文章,很可能是这样),那么你的职业生涯中可能会有某个时候被要求标记和设计某种形式的表单。如果你害怕编写那个表单,想象一下你在用户身上制造的恐惧。现在结束了。

你已经成熟,并寻求值得这种成熟的新挑战。如果我们能停止担心并学会喜欢表单,那么我们的受众实际上也更有可能喜欢它们。

在本章中,我们将看一些 HTML5 用于交互式表单的实际例子,包括显示占位符文本,为表单字段添加自动对焦,使用 HTML5 和 CSS3 对表单进行样式设置,使用电子邮件输入类型,使用 URL 输入类型添加 URL,使用数字标签,使用范围标签,创建搜索字段,以及创建一个选择器来显示日期和时间。

现在让我们开始吧!

显示占位符文本

我们想要检查的第一个新的 HTML5 表单功能是本地显示占位符文本的能力。

如何做...

我们都曾使用过 - 甚至创建过 - 表单占位符文本。但现在有了 HTML5,我们将以稍有不同且更有效的方式来做。Packt Publishing 网站具有搜索整个网站或仅搜索书籍/电子书的功能。

如何做...

一旦用户点击这两个表单字段中的一个,占位符文本就会消失。

如何做...

这是通过使用值属性来显示占位符文本的传统方法:

<form action='/search'>
<div id="search-site">
<input type="text" class="form-text" name='keys' value="Search entire site" onclick='clearIf(this, "Search entire site")'/>
</div>
<div id="search-button-site">
<input type="image" src="img/search- button.png">
</div>
</form>
<form action='/books'>
<div id="search-books">
<input type="text" class="form-text" name='keys' value="Search only books/eBooks" onclick='clearIf(this, "Search only books/eBooks")'/>
</div>
<div id="search-button-books">
<input type="image" src="img/search- button.png">
</div>
</form>

使用placeholder属性而不是value会导致:

<form action='/search'>
<div id="search-site">
<input type="text" class="form-text" name='keys' placeholder="Search entire site" onclick='clearIf(this, "Search entire site")'/>
</div>
<div id="search-button-site">
<input type="image" src="img/search- button.png">
</div>
</form>
<form action='/books'>
<div id="search-books">
<input type="text" class="form-text" name='keys' placeholder="Search only books/eBooks" onclick='clearIf(this, "Search only books/eBooks")'/>
</div>
<div id="search-button-books">
<input type="image" src="img/search- button.png">
</div>
</form>

它是如何工作的...

placeholder属性可以取代value属性来在表单中显示占位符文本。在这种情况下,开发人员添加了一个onclick事件处理程序来适应旧版浏览器。这是另一个例子,优秀的语义增加了标签的额外含义。

还有更多...

记住 - 并计划 - 当用户点击每个表单字段时,占位符文本本身将消失。如果用户在不填写表单字段的情况下点击其他地方,placeholder将重新出现。

仅文本

placeholder属性只能包含文本。我们不能在其中包含其他标记、图像或任何其他元素。

拥抱斜体

默认情况下,占位符文本将以斜体显示。不幸的是,没有很好的方法来改变这一点。与其对头撞墙,不如事先知道这一点,并说服你的设计师,文本应该是斜体,并让他专注于真正重要的事情。

浏览器支持

支持新的placeholder属性的 Web 浏览器。

浏览器支持

另请参阅

Build Guild 是全国网页人员的每月聚会。使用 HTML5(并使用占位符属性!)在buildguild.org构建,开发人员可以每隔几周聚在一起喝酒聊天。已经在城市建立了本地分会,例如:德克萨斯州阿比林;纽约州奥尔巴尼;蒙大拿州比灵斯;密歇根州大急流城;康涅狄格州哈特福德;肯塔基州路易斯维尔;威斯康星州密尔沃基;纽约市,纽约州;宾夕法尼亚州费城;宾夕法尼亚州匹兹堡;密苏里州圣路易斯;马萨诸塞州塞勒姆。

如果你所在地区还没有 Build Guild,请创建一个!联系网站所有者buildguild.org开始!胡子是可选的。

为表单字段添加自动对焦

过去,我们不得不依赖 JavaScript 来为特定的表单字段添加输入焦点,但现在不再需要了!现在我们可以在 HTML5 中本地实现这个功能!

如何做...

Ally Creative 在他们的联系表单中有效地使用了autofocus功能,网址是allycreative.net/contact

如何做...

它是如何工作的...

他们是这样做的:

<form action="" method="post">
<ol id="left">
<li>
<label for="contact-name" class="label-fade">Jane Doe of ACME Corporation</label>
<input type="text" id="contact-name" name="contact-name" title="Name / Business" autofocus /></li>
<li>
<label for="contact-mail" class="label- fade">jane.doe@acme.com</label>
<input type="text" id="contact-mail" name="contact-mail" title="E-mail Addy" /></li>
<li>
<label for="contact-phone" class="label-fade">541 / 567- 5309</label>
<input type="text" id="contact-phone" name="contact-phone" title="Phone Number" /></li>
<li>
<label for="contact-budget" class="label-fade">Project Budget</label>
<input type="text" id="contact-budget" name="contact-budget" title="Budget" /></li>
<li><input type="hidden" id="contact-human" name="contact-human" title="Human" /></li>
</ol>
<ol id="right">
<li>
<label for="contact-subject" class="label-fade">Subject</label>
<input type="text" id="contact-subject" name="contact-subject" title="Budget" /></li>
<li>
<label for="contact-body" id="textarea-label" class="label- fade">Say something.</label>
<textarea id="contact-body" name="contact-body" title="Contact Copy"></textarea></li>
<li class="f-right"><span id="required"></span> <input type="image" src="img/button.png" id="submit-button" alt="Submit!" /></li>
</ol>
</form>

Ally Creative 的开发人员只需将autofocus属性应用于联系人姓名的表单字段,并添加适当的样式来改变背景颜色,就创建了一个流畅、互动的表单,用户很容易完成。

还有更多...

新的 HTML5 autofocus属性旨在适用于所有表单控件。所以无论你是收集用户的姓名、地址、电话号码还是其他数据,都要聪明地使用autofocus的能力!

每页一个

请记住,每个页面只能设置一个表单字段为autofocus

旧浏览器

一会儿,你会看到目前只有两个现代浏览器支持autofocus。幸运的是,旧浏览器会简单地忽略这个属性。考虑到像autofocus这样的工具可以丰富那些能看到它的用户的体验,而不会损害或降低那些使用较差浏览器的用户体验。无害,无犯。

浏览器支持

支持新的autofocus属性的 Web 浏览器:

浏览器支持

另请参阅

Mozilla 的“HTML5 的人”视频系列介绍了 HTML5 运动的许多领军人物。Remy Sharpe,我们在其他地方使用过的“HTML5 Shim”的作者,是一位 JavaScript 工匠。当他描述新 HTML5 规范的最喜欢的方面时,这应该不足为奇:

“对我来说,HTML5 最令人兴奋的方面是 JavaScript API 的深度。向 Joe Bloggs 解释,实际上这个新规范的 HTML 并不是大部分 HTML;它主要是 JavaScript,这是相当棘手的。”

阅读并观看完整的采访:hacks.mozilla.org/2011/01/people-of-html5-remy-sharp

使用 HTML5 和 CSS3 为表单设置样式

作者见过的使用 HTML5 和 CSS3 创建表单的最简单但最美丽的例子之一是加拿大 FoundationSix 的,网址是foundationsix.com/contact。他们是这样做的。

使用 HTML5 和 CSS3 为表单设置样式

如何做...

FoundationSix 团队从一个相当简单的联系表单标记开始。请注意,出于篇幅考虑,这个例子中省略了冗长的国家下拉列表。

它是如何工作的...

<form id="contactf6" method="post" action="http://foundationsix.com/index.php" enctype="multipart/form-data" >
<fieldset id="contactinfo">
<ul>
<li>
<label for="name">Name</label>
<input id="name" name="name" type="text" class="required">
</li>
<li>
<label for="email">Email</label>
<input id="email" name="email" type="text" class="required email">
</li>
<li>
<label for="website">Website</label>
<input id="website" name="website" type="text" class="required">
</li>
<li>
<label for="country">Country</label>
<select id="country" name="country" class="selectors">
<option selected value="">Please Select...</option>
</select>
</li>
</ul>
</fieldset>
<fieldset id="natureinfo">
<ul>
<li class="selectli">
<label for="nature">Nature</label>
<select id="nature" name="nature" class="selectors">
<option selected value="Get A Quote">Get A Quote</option>
<option value="Get More Info">Get More Info</option>
<option value="Say Hello">Say Hello</option>
</select>
</li>
<li class="selectli showmore">
<label for="scope">Scope</label>
<select id="scope" name="scope" class="selectors">
<option selected value="">Please Select...</option>
<option value="Complete Website Design">Complete Website Design</option>
<option value="Design Only">Design Only</option>
<option value="Coding Only">HTML / CSS Coding Only</option>
<option value="Other">Other</option>
</select>
</li>
<li class="selectli showmore">
<label for="budget">Budget</label>
<select id="budget" name="budget" class="selectors">
<option selected value="">Please Select...</option>
<option value="$2,500-$5,000">$2,500-$5,000</option>
<option value="$5,000-$7,500">$5,000-$7,500</option>
<option value="$7,500-$10,000">$7,500-$10,000</option>
<option value="$10,000-$15,000">$10,000-$15,000</option>
<option value="$15,000-$20,000">$15,000-$20,000</option>
<option value="$20,000-$50,000">$20,000-$50,000</option>
<option value="$50,000+">$50,000+</option>
</select>
</li>
<li class="selectli showmore">
<label for="timeframe">Timeframe</label>
<select id="timeframe" name="timeframe" class="selectors">
<option selected value="">Please Select...</option>
<option value="Right Away">Right Away</option>
<option value="Within 1 Month">Within 1 Month</option>
<option value="Within 2 Months">Within 2 Months</option>
<option value="Within 3 Months">Within 3 Months</option>
<option value="Within 6 Months">Within 6 Months</option>
<option value="Don't Know Yet">Don't Know Yet</option>
</select>
</li>
</ul>
</fieldset>
<fieldset id="message">
<ul>
<li>
<label for="messagetext">Message</label>
<textarea id="messagetext" name="message"></textarea>
</li>
</ul>
</fieldset>
<div id="submitbutton"><input type="submit" name="submit"></div>
</form>

团队为这个联系页面提供了一个特殊的样式表。请注意它是多么干净,只定义了必要的值,而省略了任何多余的东西。

html {
background: url(../img/sitebg.jpg) repeat; -webkit-font-smoothing: antialiased;
}
body {
color: #8a8a8a; font: 13px/19px "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; background: url(../img/subbg.jpg) repeat-x;
}
#contactform {
float: left; width: 498px; margin-bottom: 40px;
}
#formtop {
height: 97px; width: 498px; background: url(../img/formtop.png) no-repeat;
}
#formtop h1 {
text-indent: -9999px; width: 445px; height: 57px; margin: 0 auto; background: url(../img/formheader.png) no-repeat; position: relative; top: 39px;
}
#formcontent {
background-image: url(../img/formrepeat.png); width: 498px; background-position: 1px;
}
form {
width: 445px; margin: 0 auto;
}
form label {
font: 13px "ClarendonRoman", Georgia, Times, serif; color: #525250; letter-spacing: 2px; text-transform: uppercase; float: left; position: relative; top: 4px;
}
form label.error {
text-transform: none; letter-spacing: 0; color: #a21714; font: 15px "SeanRegular", Courier New, Courier New, Courier6, monospace; margin-top: -10px; clear: both; padding: 0px 0px 10px 21px; background: url(../img/errow.png) no-repeat 0 0;
}
form ul {
padding-top: 10px;
}
form ul li {
padding-top: 10px; clear: both; overflow: hidden;
}
form ul li.selectli {
padding-bottom: 10px;
}
form select, form input {
float: right;
}
form input {
border-bottom: 1px dashed #989895; border-right: none; border-left: none; border-top: none; color: #4f4f4f; background: none; outline: none; position: relative; bottom: 13px; font: 16px "SeanRegular", Courier New, Courier New, Courier6, monospace; letter-spacing: 1px;
}
form input:focus {
border-bottom: 1px dashed #000; -webkit-transition:border 0.3s ease-in; -moz-transition:border 0.3s ease-in; -o-transition:border 0.3s ease-in; transition:border 0.3s ease-in;
}
form select {
width: 300px;
}
input#name {
width: 370px;
}
input#email {
width: 360px;
}
input#website {
width: 340px;
}
fieldset#contactinfo {
padding-bottom: 23px; border-bottom: 1px solid #a7a7a4;
}
fieldset#natureinfo {
margin-top: 4px;
}
fieldset#message {
background: url(../img/messagebar.png) top no-repeat; width: 445; margin-top: 25px;
background: url(../img/messagebar.png) top no-repeat; width: 445; margin-top: 25px;
}
fieldset#message label {
display: none;
}
textarea#messagetext {
margin-top: 4px; width: 445px; height: 150px; border: none; background: none; outline: none; resize: none; overflow: auto; color: #4f4f4f; font: 16px "SeanRegular", Courier New, Courier New, Courier6, monospace; letter-spacing: 1px; float: left; display: block;
}
#submitbutton {
float: right;
}
#submitbutton input {
cursor: pointer; background: url(../img/submit.png) no-repeat; width: 445px; height: 86px; border: none; text-indent: -9999px; position: relative; bottom: 10px;
}
#submitbutton input:hover {
background-position: 0 -86px;
}
span#formbottom {
background: url(../img/formbottom.png) no-repeat; width: 498px; height: 108px; display: block;
}
#othercontact {
float: right; width: 566px; margin-bottom: 40px;
}
#map {
width: 552px; height: 269px; background: url(../img/map.jpg) center no-repeat rgb(233,233,228); background: url(../img/map.jpg) center no-repeat rgba(255,255,255,0.3); padding: 6px; border: 1px solid rgb(249,249,248); border: 1px solid rgba(255,255,255,0.7); margin-bottom: 28px; position: relative;
}
span#mappointer {
width: 77px; height: 80px; display: block; position: absolute; top: 66px; left: 257px; background-image: url(../img/map-pin.png);
}
section.subcontact {
float: left; width: 267px; position: relative; padding-left: 3px; border-top: 6px solid #d3d2c5; -webkit-transition:border 0.4s ease-in; -moz-transition:border 0.4s ease-in; -o-transition:border 0.4s ease-in; transition:border 0.4s ease-in;
float: left; width: 267px; position: relative; padding-left: 3px; border-top: 6px solid #d3d2c5; -webkit-transition:border 0.4s ease-in; -moz-transition:border 0.4s ease-in; -o-transition:border 0.4s ease-in; transition:border 0.4s ease-in;
}
section.subcontact:hover {
border-top: 6px solid #cc7b58; -webkit-transition:border 0.3s ease-in; -moz-transition:border 0.3s ease-in; -o-transition:border 0.3s ease-in; transition:border 0.3s ease-in;
}
section.subcontact h2 {
padding-top: 17px; color: #5a5a5a; font: 20px "ClarendonRoman", Georgia, Times, serif; margin-bottom: 10px; letter-spacing: -0.05em;
}
section.subcontact p {
margin-bottom: 16px; width: 260px;
}
section.subcontact.subright {
position: relative; left: 25px;
}
ul.iconlist {
padding-top: 6px;
}
ul.iconlist li {
padding: 12px 25px; border-top: 1px dashed #b2b2ab;
}
li#mapicon {
background: url(../img/icons/map.png) no-repeat 0 14px;
}
li#emailicon {
background: url(../img/icons/mail.png) no-repeat 0 13px;
}
li#vcardicon {
background: url(../img/icons/card.png) no-repeat 0 13px;
}
li#twittericon {
background: url(../img/icons/twitter.png) no-repeat 0 13px;
}
li#docicon {
background: url(../img/icons/doc.png) no-repeat 3px 13px;
}

还有更多...

大部分情况下,为 HTML5 添加层叠样式表就像为 XHTML 或以前版本的 HTML 添加 CSS 一样。只是现在我们有额外的标签需要跟踪。

提示

请记住,HTML5 和 CSS3 是两回事。人们经常把它们混在一起——就像他们对“Web 2.0”这个术语做的那样,直到这个术语最终失去了所有意义(如果它确实有任何意义的话)。我们会滥用“HTML5”这个术语,以至于最终失去所有意义吗?或者它已经发生了?只有你才能防止森林火灾。

旧浏览器

在为 HTML5 设置样式时,我们需要注意两件事:

  1. 当一些新元素还不被所有浏览器支持时,如何为其设置样式。

  2. 当新的 HTML5 元素在任何给定的浏览器中不被支持时,备用方案是什么样子的。

测试,测试,测试

在样式化 HTML5 时,关键是在浏览器中进行测试。为了我们的客户和整个网络开发的利益,我们被迫了解在浏览器中发生的事情,并根据我们的经验进行调整。

关于伪类

CSS3 提供了一些新的伪类,用于区分必填表单字段和非必填字段。我们将把这些与内置的 HTML5 表单验证结合起来:

  • :required - 让我们根据所需的内容来设置字段样式

  • :optional - 让我们根据所需的内容来设置字段样式

  • :valid - 将与表单验证一起使用

  • :invalid - 将与表单验证一起使用

  • :in-range - 适用于最小和最大字符,比如电话号码

  • :out-of-range - 适用于最小和最大字符,比如电话号码

另请参阅

如果您想尝试使用 CSS3 来样式化 HTML5,Blue Griffon 的开发人员创建了bluegriffon.org,这是一个新的所见即所得的网络内容编辑器。该工具支持多种语言,允许用户在不太考虑代码的情况下使用网络标准。

使用电子邮件输入类型

HTML5 支持的众多新输入类型之一是email。有多少次您使用<input type="text" />构建表单,意图收集电子邮件地址?现在我们可以使用更具语义的东西!稍后,我们将看到这也支持表单验证。

如何做...

以前的 FoundationSix 示例可以很容易地转换为这种新的输入类型。而不是:

<li>
<label for="email">Email</label>
<input id="email" name="email" type="text" class="required email">
</li>

我们可以简单地更改输入类型,最终得到:

<li>
<label for="email">Email</label>
<input id="email" name="email" type="email" class="required email">
</li>

在视觉上,<input type="email" />标签看起来与<input type="text" />完全相同。区别在于浏览器对信息的处理方式。

工作原理...

将类型从"text"更改为"email"允许较新的浏览器验证用户输入的是否真的是有效的电子邮件地址。请注意,服务器无法确定电子邮件帐户是否处于活动状态,只能确定地址本身是否格式良好。

还有更多...

那么,如果提交的电子邮件地址无效会发生什么?事实上,情况仍未明朗。Opera 浏览器有一个实验性的错误消息,Firefox 有自己的实验性附加组件。不幸的是,这是一个灰色地带,我们必须耐心等待浏览器以一致的方式处理它。

浏览器支持

但是关于<input type="email" />的酷炫之处在于:浏览器支持它!嗯,有点。即使不理解<input type="email" />的浏览器也会默认回到<input type="text" />,所以它仍然有效。太棒了!

无需 JavaScript

正如我们将在其他情况下看到的那样,HTML5 中的<input type="email" />允许我们停止使用 JavaScript 来实现类似的结果。我们不再需要使用行为层来弥补标记或表现层的不足。

验证的发展

表单验证已经从互联网的开始发展。在最早期,开发人员被迫使用诸如 CGI 脚本之类的技术来提交表单并完全重绘结果页面。只有在页面提交到服务器之后,用户才能知道他们的信息是否被接受。如果没有,他们就必须重新开始。

随着时间的推移,开发人员学会了使用 AJAX 来执行表单的客户端验证。这很有效,但重要的工作落在了 JavaScript 身上。当 JavaScript 被关闭或需要满足无障碍要求时,这就带来了挑战。

现在有了 HTML5,一些验证可以在浏览器中进行,而不需要将信息发送到服务器或依赖 JavaScript。虽然不如 AJAX 解决方案那样强大,但这种类型的验证可以捕获许多最常见的错误类型。

使用 URL 输入类型添加 URL

HTML5 支持的许多新输入类型之一是URL。你有多少次构建了一个使用<input type="text" />的表单,意图收集一个网站地址?现在我们可以使用更语义上正确的东西!稍后我们将看到这也支持表单验证。

如何做...

以前的 FoundationSix 示例也可以轻松转换为这种新的输入类型。而不是:

<li>
<label for="website">Website</label>
<input id="website" name="website" type="text" class="required">
</li>

我们可以简单地更改输入类型,最终得到:

<li>
<label for="website">Website</label>
<input id="website" name="website" type="URL" class="required">
</li>

<input type="email" />一样,<input type="URL" />标签在视觉上看起来与<input type="text" />相同。不同之处再次在于浏览器对输入的信息的处理方式。

工作原理...

将类型从"text"更改为"URL"允许更新的浏览器验证用户输入的是否实际上是一个有效的网站地址。请注意,服务器无法确定网站是否活动,只能确定地址本身是否格式良好。

还有更多...

那么,如果提交的网站地址无效会发生什么?事实上,这里的情况还不明朗。不幸的是,这是一个灰色地带,我们需要耐心等待,直到浏览器以一致的方式处理它。

浏览器支持

但是,关于<input type="URL" />的酷事在于:浏览器支持它!嗯,有点。即使不理解<input type="URL" />的浏览器也会默认回到<input type="text" />,所以它仍然有效。太棒了!

无需 JavaScript

正如我们将在其他情况下看到的那样,HTML5 中的<input type="URL" />允许我们停止使用 JavaScript 来实现类似的结果。我们不再需要使用行为层来弥补标记或表示层的不足。

接下来是什么?

随着浏览器的发展,将来我们可能会看到一些实现,允许浏览器对<input type="URL" />做一些更智能的事情,比如预取一个网站图标以在评论字段中显示。时间会告诉我们。

另请参阅

乐队 Arcade Fire 与电影制作人 Chris Milk 合作,为 Chrome 浏览器创建了基于乐队歌曲"We Used To Wait"的互动在线电影"The Wilderness Downtown",网址为thewildernessdowntown.com,完全使用 HTML5 和 CSS3。该网站因其使用画布、HTML5 视频、谷歌地图等而成为有史以来最受关注的 HTML5 体验之一。

使用数字标签

HTML5 现在允许用户在一系列数字中进行选择。例如,如果您希望您的观众购买商品,您可能希望他们使用整数。毕竟,谁会订购 2 双鞋半?

如何做...

如果我们继续以购买鞋子的例子,我们可以开发一个这样的表单:

<form>
<label>How many shoes would you like to purchase?<label>
<input type="number" name="quantity" min="2" max="6" step="2" value="2" size="4" />
</form>

请注意,在input中,我们可以选择性地指定可以订购的最小数量(2)和最大数量(6)。在这种情况下,step允许我们确保用户只能以成对的方式订购鞋子,而value设置了显示的初始数量。然后,size控制input框的宽度。

工作原理...

指定<input type="number">将显示带有上下箭头的新表单控件,允许用户增加和减少字段中的值。这些通常被称为“微调器”或“微调框”。您还可以设置此字段的增量:

工作原理...

还有更多...

新的<input type="number" />标签在在线电子商务之外还有用途。例如,我们可以想象一个非营利组织使用它来设置一个允许用户捐赠固定金额的表单。由于组织有时会为不同的捐款金额提供奖品,表单可以被创建为只允许以这些最低增量输入。

浏览器支持

目前<input type="number" />只受 Opera 以及基于 Webkit 的浏览器(如 Chrome 和 Safari)支持。但是关于<input type="number" />有个很酷的事情:像<input type="email" /><input type="URL" />一样,其他浏览器也支持它!嗯,有点。就像这些标签一样,即使不理解<input type="number" />的浏览器也会默认回到<input type="text" />,所以它仍然有效。太棒了!

没有 JavaScript

正如我们将在其他示例中看到的那样,HTML5 中的<input type="number" />允许我们停止使用 JavaScript 来实现类似的结果。我们不再需要使用行为层来弥补标记或表现层的不足。

使用 range 标签

HTML5 现在允许我们创建一种全新的输入方式。range 标签创建了一个滑块控件,允许用户在一系列值中进行选择。这以前很困难,但现在不是了!看看吧!

如何做...

有趣的是,我们可以使用几乎与数字示例中相同的代码,只是将输入类型更改为"range"。以下是如何做到的:

<form>
<label>How many shoes would you like to purchase?<label>
<input type="range" name="quantity" min="2" max="6" step="2" value="2" />
</form>

请注意,我们可以使用相同的可选min、max、step、valuesize属性。

它是如何工作的...

指定<input type="range">将显示带有滑块的新表单控件,允许用户增加和减少字段中的值:

它是如何工作的...

还有更多...

<input type="range">标签还有许多其他用途,远远超出了电子商务。实际上,由于我们看不到当前选择的值,购物可能不是这个新标签的最佳用途。作者可以想象使用<input type="range">用于基于 Web 的音乐播放应用程序,用户可以在不必看到特定音量数字的情况下,直观地增加或减少音量。

使用时要小心

不幸的是,没有非 JavaScript 的方法来显示范围输入标签的当前选择值。希望随着 HTML5 的进一步定义和更多浏览器支持其原生控件,我们将能够更好地控制它。在那之前,请谨慎使用。

没有 JavaScript

正如我们将在其他示例中看到的那样,HTML5 中的<input type="range" />允许我们停止使用 JavaScript 来实现类似的结果。我们不再需要使用行为层来弥补标记或表现层的不足。

浏览器支持

<input type="number" />一样,目前<input type="range" />只受 Opera 以及基于 Webkit 的浏览器(如 Chrome 和 Safari)支持。但是关于<input type="range" />有个很酷的事情:像<input type="email" /><input type="URL" /><input type="number" />一样,其他浏览器也支持它!嗯,有点。就像这些标签一样,即使不理解<input type="range" />的浏览器(Firefox,我在看你!)也会默认回到<input type="text" />,所以它仍然有效。太棒了!

另请参阅

Mozilla 的“HTML5 的人”视频系列展示了 HTML5 运动的许多主要声音。作者 Bruce Lawson 非常有趣和权威,尤其是当他批评将 HTML5 用作泛指相关但不同技术的术语时:

“客户和记者将使用'HTML5'来表示 CSS 3/在 iThings 上运行的视频/地理位置启用的应用程序。这是新的'Web 2.0'。但我们从业者需要搞清楚我们的命名。没有 HTML5 图像转换,就像没有 CSS 语义一样-说有这些东西表明你没有理解 2001 年关于分离样式和内容的备忘录。”

阅读并观看完整的采访:hacks.mozilla.org/2011/01/people-of-html5-bruce-lawson

创建搜索字段

HTML5 支持的许多新输入类型之一是search。您有多少次构建了一个使用<input type="text" />的表单,打算允许用户搜索网站?现在我们可以使用更具语义的东西。

如何做...

让我们使用占位属性构建一个快速搜索字段。到目前为止,您已经熟悉了这种过时的方法:

<form>
<input name="something" type="text" value="keyword" />
<input type="submit" value="Search" />
</form>

我们都做过无数次了,对吧?好吧,让我们试试这个:

<form>
<input name="something" type="search" placeholder="keyword" />
<input type="submit" value="Search" />
</form>

发现了区别吗?我们的类型已从text更改为search,占位文本不再使用 value 标记。这对我们开发人员以及搜索引擎和辅助技术更有意义。

它是如何工作的...

指定<input type="search">将在 Opera 以及 Chrome 和 Safari 等基于 Webkit 的浏览器中显示带有圆角的新表单字段:

它是如何工作的...

还有更多...

圆角搜索框是苹果在 OSX 上以及 iPad 和 iPhone 上推广的设计方法。苹果正在逐渐成为移动体验的思想领袖,以及 HTML5 的最积极的倡导者之一。

为什么要修复完美?

当然,可以覆盖新的 HTML5 搜索字段的默认圆角样式,但为什么呢?它已经看起来很酷了!

浏览器支持

这已经成为一个熟悉的叮嘱,但是就像<input type="email" /><input type="URL" /><input type="number" /><input type="range" />一样,您可以放心,如果浏览器不原生理解<input type="search" />,它将继续像<input type="text" />一样进行处理。

搜索结果

新的search规范还支持新的results属性,以在下拉列表中显示已搜索的术语。

另请参阅

别管子弹在nevermindthebullets.com是一个互动在线游戏,专门用来演示微软 Internet Explorer 9 能够处理的 HTML5 和 CSS3 功能,包括:@font-face;<canvas>动画;<header><section>布局;JavaScript 加速;CSS3 2D 变换;CSS3 多背景;可编辑内容;<audio>音轨播放器;<video>播放器。

创建一个选择器来显示日期和时间

每个飞机、火车和汽车租赁网站都将拥有某种时间/日期选择器。终于有了一个语义方法来处理这个问题,所以让我们看看如何使用 HTML5 创建这些input类型。

提示

截至目前,只有 Opera 浏览器完全支持这些新的input标签。

如何做到...

HTML5 实际上有六种不同的新input,可以控制日期和时间。简而言之,它们是:

  • <input type="date" />

  • <input type="datetime" />

  • <input type="datetime-local" />

  • <input type="month" />

  • <input type="time" />

  • <input type="week" />

这些input类型可以被认为是彼此的变体。作为开发人员,我们的工作是选择最适合您收集的数据的那种。

它是如何工作的...

对于日期选择器:

<form>
<input type="date"/>
</form>

对于日期/时间选择器:

<form>
<input type="datetime"/>
</form>

对于本地日期/时间选择器:

<form>
<input type="datetime-local"/>
</form>

对于月/年选择器:

<form>
<input type="month"/>
</form>

对于时间选择器:

<form>
<input type="time"/>
</form>

对于周选择器:

<form>
<input type="week"/>
</form>

还有更多...

鼓励您尝试每个新的基于日历的input标签,以确定哪个最适合您特定的网站或应用程序。

浏览器支持

截至目前,只有 Opera 完全支持这些新的input标签。随着时间的推移,其他浏览器预计会赶上。一旦我们拥有完全可样式化的基于日期/时间的input方法,那将是一个真正快乐的日子。

与此同时,其他浏览器将默认显示这些input类型为纯文本框。它们仍然可以工作,但不会像我们希望的那样漂亮。耐心点,小草 hopper。记住,我们正在处理最新的技术——而不是完全成熟、经过验证和批准的方法。

如果一切都失败了

User Agent Man 撰写了一篇关于当你需要备用计划时该怎么做的文章,当这些各种新的 HTML5 input标签不按你期望的方式工作时。查看完整文章:useragentman.com/blog/2010/07/27/cross-browser-html5-forms-using-modernizr-webforms2-and-html5widgets

另请参阅

Forrst.com是由 Kyle Bragger 使用 HTML5 创建的一个很棒的在线资源。Forrst 是一个充满活力的网络开发者和设计师社区,他们相信通过分享和建设性地批评彼此的工作,可以增加他们对网站创建工艺的知识、技能和热情。我们很欣赏他们的工作态度。

第六章:使用 Canvas 开发丰富的媒体应用程序

在本章中,我们将涵盖:

  • 设置canvas环境

  • 理解 2D 渲染上下文

  • 动态处理形状

  • 使用canvas为图像绘制边框

  • 圆角

  • 创建交互式可视化

  • 弹跳球

  • 创建备用内容

介绍

“我更喜欢画画而不是说话。画画更快,也给谎言留下的空间更少。”- 勒·柯布西耶

这可能是整本书中最实验性的一章。在接下来的配方中,我们将真正推动这组配方所能实现的极限。

注意

请注意,随着时间的推移,实验性的新canvas元素规范可能会发生变化。请将这组配方视为出版时可能的情况的快照。

在网站上放置一张图片是如此容易,我们现在认为这是理所当然的。通过代码,你只需告诉浏览器显示一张图片,就完成了。所有这些似乎都像是小孩子的游戏。目前,一些浏览器实际上可以使用新的canvas元素动态创建图像。所有繁重的工作都交给了 JavaScript。

新的开源canvas元素的很酷之处不仅在于你可以动态地创建图像,而且用户的操作也可以实时地创建新的图像,而无需插件。听起来很棒,对吧?在许多方面确实如此,但它也让我们使用辅助技术的朋友们感到束手无策。

提示

如果你使用的浏览器不支持新的canvas元素会发生什么?基本上什么都不会发生。浏览器只是不会显示它。这就是为什么你需要特别小心这项技术,不要在新的canvas元素中放置任何你的网站或应用程序绝对依赖的东西。你还必须考虑备用内容。

支持canvas的浏览器包括:

介绍

提示

在继续使用新的canvas元素进行开发之前,请确保你对 HTML 和 JavaScript 有扎实的基础。对面向对象编程感到舒适肯定也是有好处的。

在本章中,我们将看到设置canvas环境的真实例子,理解 2D 渲染上下文,动态处理形状,使用canvas为图像绘制边框,圆角,创建交互式可视化,弹跳球以及创建备用内容。

现在,让我们开始吧!

设置canvas环境

创建新的canvas元素很容易。

如何做...

看看这是多么简单:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="FirstCanvas" width="800" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

它是如何工作的...

当然,我们可以使用任何需要的高度和宽度尺寸,但是我们需要开始的是这组简单的标签。

提示

你可能会认为我们可以使用 CSS 来控制高度和宽度,但要抵制这种诱惑。因为新的canvas元素包含一个 2D 渲染上下文,这种方法可能会导致不可预测的行为。

还有更多...

接下来,我们将调用新的canvas元素 JavaScript API,同时调用 jQuery:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
$(document).ready(function() {
var canvas = document.getElementById("FirstCanvas");
var ctx = canvas.getContext("2d");
});
</script>
</head>
<body>
<canvas id="FirstCanvas" width="800" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

他很聪明

“让我完全明确一件事:当你使用canvas时,你并不是在canvas元素本身上绘图。相反,你实际上是在通过 JavaScript API 访问canvas元素的 2D 渲染上下文上绘图。”- Rob Hawkes

我在说什么?

苹果最早在 OSX Dashboard 中引入了新的canvas元素。后来它在 Safari 和 Chrome 等 web 浏览器中实现,其他浏览器也纷纷效仿。从那时起,它已成为 HTML5 规范的正式部分。

<canvas>的下一步是什么?

现在,我们只是勉强触及了新的canvas元素所能做到的一小部分。现在和将来,我们将使用它来创建动画,图表,图表,绘图应用程序,图形和用户界面。你会想到什么呢?

另请参阅

开发者 Martin Angelov 为 Tutorial Zine 撰写了一篇名为《使用 Canvas 和 jQuery 创建 HTML5 幻灯片》的很棒的指南:tutorialzine.com/2010/09/html5-canvas-slideshow-jquery。在这篇文章中,Martin 演示了如何将新的 canvas 元素与 jQuery 结合使用,这是最流行的 JavaScript 框架,以创建一个非常互动的图像幻灯片。

理解 2d 渲染上下文

重要的是要理解,新的canvas元素实际上是一个在浏览器中绘制位图图像的“表面”。

如何做...

像这样定义一个canvas标签只是讲了一半的故事:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="FirstCanvas" width="800" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

它是如何工作的...

单独的 HTML5 代码什么也做不了。我们必须使用 JavaScript 来使文档对象模型检索 2d 渲染上下文,以便让一些事情发生:

<script>
$(document).ready(function() {
var canvas = document.getElementById("FirstCanvas");
var ctx = canvas.getContext("2d");
});
</script>

公平地说,如果 HTML 中没有canvas标签,那么这一点 JavaScript 也不会起作用。

还有更多...

你可能会想到这个名字。如果有一个 2d 渲染上下文,那么可能也有一个 3d 渲染上下文吧?简短的答案是肯定的。但更详细的答案并不那么简单。

虽然在理论上存在 3d 渲染上下文,但在本出版物发表时,没有浏览器支持它。所以如果新的canvas元素以 3d 方式渲染,但没有人看到它,它真的做了什么吗?

你可以掌握

2d 上下文为新的canvas元素使用了许多不同的绘图上下文,这些语法应该对熟悉 CSS 和 JavaScript 的人来说看起来非常熟悉。

X,见 Y

在绘制时,请记住浏览器窗口左上角的 X 和 Y 轴。数值向下增加。

尊重我的权威!

万维网联盟的 HTML5Canvas 2d 上下文规范可以在这里找到:dev.w3.org/html5/2dcontext。在那里,我们可以深入了解诸如符合性要求、canvas状态、变换、合成、颜色和样式、线条样式、阴影、简单形状、复杂形状、焦点管理、文本、图像、像素操作、绘图模型、示例等更多信息。

另请参阅

Steve Fulton 和 Jeff Fulton 为 O'Reilly Books 撰写了《HTML5 Canvas》一书。虽然本章将为您提供大约 30 页有价值的新canvas元素配方,但 Fulton 的书大约有 400 页。把它当作是本章结束后的资源。在这里查看:oreilly.com/catalog/0636920013327

动态处理形状

让我们来看看允许新的canvas元素绘制矩形的 JavaScript 函数。

如何做...

fillRect(x,y,width,height)
strokeRect(x,y,width,height)

按顺序:

fillRect(x,y,width,height)

画一个填充的矩形。接下来,

strokeRect(x,y,width,height)

在矩形周围画出一个轮廓。

现在,让我们画一些形状。

它是如何工作...

我们将从我们的基本canvas代码开始,并整合我们的新函数:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
$(document).ready(function() {
var canvas = document.getElementById("FirstCanvas");
var ctx = canvas.getContext("2d");
ctx.strokeRect(10, 10, 396, 236);
ctx.fillStyle = "red";
ctx.fillRect(11, 11, 100, 100);
ctx.fillStyle = "white";
ctx.fillRect(111, 11, 34, 100);
ctx.fillStyle = "red";
ctx.fillRect(156, 11, 249, 100);
ctx.fillStyle = "white";
ctx.fillRect(11, 111, 394, 34);
ctx.fillStyle = "red";
ctx.fillRect(11, 145, 100, 100);
ctx.fillStyle = "white";
ctx.fillRect(111, 145, 34, 100);
ctx.fillStyle = "red";
ctx.fillRect(156, 145, 249, 100);
});
</script>
</head>
<body>
<canvas id="FirstCanvas" width="416" height="256">
<p>Flag of Denmark</p>
</canvas>
</body>
</html>

我们创建的东西类似于丹麦的国旗!

它是如何工作的...

还有更多...

这个例子一开始可能并不令人印象深刻,但当你记住我们几乎没有使用任何 HTML 和 CSS 就创建了一张图片时,新的canvas元素开始看起来相当令人印象深刻。

任何你想要的方式

请注意,虽然我们使用了颜色名称(“white”和“red”),我们也可以使用十六进制值或 RGB 甚至 HSL!使用对你和你的互动项目最有意义的内容。

类似于表格?

将此示例的颜色和大小规格几乎视为我们过去用于布局的老式tables。虽然肯定不同,但在这种情况下确实有一些相似之处。

首先成为一个正方形

掌握矩形是在掌握设置元素本身的能力之后,重要的第一个canvas技术。理解这种方法的基础将帮助你掌握接下来几个配方的基础。

另请参阅

另一本将近 400 页的书是 Rob Hawkes 的《Foundation HTML5 Canvas: For Games and Entertainment》,来自 Friends of Ed。在这本书中,Hawkes 为那些刚接触新的“画布”元素的人,一直到最有经验的专家提供了一个提升技能的出版物。听起来像你认识的人吗?在这里查看:friendsofed.com/book.html?isbn=1430232919

使用画布为图像绘制边框

让我们仔细看看使用新的“画布”元素绘制图像周围边框的超级简单方法。

如何做...

首先,我们将从基本的“画布”代码开始,并添加一行新的代码来绘制边框:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
$(document).ready(function() {
var canvas = document.getElementById("FirstCanvas");
var ctx = canvas.getContext("2d");
ctx.strokeRect(10, 20, 100, 100);
});
</script>
</head>
<body>
<canvas id="FirstCanvas" width="800" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

如何做...

它是如何工作的...

JavaScript 的那一行告诉浏览器创建一个矩形,从新的“画布”元素的左边 10 像素,顶部 20 像素开始。它绘制了一个 100 像素的正方形框。

还有更多...

这很好,但如果我们希望边框是除了默认颜色之外的任何其他颜色,我们需要指定它:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
$(document).ready(function() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "rgb(0, 128, 0)";
ctx.strokeRect(10, 20, 100, 100);
});
</script>
</head>
<body>
<canvas id="myCanvas" width="600" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

在这种情况下,我们使用strokeStyle来指定纯绿色的 RGB 颜色。

还有更多...

首先是样式

提示

如果你打算为边框设置样式,你需要在浏览器绘制边框之前指定。如果你在之后指定样式,浏览器将会忽略它。

许多颜色值都可以使用

我们刚刚使用的样式属性是 RGB,但该方法也适用于颜色(例如“绿色”)、十六进制值、HSL 和 RGBA。

我喜欢大边框,我无法否认

如果没有指定边框宽度,浏览器将自动绘制一个像素的边框。以下是如何更改它的方法:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
$(document).ready(function() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 10;
ctx.strokeStyle = "rgb(0, 128, 0)";
ctx.strokeRect(10, 20, 100, 100);
});
</script>
</head>
<body>
<canvas id="myCanvas" width="600" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

就是这么简单:

我喜欢大边框,我无法否认

另请参阅

rgraph.net是一个专门为新的“画布”元素设计的图形库。它允许您轻松创建各种图表类型:条形图、双极图、圆环图、漏斗图、甘特图、水平条形图、LED 显示、折线图、仪表、里程表、饼图、进度条、玫瑰图、散点图和传统的雷达图,使用 HTML5、canvas和 JavaScript。

圆角

到目前为止,我们已经使用方形或矩形形状创建了图像和边框。接下来,我们将看看如何使用新的“画布”元素通过 JavaScript 来使这些图像和边框的角变圆。

如何做...

圆角的能力不是canvas的本机功能,但 Rob Hawkes 是一个非常聪明的人,他想出了如何实现它的方法。这就是 Rob 做的事情,在这里解释:rawkes.com/blog/2010/12/11/rounded-corners-in-html5-canvas.

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
$(document).ready(function() {
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");
var rectX = 10;
var rectY = 10;
var rectWidth = 100;
var rectHeight = 100;
var cornerRadius = 15;
context.lineJoin = "round";
context.lineWidth = cornerRadius;
context.strokeStyle = "rgb(0, 128, 0)";
context.strokeRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);
});
</script>
</head>
<body>
<canvas id="myCanvas" width="600" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

它是如何工作的...

首先,Rob 选择了一个稍微不同的方法来调用 2d“画布”渲染上下文,但他的方法也完全有效。看看:

$(document).ready(function() {
var canvas = $("#myCanvas");
var context = canvas.get(0).getContext("2d");

Rob 代码的下一部分应该看起来非常熟悉:他设置了图像的 X 和 Y 坐标,它的大小,然后是边框半径:

var rectX = 10;
var rectY = 10;
var rectWidth = 100;
var rectHeight = 100;
var cornerRadius = 15;

然后 Rob 调用了连接线和他想要使用的特定边框半径的能力。假装直到你成功为止!

context.lineJoin = "round";
context.lineWidth = cornerRadius;

最后是边框的颜色(仍然是绿色!)和将所有内容联系在一起的最后一小部分脚本:

context.strokeStyle = "rgb(0, 128, 0)";
context.strokeRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);

还有更多...

现在 Rob-如果你也在跟着做-可以成为一个拥有美丽圆角图像的摇滚明星。

还有更多...

就像学术能力测试一样

提示

记住:lineWidth对于新的“画布”元素来说就像 border-radius 对 CSS 来说一样。它们都实现了同样的功能-但是方式完全不同。

IE 呢?

可以使用 ExplorerCanvas 库在 Internet Explorer 6-8 中支持一些新的“画布”元素的功能:code.google.com/p/explorercanvas.

我们正在奠定基础

在本章的大部分食谱中,我们只使用了新的canvas元素在浏览器中绘制静态形状,而没有使用图像。这可能看起来毫无事件,甚至可能违反直觉。重点是为您提供这种新能力的坚实基础,以便您可以扩展它,使用新的canvas元素创建游戏,可视化数据,并允许用户动态绘制对象。

另请参阅

Mozilla 的“HTML5 的人”视频系列中有许多 HTML5 运动的领军人物。John Foliot 是 HTML5 中媒体元素无障碍子委员会的联合主席。当他为这些技术当前浏览器支持的状况感到懊恼时,这一点应该不足为奇:

“我认为 HTML5 开始提供的许多东西对所有用户都有好处,包括使用辅助技术的用户。然而,许多承诺的东西在所有浏览器中尚不受支持,相关技术——辅助技术——还有很长的路要走才能利用这一好处。”

阅读并观看完整的采访:hacks.mozilla.org/2011/02/people-of-html5-john-foliot.

创建交互式可视化

Carbon Five 团队面临着一个艰巨的任务:创建他们的技能和兴趣的物理图。他们可能从办公室的墙开始,但很快意识到新的canvas元素带来的新能力将允许交互性,并且可以根据此进行结论。以下是他们在这里所做的:carbonfive.github.com/html5-playground/interest-map/interest-map.html.

创建交互式可视化

如何做...

提示

在按照本食谱操作时,查看源代码将非常有帮助:view-source:http://carbonfive.github.com/html5-playground/interest-map/interest-map.html

Carbon Five 团队提醒我们,画布并不是 HTML5 规范的正式部分,他们使用 HTML4.01 Transitional DOCTYPE 创建了这个交互式可视化。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

以下是他们在 JavaScript 和新的canvas元素中所做的一些详细内容。他们从一些变量开始,比如卡片样式。在这里,他们做了几件事情:设置背景颜色,创建黑色边框,卡片的宽度,以及围绕它的阴影的值。

var CARD_STYLE = { fill:'rgb(240,240,240)',stroke:'rgb(0,0,0)',width:.05, shadow:{x:0, y:4, blur:4, color:'rgba(0, 0, 0, 0.3)'} };

下一个变量对于了解 CSS 的人来说应该很熟悉。在这里,设置了卡片的字体重量、大小、字体、颜色等等:

var CARD_FONT = {font:'bold 8pt Courier', color:'#555', yoffset:10, height:14};

接下来,他们设置了与边距、宽度、高度、比例、半径、阴影等相关的几个变量。

var MARGIN = [75,75,75,100], WIDTH = 1000-MARGIN[1]-MARGIN[3], HEIGHT = 650-MARGIN[0]-MARGIN[2], CARD_SCALE=.75, CARD_RADIUS = 40, TAG_RADIUS = 50, CACHE_RADIUS=70, CLEAR_RADIUS = 50, ITERATIONS = 20, DEGREE = .5, CARD_SHADOW = 2, AXIS_ANIM=700;

最后,他们为技能、人员和人员与技能矩阵设置了变量。不幸的是,这些代码块太长,无法在此重新发布。

它是如何工作的...

变量本身并不会有太大作用,除非它们有函数来对其进行操作。

在初始化显示后,Carbon Five 团队使用更多的函数,比如在 2Dcanvas渲染元素上绘制:

function draw(t) {
var ctx = el('display').getContext('2d');
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.save(); ctx.globalAlpha = 1 - .75*arrow_visibility;
each( cards, function(card) {
var t0=card.tween(t); x = MARGIN[3] + card.lx + (card.x-card.lx)*t0, y = MARGIN[0] + card.ly + (card.y-card.ly)*t0;
draw_card( ctx, x, y, card.index);
});
ctx.restore();
if ( arrow_visibility > 0 ) {
ctx.save(); ctx.globalAlpha = arrow_visibility;
each( PEOPLE, function(p) { draw_interest_arrow(ctx,p,t); });
ctx.restore();
if (over_person) draw_over_arrow(ctx,over_person,t);
}
draw_axes(ctx);
}

以及创建名称标签:

function nametag( ctx, cardx, cardy, person, r, interest ) {
ctx.save(); ctx.translate( cardx, cardy ); ctx.rotate( r + .4*(Math.random()-.5) );
ctx.translate( -TAG_RADIUS - + 4*Math.random(), 0 ); ctx.rotate( -r );
draw_nametag( ctx, person, interest );
ctx.restore();
}

并绘制箭头:

function draw_arrow( ctx, length, head_length, head_width ) {
var cx1 = .9*(length - head_length), cy1 = .2*head_width, cx2 = (length - head_length), cy2=.2*head_width;
ctx.beginPath();
ctx.moveTo(0,0);
ctx.bezierCurveTo( cx1, cy1, cx2, cy2, length-head_length, head_width );
ctx.lineTo( length, 0 ); ctx.lineTo( length-head_length, -head_width );
ctx.bezierCurveTo( cx2, -cy2, cx1, -cy1, 0, 0 );
ctx.closePath();
}

还有更多...

已经设置了变量和函数,最后要做的就是在 HTML 中调用canvas元素本身,为其提供一个运行的空间:

<canvas id="display" width="1000" height="650"></canvas>

两个出租人的邪恶

在旧网页时代,Carbon Five 团队可以选择将他们的地图放在物理墙上,或者为计算机显示创建静态图像。虽然任何一种方式都可以渲染得和使用新的canvas元素一样好,但它们都不允许团队像新的canvas元素那样提取有价值的信息。

备用内容呢?

有趣的是,Carbon Five 在这种情况下没有在新的“画布”元素中使用任何回退内容。这是一个你需要仔细权衡的方法,因为那些使用旧浏览器或辅助技术的人将什么也看不到,真的什么也看不到。Carbon Five 在这个内部项目中得以成功。你能吗?

接受他的提议。

blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1上写关于这个项目时,Carbon Five 的开发者亚历克斯·克鲁克山甚至提出为前五个以合理格式提供数据的人创建可视化地图。截至发布日期,尚不清楚是否有人接受了他的提议。

另请参阅

雅各布·赛德林用他的新画布元素可视化了乐队 Radiohead 的歌曲“Idioteque”,这首歌来自专辑“Kid A”,网址是:nihilogic.dk/labs/canvas_music_visualization。雅各布正在挑战“画布”元素和 JavaScript 的极限,这就是为什么我们认为他很棒!

弹跳一个球

我们已经看过如何使用新的“画布”元素绘制形状,接下来我们将把注意力转向让这些形状移动起来。作者文森·鲁弗斯向我们展示了如何做到这一点。

如何做...

我们将从我们通常的canvas HTML 代码开始:

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="FirstCanvas" width="800" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

接下来是独特的部分:JavaScript。在这里,文森选择了一个稍微不同的方法来调用 2D“画布”渲染上下文,但他的方法也完全有效。看看:

<script>
var context;
function init()
{
context= myCanvas.getContext('2d');
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100, 100 on the canvas
context.arc(100,100,20,0,Math.PI*2,true); context.closePath();
context.fill();
}
</script>

将这些代码放在一起,应该是这样的。请注意,添加了一个onLoad函数到body标签。

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
var context;
function init()
{
context= myCanvas.getContext('2d');
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100, 100 on the canvas
context.arc(100,100,20,0,Math.PI*2,true); context.closePath();
context.fill();
}
</script>
</head>
<body onLoad="init();">
<canvas id="myCanvas" width="300" height="300">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

然后渲染这个蓝色的球:

如何做...

它是如何工作的...

到目前为止,文森的代码非常简单。我们看到他是如何调用 2D“画布”渲染上下文的。接下来他设置了填充的颜色:

context.fillStyle="#0000ff";

然后画一个距离顶部和左边 100 像素的弧线,并用他已经设置的蓝色填充它:

context.arc(100,100,20,0,Math.PI*2,true); context.closePath();
context.fill();

但现在我们只有一个蓝色的球静静地坐在那里。接下来,文森向我们展示了如何使用变量和一个名为draw的新函数让它移动。

还有更多...

<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<meta charset="utf-8" />
<script src="img/ jquery.min.js"></script>
<script>
var context;var x=100;var y=200;var dx=5;var dy=5;
function init()
{
context= myCanvas.getContext('2d');
setInterval(draw,10);
}
function draw()
{
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100, 100 on the canvas
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
x+=dx;
y+=dy;
}
</script>
</head>
<body onLoad="init();">
<canvas id="myCanvas" width="300" height="300" >
</canvas>
</body>
</html>

还有更多...

正如你所看到的,球在运动,但只是画了一条直线超出了“画布”的边缘。文森解释了原因:

“这是因为每次调用draw()函数时,它都会在新的坐标处画一个圆圈,而不会移除旧的圆圈。这就是getContext对象的工作原理,所以这不是一个 bug;它实际上并没有移动圆圈,而是每次调用函数时在新的坐标处画一个圆圈。”

重新开始

文森向我们展示了一种方法,可以在新的“画布”元素绘制每一个新的圆圈时擦除旧的圆圈:

<script>
var context;
var x=100;
var y=200;
var dx=5;
var dy=5;
function init()
{
context= myCanvas.getContext('2d');
setInterval(draw,10);
}
function draw()
{
context.clearRect(0,0, 300,300);
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100, 100 on the canvas
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
x+=dx;
y+=dy;
}
</script>

现在,球似乎向右下方超出了“画布”的边界。

不要把我困住

为了确保球保持在“画布”的边界内,文森编写了一些逻辑来检查 x 和 y 坐标是否超出了“画布”的尺寸。如果超出了,他就让球改变方向。

<script>
var context;
var x=100;
var y=200;
var dx=5;
var dy=5;
function init()
{
context= myCanvas.getContext('2d');
setInterval(draw,10);
}
function draw()
{
context.clearRect(0,0, 300,300);
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 20 at the coordinates 100, 100 on the canvas
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
// Boundary Logic
if( x<0 || x>300) dx=-dx;if( y<0 || y>300) dy=-dy;x+=dx;y+=dy;
}
</script>

现在,球应该在“画布”的四个边上不断地弹跳。

不要把我困住

这是一个成长的过程

正如文森在他引人入胜的教程中提醒我们的那样,弹跳的球乍看起来可能很简单,但实际上这是一个关键的技术,需要理解才能开发任何新的 HTML5“画布”元素游戏。

另请参阅

可以在 Yuri Vishnevsky 的weavesilk.com上看到用户生成的图形的一个美丽的例子。该网站使用新的canvas元素作为生成艺术实验的一部分。一些生成的图像非常漂亮,Yuri 已经将它们作为令人惊叹的桌面背景图像提供。还计划推出 iPhone 和 iPad 版本。

创建回退内容

“当作者使用canvas元素时,他们还必须提供内容,当呈现给用户时,传达与位图canvas本质上相同的功能或目的。此内容可以放置为canvas元素的内容。canvas元素的内容(如果有)是元素的回退内容。”- WHATWG HTML5 规范

如果有人查看您的精彩新canvas应用程序的浏览器使用较旧的浏览器,并且无法识别您的编码天赋会发生什么?或者当有人使用辅助技术时会发生什么?让我们来看看。

如何做到...

如果出于某种原因,用户的浏览器不支持新的canvas元素,作为开发人员,我们要为他们提供有价值的东西。

在这里我们可以使用图像作为回退。

<canvas id="clock" width="200" height="200">
<img src="img/clock.gif" width="200" height="200" alt="clock"/>
</canvas>

或者文本:

<canvas id="clock" width="200" height="200">
<p>clock</p>
</canvas>

或者几乎任何其他元素。

它是如何工作的...

到目前为止,您已经熟悉了alt标签如何用于图像文件:如果图像文件不显示或用户依赖辅助技术,alt标签至少为他们提供了一个有价值的文本标签,代表他们所错过的内容。新的canvas元素的回退内容是一个类似的概念,但它能够做到并且比只是一个alt标签更有价值。

还有更多...

支持新的canvas元素的浏览器将忽略容器内的内容,并正常呈现新的canvas元素。

谢谢,Mozilla

如果需要回退内容,必须使用一些 CSS 技巧来掩盖 Safari 中的回退内容(应该只呈现canvas),并且还要掩盖 IE 中的 CSS 技巧本身(应该呈现回退内容)。- Mozilla.org

我们将如何处理可访问性?

规范作者和 HTML5 社区普遍认为新的canvas元素只是部分成熟。让使用辅助技术的人置身于寒冷中似乎不是正确的做法。敬请关注。

我们准备好使用了吗?

许多开发人员认为新的canvas元素的可访问性是新 HTML5 规范中的最后一个关键点。由于几乎没有有意义的回退功能,这个新元素似乎还没有准备好投入使用。

第七章:使用 JavaScript 进行交互

在本章中,我们将涵盖:

  • 使用 JavaScript 播放音频文件

  • 使用拖放 API 与文本

  • 使用vid.ly和 jQuery 实现跨浏览器视频支持

  • 使用 jQuery 动态显示视频

  • 使用 jQuery 创建可移动的视频广告

  • 使用Easel.jscanvas标签控制图像的显示

  • 使用Easel.jscanvas标签来制作图像序列的动画

  • 使用canvas标签和 JavaScript 进行随机动画播放音频

介绍

虽然 HTML5 可能会结束对 Flash 的使用,但它使 JavaScript 比以前更受欢迎。有许多库和插件可用于增强和扩展 HTML5 和 CSS3,以创建丰富的交互体验。

本章包含了一些示例,展示了 JavaScript 如何与 HTML5 标签一起使用,例如音频、视频和画布,以及 CSS3 选择器和元素。

使用 JavaScript 播放音频文件

HTML5 在互联网上使用音频文件方面引入了更多的灵活性。在这个示例中,我们将创建一个游戏来练习使用音频标签和 JavaScript 加载和播放声音。

准备工作

您需要一个音频文件来播放,一张图片和一个支持 HTML5 的现代浏览器。本章的示例文件可以从www.packtpub.com/support?nid=7940下载。Free Sound Project (freesound.org)有您可以使用的音频文件,只要给予制作人信用,照片可以在www.Morguefile.com找到,用于您的个人项目。

如何做...

现在我们准备创建一系列按钮和一个简短的 JavaScript 程序,当其中一个按钮被按下时,将播放一个随机的音频文件。

打开您的 HTML 编辑器并创建一个 HTML5 页面的开头部分。

<!DOCTYPE html><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Playing a sound file with JavaScript</title>

因为我们只有几种样式,所以我们将它们添加到 HTML 页面的头部区域。

<style>h1{font-family:"Comic Sans MS", cursive; font-size:large; font-weight:bold;}
button{ padding:5px;margin:5px;}
button.crosshair { cursor: crosshair; }
button.crosshairthree {margin-left:40px;
cursor:crosshair;} </style>

脚本需要创建三个变量。开头的脚本标签和变量应该看起来像以下代码块:

<script>//variables
var mySounds=new Array();
mySounds[0]="boing";
mySounds[1]="impact";
mySounds[2]="squeak";
mySounds[3]="whack";
mySounds[4]="space";
var soundElements;
var soundChoice;

现在我们已经为脚本创建了全局变量,我们可以创建函数。键入function whackmole(){开始函数,然后在新行上键入var i = Math.floor(Math.random() * 5);使用 JavaScript 数学库生成一个相对随机的数字。接下来,键入soundChoice = mySounds[i];将数组值分配给soundChoice。使用soundElements[soundChoice].play();}关闭函数。您的函数代码目前应该看起来像以下内容:

function whackmole() {
var i = Math.floor(Math.random() *5);
soundChoice = mySounds[i];
soundElements[soundChoice].play();}

键入function init(){开始函数。在新行上,键入soundElements = document.getElementsByTagName("audio");} </script>来完成我们的 JavaScript 代码块。它应该看起来像以下代码块:

function init(){
soundElements = document.getElementsByTagName("audio");}
</script>

关闭头标签并键入 body 标签,添加一个init()函数调用,使其看起来像:

</head><body onLoad="init();">

使用<header>标签为页面的页眉区域创建一个标题区域。使用标题标签<h1>显示页面的标题:

<header><h1>Whack A Mole!</h1></header>

有五个按钮来创建一个平衡的外观,它们都被分配了一个类。

<section> <p> <button class="crosshair" onclick="whackmole();"> <img src="img/downmole.png" width="37" height="24" alt="Mole peeping out of hole"></button>
<button class="crosshair" onclick="whackmole();"> <img src="img/downmole.png" width="37" height="24" alt="Mole peeping out of hole"></button></p>

第三个按钮的类名为crosshairthree,以便更好地控制其在屏幕上的位置。

<p style="padding-left:30px;"><button class="crosshair" onclick="whackmole();"><img src="img/downmole.png" width="37" height="24" alt="Mole peeping out of hole"></button></p> <p><button class="crosshair" onclick="whackmole();"> <img src="img/downmole.png" width="37" height="24" alt="Mole peeping out of hole"></button><button class="crosshair" onclick="whackmole();"><img src="img/downmole.png" width="37" height="24" alt="Mole peeping out of hole"></button></p></section>

如果您正在使用本书的代码文件,那么音频文件标签应该类似于下面的代码块:

<section><audio id ="boing" autobuffer>
<source src="img/cartoonboing.ogg" />
<source src="img/cartoonboing.mp3" /></audio>
<audio id ="impact" autobuffer>
<source src="img/cartoonimpact.ogg" />
<source src="img/cartoonimpact.mp3" /></audio>
<audio id ="squeak" autobuffer>
<source src="img/cartoonsqueak.ogg" />
<source src="img/cartoonsqueak.mp3" /></audio>
<audio id ="whack" autobuffer>
<source src="img/cartoonwhack.ogg" />
<source src="img/cartoonwhack.mp3" /></audio>
<audio id="space" autobuffer>
<source src="img/cartoonspaceboing.ogg" />
<source src="img/cartoonspaceboing.mp3" /></audio>

用关闭标签完成页面:

</section></body></html>

将文件保存为playing-audio-files-with-javascript.html并在浏览器中查看。它应该看起来类似于以下屏幕截图:

如何做...

它是如何工作的...

首先,我们创建了一个基本的 HTML5 页面的开头。然后,我们添加了 CSS 样式,为按钮添加背景图像,并在鼠标或指针设备移动到按钮上时将鼠标图标更改为十字准线。这给了我们一个视觉上的模拟目标武器,比默认的鼠标图标更有趣。

创建了三个变量供脚本使用:mySounds, soundElementssoundch。我们创建的第一个函数名为whackmole()包含一个内部变量i,它保存了一个随机生成的数字的结果。Math.random()导致生成一个伪随机数。然后我们将其乘以5,我们的音频文件数量,并使用Math.floor()的结果创建一个值范围从零到五的整数。然后将该值分配给临时变量i,然后用于使用随机生成的数组值填充变量mySounds。这个新的数组值存储在变量soundChoice中,soundChoice = mySounds[i]。这使我们能够在按下按钮时使用soundElements[soundChoice].play()触发audio标签的play()动作。

我们创建的第二个函数是init(),稍后我们将其与body标签绑定,使用onLoad,这样我们就可以使用audio标签及其数组值,通过getElementsByTagName获取音频文件,如soundElements变量中所包含的。

接下来,我们添加了<body onLoad="init();">标签,以及一系列包含我们可爱的鼹鼠图像的按钮到页面上。每个按钮都包含一个onClick()事件,调用了whackmole()函数。我们的第三个按钮与其他按钮的类不同,crosshairthree,它在按钮左侧添加了额外的边距,使其看起来更加居中。

注意

火狐目前有一个怪癖,如果你不先列出.ogg音频源,它就找不到。

最后,我们使用<audio><source>标签将声音文件添加到页面。使用源标签列出了每个文件的oggmp3格式。因为源标签被认为是其所包围的父音频标签的“子”标签,所以根据使用的浏览器,任何文件格式都会播放,因为不同的浏览器目前更喜欢不同的声音文件格式。

还有更多...

您可以看到,通过为不同的图像播放不同的声音文件,非常容易创建一个儿童的形状或动物朗读页面等应用程序。

使用 jQuery 控制音频剪辑的外观

jQuery 中的.animate函数打开了新的方式,当访问者采取行动或作为丰富媒体体验的一部分时,可以使音频控件出现、淡出和消失。以下是一个示例,演示了如何使音频控件淡出,然后迅速重新出现:

<script> $(document).ready(function(){
$('audio').delay(500).hide('fade', {}, 1000 ).slideDown('fast'); }); </script>
<!- - the HTML -- ><audio id ="boing" autobuffer> <source src="img/cartoonboing.ogg" /> <source src="img/cartoonboing.mp3" /></audio>

我们将在本章的一个示例中使用视频文件执行类似的技巧。

另请参阅

第八章,“拥抱音频和视频”将涵盖更多关于音频标签及其使用方式的信息。

使用文本的拖放 API

虽然所有浏览器都可以原生地拖放图像或链接,但放置对象以前需要复杂的 JavaScript 或第三方库。拖放 API 旨在提供一种更简单、标准化的方式,使用户能够将任何类型的对象拖放到标识区域中。实际上,在各种浏览器中使用该 API 是一项挑战。目前主要支持此 API 的浏览器是 Firefox、Chrome 和 Safari。

准备工作

www.packtpub.com/support?nid=7940下载本教程的代码。本教程标题中使用的字体来自www.fontsquirrel.com,您也可以在该网站下载其他字体。本教程可能无法在 Internet Explorer 中使用。我们将创建一个井字棋游戏,演示拖放 API 的工作原理。

如何做...

打开您的 HTML 编辑器,首先创建一个基本的 HTML5 页面。我们将添加两个样式表链接,一个用于支持我们将加载到页面标题的@fontface字体,另一个是我们的主样式表。输入如下所示的代码,然后将文件保存为using-drag-drop-api.html

<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <title>Using the drag-and-drop API element</title> <link rel="stylesheet" href="fonts/specimen_files/specimen_stylesheet.css" type="text/css" charset="utf-8" /> <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" />

让我们继续对页面进行样式设置。创建或打开名为stylesheet.css的 CSS 文件。将页面的整体margin设置为100px,默认颜色设置为#666

@charset "UTF-8";/* CSS Document */body { margin:100px; color:#666; }

页面的内容标签应该都设置为display:block,如下所示的代码:

article, aside, figure, footer, header, hgroup, menu, nav, section { display:block; }

现在,我们要指定@fontface信息。代码和字体文件来自www.fontsquirrel.com字体包,已包含在本教程的代码文件中。

@font-face { /* This declaration targets Internet Explorer */ font- family: '3DumbRegular';src: url('3dumb-webfont.eot');}@font-face {/* This declaration targets everything else */font-family: '3DumbRegular';src: url(//:) format('no404'), url('fonts/3dumb- webfont.woff') format('woff'), url('fonts/3dumb-webfont.ttf') format('truetype'), url('fonts/3dumb-webfont.svg#webfontlNpyKhxD') format('svg');font-weight: normal;font-style: normal;}

h1标签添加颜色,并将font-family属性设置为3DumbRegular,这是我们字体的名称。

h1{color:#C60;font-family: '3DumbRegular';}

创建一个名为gametilebox的新 div,用于容纳组成游戏瓷砖的字母。将盒子的float属性设置为left,宽度和高度设置为280px。根据以下代码片段设置padding, margin-right, borderbackground-color

#gametilebox{ float:left;width:280px; height:280px; padding:10px; margin-right:30px; border:1px solid #000; background-color:#ccc; }

游戏板将共享许多与瓷砖框相同的属性,因此复制gametilebox的样式,然后粘贴并命名为"gameboard"。添加一个background-image属性,url 为images/tictactoegrid.jpg,并将background-color设置为aa

gameboard div应该如下所示代码:

#gameboard { float:left; width:280px; height:280px; padding:10px; margin-right:30px;border:1px solid #000; background-image:url(images/tictactoegrid.jpg); background-color:#aaa;}

让我们对div块进行样式设置,用于放置我们的字母。所有block div 的float应设置为leftwidth不应大于85pxheight不应大于80px。它们将位于 3x3 的网格上,因此第二行和第三行的第一个块也需要具有clear:both属性。第二行和第三行的第三个块应该具有较低或没有paddingmargin-right属性。因为有九个,所以这里只显示了一个块代码的示例:

#blockA {float:left; width:75px; height:75px; padding:5px 5px 5px 2px; margin-right:10px; border:none; background-color:red;}
#blockB {float:left; width:75px; height:75px; padding:5px; margin-right:10px; border:none; background-color:blue;}

现在,我们将为字母游戏瓷砖设置样式。在样式表中创建一个名为lettertile的新类,然后按照这里显示的属性设置类的属性:

.lettertile { width:60px; height:60px; padding:5px; margin:5px; text-align:center; font-weight:bold;font-size:36px;color:#930; background-color:transparent;display:inline-block;}

我们将添加的最后一个样式是draggable属性。创建下面的样式以帮助跨浏览器兼容性:

*[draggable=true] { -moz-user-select:none; -khtml-user-drag: element; cursor: move;}

样式表已经完成,现在我们可以开始编写脚本来拖动字母瓷砖并放置它们。

打开之前创建的 html 页面using-drag-drop-api.html,并为 IE 浏览器输入以下代码:

<!--[if IE]><script src="img/html5.js"> </script><![endif]-->

在样式表链接的下方直接添加一个开头的<script>标签,并输入第一个函数dragDefine(ev),该函数接受一个事件参数,并在后面加上{。在大括号后面,输入ev.dataTransfer.effectAllowed ='move';然后,在新的一行上,输入ev.dataTransfer.setData("text/plain", ev.target.getAttribute('id'));以设置数据类型和目标属性。最后,输入return true;并加上一个闭合的}来完成函数。

function dragDefine(ev) {ev.dataTransfer.effectAllowed = 'move'; ev.dataTransfer.setData("text/plain", ev.target.getAttribute('id')); return true;}

现在,我们需要定义dragOver函数。输入dragOver(ev)和一个开头的{,然后通过添加ev.preventDefault()来调用preventDefault()函数。函数块应该类似于下面的代码:

function dragOver(ev) { ev.preventDefault();}

我们需要的下一个函数是指示拖动完成的函数。输入function dragEnd(ev),然后一个开头的{。输入return true; }来完成函数。

输入function dragDrop(ev)并加上一个开头的{,然后换行添加我们的第一个方法。输入var idDrag = ev.dataTransfer.getData("Text")来创建一个将保存文本字符串的拖动变量,然后输入ev.target.appendChild (document.getElementById(idDrag))。完成函数后,输入ev.preventDefault()。函数块应该如下所示代码:

function dragDrop(ev) {
var idDrag = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(idDrag));
ev.preventDefault();} </script>

关闭页面的头部部分。输入<body><header>,然后<h1>拖放井字棋</h1></header>来完成页面的标题。

</head><body><header><h1>Drag and Drop Tic Tac Toe</h1></header>

接下来,输入<section><h3>将字母从灰色框拖到游戏板上(然后再拖回去!)</h3>

创建一个 ID 为"gametilebox"的 div,并设置ondragover ="dragOver(event)"ondrop="dragDrop(event)"。它应该如下所示:

<div id="gametilebox" ondragover="dragOver(event)" ondrop="dragDrop(event)">

现在,我们将为每个游戏瓷砖创建一个div。创建六个"X"瓷砖和六个"O"瓷砖,每个都以从1-12的数字结尾的id开始。每个div将包含类"lettertile",每个draggable属性将包含值"true"。每个瓷砖还将包含ondragstart="return dragDefine(event)"ondragend="dragEnd(event)"div块应该看起来像以下代码:

<div id="lettertile1" class="lettertile" draggable="true" ondragstart="return dragDefine(event)" ondragend="dragEnd(event)">X</div>
<div id="lettertile2" class="lettertile" draggable="true" ondragstart="return dragDefine(event)" ondragend="dragEnd(event)">X</div>
<div id="lettertile3" class="lettertile" draggable="true" ondragstart="return dragDefine(event)" ondragend="dragEnd(event)">X</div>

现在,我们可以为我们在stylesheet.css中创建的块样式创建实际的divs。首先键入<div id= "gameboard">。应该为每个块 id 创建一个div,从"blockA"到"blockI"。它们每个都将包含一个ondragover="return dragOver(event)"和一个ondrop="dragDrop(event)"。它们应该看起来像以下代码块。

<div id="blockA" ondragover="return dragOver(event)" ondrop="dragDrop(event)"></div>
<div id="blockB" ondragover="return dragOver(event)" ondrop="dragDrop(event)"></div>
<div id="blockC" ondragover="return dragOver(event)" ondrop="dragDrop(event)"></div>

bodyhtml的闭合标签关闭页面,将文件命名为"using-drag-drop-api.html",然后在浏览器窗口中查看结果。拖动几个字母,结果应该类似于以下截图:

如何使用拖放 API,使用文本

它是如何工作的...

首先,我们创建了一个基本的 HTML5 页面,并使用@fontface添加了一个草图字体作为标题,以使我们的游戏具有有趣的视觉效果。接下来,我们通过将margin设置为body和所有块级元素的display:block来为页面设置样式,以便更好地控制这些元素的呈现。在样式化标题字体后,我们为游戏瓷砖框定义了widthheight。这将是容纳组成游戏瓷砖的字母的容器。

我们通过在 IE 浏览器中键入一个特殊的注释标签来开始我们的脚本,以指向一个额外的脚本文件来触发 HTML5 元素:<!--[if IE]><script src="img/html5.js"></script><![endif]-->。这是由 Remy Sharp(http://remysharp.com/html5-enabling-script/)根据 MIT 许可证提供的,以在处理 Internet Explorer 时保持我们的理智。

当用户开始拖动物品时,dragDefine()函数被调用。它首先检查物品是否可拖动,使用dataTransfer.effectAllowed='move'。然后,它将要传输的数据类型设置为text,并使用dataTransfer.setData("text/plain")target.getAttribute('id'))来识别目标的id。该函数返回 true,表示可以拖动对象。

接下来,我们定义了dragOver函数,当拖动的物品位于另一个物品上时调用,接受一个名为ev的事件参数,然后使用它来调用preventDefault()以允许放置物品。拖放 API 规范明确规定,我们必须取消拖动,然后准备放置。

然后创建了dragEnd()函数,当拖动完成时返回 true。它还接受一个事件参数。

完成所有拖动功能后,我们准备创建代码来放置物品。dragDrop()函数接受一个事件参数,并使用该值获取文本对象的值,然后将其传递给一个新变量var idDrag来保存文本字符串,然后再使用getElementById来识别正确的元素 ID 进行放置。就像dragEnd()一样,我们必须调用拖放 API 中的preventDefault()函数来指示可以放置对象。

在关闭页面的头部区域后,在 body 中放置了内容框来容纳我们的字母瓷砖和游戏板块。这些由两个父 div 容器组成,每个容器都包含包含字母瓷砖或游戏板网格部分的子 div。

游戏瓷砖框在拖动字母瓷砖时调用了dragOver()函数。字母瓷砖 div 本身通过draggable="true"变得可拖动,并在拖动时返回dragDefine()。当拖动停止时,它们调用dragEnd()函数。

因为我们希望字母块能够被放下并停留在游戏板的特定区域,我们为网格上的每个单独的块创建了 div,以便在它们被放到板上时保持我们的字母在那里,并在对象被拖动到它们上方时返回dragOver事件,并在对象被放到它们上时调用dragDrop()

为什么要费心设置块 div?我们本可以在左边设置我们的游戏块盒子,右边设置游戏板,然后就完成了。结果会是,当我们从左边的盒子拖动块到游戏板时,它们会被放下并按照它们被放下的顺序排列,而不是我们想要放置它们的地方。这种默认行为在你想要对列表进行排序时很好,但当需要精确控制对象放置位置时就不行了。

我们需要覆盖当对象被放下时产生的默认行为。我们创建了九个游戏板块,都是相同的基本大小。每个块的主要变化是paddingmargin

花几分钟时间阅读www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html上的拖放规范,你会注意到他们明确表示他们只定义了一个拖放机制,而不是你必须执行的操作。为什么?因为使用智能手机或其他触摸屏设备的用户可能没有鼠标等指针设备。

还有更多...

这个拖放 API 的演示可以通过多种方式构建成一个完整的游戏,包括计分、游戏板重置按钮和其他交互元素。

创建一个基于画布的井字棋游戏

可以使用两个画布,一个用于游戏块盒子,另一个用于游戏板。可以使用画布动态绘制板和游戏块,然后在屏幕上写入分数或消息,比如“你赢了”。

在用户玩游戏时显示响应消息

Remy Sharp 在html5demos.com/drag-anything上有一个很棒的演示,展示了当一个对象被放下时如何在屏幕上显示消息。

要被放下的对象的源标签类似于:

<div id="draggables"><img src="img/picean.png" alt="Fish" data-science-fact="Fish are aquatic vertebrates (animals with backbones) with fins for appendages." /> </div>

当对象被拖动到时,“放置区”框可能如下所示:

<div class="drop" id="dropnames" data-accept="science-fact"> <p>Learn a science fact!</p> </div>

当图像被放入框中时,你会看到包含在“data-science-fact”中的文本,而不是图像。

另请参见

jQuery 的 Packt 书籍,本书中的其他配方,以及高级 HTML5 的 Packt 书籍。

使用 vid.ly 和 jQuery 支持跨浏览器视频

支持大多数浏览器需要将视频编码为多种格式,然后将正确的格式提供给浏览器。在这个配方中,我们将使用一个名为 vid.ly 的在线视频显示库(www.vid.ly),在多个浏览器上可靠地准备和分享视频,并在页面上改变背景颜色。

准备工作

你需要一个视频上传到www.vid.ly。一些浏览器不允许本地提供文件,所以你可能也需要一个地方来上传你的文件和测试页面。

如何做...

输入<!DOCTYPE html> <html lang="en"> <head>,然后开始添加样式声明,输入<style type="text/css"> h2{color:#303;}

样式一个 div 来包含特色内容:#featured {position:relative; padding: 40px; width: 480px; background-color:#000000; outline: #333 solid 10px; }

输入video {padding: 3px;background-color:black;}来创建视频标签的样式,然后添加一个闭合的</style>标签。

在页面中声明使用的脚本。键入<script src="img/jquery.min.js" type="text/javascript" charset="utf-8"></script>来引用主要 jQuery 库的最小化版本。然后,键入<script type="text/javascript" src="img/jquery-ui.min.js"></script>来引用用于颜色变化效果的 jQuery UI 库。最后,我们将通过在关闭</head>标签之前键入<script type="text/javascript" src="img/mycolor.js"></script>来引用我们自己的脚本。

输入一个开放的<body><section>标签,然后键入<header> <h2>Featured Video</h2></header>来显示页面标题。

现在,我们可以创建包含我们之前样式化的特色内容的 div。键入<div id="featured"> <p>此视频已通过<a href="http://vid.ly">vid.ly</a>转换为跨浏览器格式</p>

下一步是将视频剪辑上传到vid.ly进行多文件格式转换。转换过程完成后,您将收到一封电子邮件,然后可以获取视频的代码片段,如下截图所示:

如何做...

复制网站上的代码,然后粘贴到您的页面中。视频和脚本标签中的src值应该是 vid.ly 给出的 URL。代码块应该如下所示:

<video id= "vidly-video" controls="controls" width="480" height="360"> <source src="img/7m5x7w?content=video"/> <script id="vidjs" language="javascript" src="img/html5.js"></script> </video>

为了增加一些额外的乐趣,让我们在页面上添加另一个视频标签。键入以下代码:<p>哎呀,这是一个宝宝视频!</p>,为视频标签使用不同的 id,并按照以下方式调整大小:<video id="tinymovie1" controls="controls" width="190" height="120">,然后使用相同的源标签:<source src="img/7m5x7w?content=video"/><script id="vidjs" language="javascript" src="img/html5.js"></script></video>,并关闭页面:</div> </section></body></html>。将文件保存为display-videos-using-videly.html

我们要做的最后一件事是创建一个 jQuery 脚本来改变#featured div 的背景颜色。打开您的编辑器,创建一个名为myColor.js的新文件。

键入$(document).ready(function() {,然后转到新的一行,键入调用动画函数并改变背景颜色的代码:$('#featured').animate({'backgroundColor':'#ff3333', 'color': '#ffffff'}, 6000);});。

在浏览器中加载页面,观察主视频加载时颜色的变化。您可以看到以下截图显示的效果:

如何做...

工作原理...

首先,我们创建了一个标准的 HTML5 页面,并开始添加样式声明。我们将featured div 的位置设置为相对位置,以便在将来如果决定添加额外的 jQuery 效果时具有更大的灵活性。通过将padding设置为40px,将outline颜色设置为深灰色并加粗为10px,创建了强烈的视觉效果。默认的背景颜色设置为黑色(#000000),以便与最终的红色背景进行高对比度的比较。

接下来,我们样式化了video标签,使其在加载时具有黑色的background-color。我们还可以在这里添加一个背景图像作为海报。

接下来,使用<script src="img/jquery.min.js" type="text/javascript" charset="utf-8"></script>声明了基本的 jQuery 脚本。因为它不包含animate()等效果,我们还需要引用用于颜色变化效果的 jQuery UI 库的最小化版本。然后,通过键入<script type="text/javascript" src="img/mycolor.js"></script>来添加对我们自己脚本的引用。进一步减小脚本文件大小的另一种方法是创建一个仅包含来自 jQueryUI 库的动画效果的自定义脚本。

接下来,我们创建了主页面内容,包括指向 vid.ly 上的视频的链接。vid.ly 提供的默认代码会将 ID'vidley video'应用到video标签,但如果您想使用自己的样式 ID 或将为每个视频使用不同的 ID,则可以省略该代码。另一个选择是将所有视频分配相同的类,然后根据需要为它们分配唯一的 ID。

另请参阅

第八章,拥抱音频和视频,更详细地介绍了视频元素。

使用 jQuery 动态显示视频

视频元素使我们能够像处理图像一样处理视频,并以有趣和令人兴奋的方式操纵它们。

准备工作

您需要一个以多种文件格式提供的视频(这些文件在本书的章节代码中提供)。建议上传文件的服务器,因为并非所有浏览器都以可预测的方式本地播放文件。

操作步骤

首先,我们必须准备一个 HTML5 页面来放置它。输入我们页面的开放标签:<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Video Explosion</title>

打开下载的代码文件中的stylesheet.css文件,或创建一个同名的新文件。

输入以下内容来设置 body 样式:body {background: white;color:#333333; },然后按照以下方式设置 div 标签的样式:div {float:left; border:1px solid #444444;padding:5px;margin:5px; background:#999999;}

我们需要创建和设置的第一个独特的 div 是#featured。输入#featured {position:relative; width: 480px; background-color:#f2f1f1;}来创建样式。

现在创建一个名为details的 div 来容纳一个小的信息框。输入#details{ position:relative;display:block;background-color:#6CF;color:#333333; padding:10px;}以创建一个将显示在featured div 旁边的 div。

保存css文件,并在 html 页面的头部引用它,方法是使用链接标签输入<link rel="stylesheet" href="css/stylesheet.css"type="text/css" media="screen" charset="utf-8"/>

在样式表链接下方输入以下链接到主 jQuery 库:<script src="img/jquery-latest.js" type="text/javascript" charset="utf-8"></script>,然后通过输入<script type="text/javascript" src="img/jquery-ui.min.js"></script>来链接到 jQuery UI 库。最后,通过输入<script type="text/javascript" src="img/explode.js"></script>来添加对即将创建的脚本的引用。

创建一个新文件并命名为explode.js,并将其存储在一个名为js的新子文件夹中。输入$(document).ready(function(){}。在两个大括号({})之间输入$('h1').effect('shake', {times:5}, 200);创建将导致 featured div 标签中包含的内容爆炸的语句。在新行上,输入$('#featured').effect('shake', {times:3}, 100).delay(500).hide('explode',{}, 2000).slideDown('fast'););以完成脚本。您的代码块应该类似于以下代码块:

$(document).ready(function(){ $('h1').effect('shake', {times:5}, 200); $('#featured').delay(2000).hide('explode', {}, 2000 ).slideDown('fast'); });

保存文件并返回 html 页面。

为 HTML 文件添加</head>闭合标签和<body>开放标签。接下来,输入一个开放的<header>标签和标题文本:<h1>Featured Moto Video</h1>,然后输入</header>标签来完成标题区域。

创建一个开放的<section>标签,然后输入<div id="featured">来创建一个 div,用于容纳我们的视频标签和相关元素。输入<video id="movie" width="480" height="360" preload controls>,然后为三种视频文件类型的每一个添加一个 source 标签:<source src='motogoggles.ogv' type='video/ogg; codecs="theora, vorbis"'/> <source src='motogoggles.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'/> <source src='motogoggles.webm' type='video/webm; codecs="vp8, vorbis"'/>,然后使用</video>标签和</div>标签来关闭 featured div。

最终的内容块包含在details div 中。要创建它,输入<div id="details">,然后添加一个带有文本的标题标签<h1>Details</h1>,最后是一个简短的解释性文本段落:<p>视频将爆炸然后再次出现!</p>。关闭</div></section> </body></html>标签。将 HTML 文件保存为exploding-video-dynamically.html,在浏览器中打开它以查看结果。它们应该与以下截图类似,显示视频分成几部分并爆炸。

如何操作...视频操作,使用 jQuery

它是如何工作的...

stylesheet.css文件包含了特色 div 的样式,确定了页面上视频对象的位置。要注意的第一件重要的事情是position设置为relative。这使我们能够移动视频对象并使用 jQuery 执行其他操作。

我们创建了一个名为details的 div,其position也是relative,但background-color设置为浅蓝色(#6CF)。不同的颜色将有助于在视觉上将其与视频对象区分开来。

接下来,我们添加了 jQuery 库脚本。为了让我们能够访问animate类中包含的方法和函数,需要引用 jQuery UI 库。在这个例子中,我们是在本地引用它,但您也可以像我们访问主要的 jQuery 库一样链接到它。

最后,我们能够编写自己的脚本,使页面上的元素摇晃和爆炸!我们创建了一个语句来验证页面是否准备好接受我们的代码,方法是键入$(document).ready(function(){}。这个函数查询 DOM 并询问页面是否已加载并准备好接受脚本。在创建 jQuery 脚本时,使用这个包装函数是最佳实践。我们使用别名符号$来调用 jQuery 函数,以抓取h1选择器,并对其应用包含shake参数的effect动作,使元素向侧面移动,其中又包含了一个关于摇动元素的次数的参数。摇动应持续的时间间隔以毫秒定义,本例中为200。我们使用选择器$('#featured')来抓取特色 div 元素,并像对h1标签所做的那样,对其进行摇动(只摇动三次以增加变化),每次摇动持续100毫秒。现在我们添加了一些新的动作。在shakes和爆炸之间添加了500毫秒的delay,并使用.delay(500)命令附加到该命令。然后我们附加了hide动作,参数为explode,默认情况下将发生一次,持续时间为2000毫秒。视频爆炸后,slidedown动作将其以fast参数滑回屏幕上。请注意,爆炸所用的时间有点长,这样我们可以更容易地看到它。100-500毫秒的时间间隔会产生更真实的爆炸效果。如果您只想要视频本身而不是特色标签提供的背景或边框,也可以直接使用$('video')来抓取视频标签。

回到 HTML 文件,我们将视频放在一个名为featured的容器 div 中,并创建了一个父video标签,它将preload并包含默认的controls。在关闭video标签之前,我们在其中嵌套了三种视频文件类型的source标签,以便不同浏览器的用户都可以观看视频:我们没有提供 FLASH 回退,但我们可以使用 JavaScript 库,比如Video.js。然后我们关闭了</video>标签和特色 div 标签</div>

最后,我们创建了一个 div 来保存关于用户可以期待在details div 中发生的事情的信息。

还有更多...

视频元素、JavaScript 和画布标签还有很多可以做的事情。继续阅读更多实验。

使用视频和画布进行更多交互式爆炸

Sean Christmann 在www.craftymind.com上进行了一项令人惊叹的实验,使您能够在视频播放时实时爆炸多个视频部分。您可以在此处查看:www.craftymind.com/2010/04/20/blowing-up-html5-video-and-mapping-it-into-3d-space/,但请注意 - 在 Firefox 中资源消耗非常大。

所有这些爆炸是怎么回事?

起初似乎没有任何真正实际的理由来分解视频。然而,这对于模仿独特的过渡效果或对游戏中用户操作的响应可能非常有用。

实时 Chroma 键背景替换

Firefox 开发人员一直在尝试操纵视频元素。他们创建了一个教程,解释了他们如何使用画布、JavaScript 和视频元素的属性执行 Chroma 键替换。您可以在以下网址阅读有关此内容并查看演示:developer.mozilla.org/En/Manipulating_video_using_canvas

想象一下在网站上显示视频,您可以显示异国情调的背景或创建产品和人物的互动混搭。

另请参阅

视频元素在本书的第八章拥抱音频和视频中进行了深入探讨。

使用 jQuery 创建可移动视频广告

我们将在网站上创建一个视频广告,当用户向下滚动页面时,它将移动使用 jQuery 和视频标签。

准备工作

您将需要多种格式的视频文件,如.ogg/.ogv, .mp4.webm,或者使用视频服务,如www.vid.ly.com来提供跨浏览器视频。此示例未在 Internet Explorer 中进行测试,但应在 Safari、Google Chrome、Opera 和 Firefox 的最新版本中正常工作。

如何做...

我们将首先创建一个典型的网页。在编辑器中打开一个新文件,并将其保存为movable-video-ad.html。键入<!DOCTYPE html> <html lang="en"><head><meta charset="utf-8" /><title>Movable Video Ad</title>以在页面上放置第一个标签。

现在,为我们的默认样式表创建一个引用链接<link rel="stylesheet" href="css/main.css" type="text/css" media="screen" charset="utf-8" />和一个名为<link rel="stylesheet" href="css/scroll.css" type="text/css" media="screen" charset="utf-8" />的辅助样式表。

接下来,为 jQuery 脚本创建引用链接。键入<script src="img/jquery-1.4.min.js" type="text/javascript" charset="utf-8"></script>来引用核心 jQuery 代码。添加链接语句<script type="text/javascript" src="img/jquery-ui-1.7.2.custom.min.js"></script>。我们将链接到的最终脚本是我们为名为myAd.js的配方创建的自己的脚本,它将存储在我们创建的名为"js"的子文件夹中。键入<script type="text/javascript" src="img/myAd.js"></script>来链接到该文件。

键入</head><body><div id="container">开始页面的内容区域。通过键入<header> <h1>Motocross Mania</h1></header>来显示页面标题。

通过键入<div id="content"> <h2>No dirt = no fun</h2>来开始添加页面内容。现在可以通过输入文本<div id="motoad"><h3>Buy this movie!</h3>,然后在段落元素标签中包含电影标题<p><strong>MotoHelmet</strong></p>来向页面添加包含广告的 div。

然后应添加一个视频标签<video width="190" height="143" preload controls>。键入包含每种视频格式的源标签,如下面的代码块所示:

<source src='video/motohelmet.ogv' type='video/ogg; codecs="theora, vorbis"'/> <source src='video/motohelmet.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'/> <source src='video/motohelmet.webm' type='video/webm; codecs="vp8, vorbis"'/></video>

关闭</div>标签并保存到目前为止的进度。

创建一个带有 id 为 intro 的段落<p id="intro">来包含文本We review the best motorcross gear ever!!!。在段落标签和文本后面,加上一个虚拟链接列表:<ul><li><a href="#">Helmets</a></li> <li><a href="#">Gloves</a></li><li><a href="#">Goggles</a></li></ul>,用</p>关闭段落,然后创建一个新的 div 来包含一个虚拟新闻内容块,然后是另外两个虚拟 div 块,一个页脚标签,以及关闭页面元素,如下面的代码块所示:

<div id="news"><h2>Latest News</h2> <p>Trip Ousplat admits he doesn't do his own stunts! "My mom makes
me use a stunt double sometimes," The shy trick-riding sensation explains.</p> <p>Gloria Camshaft smokes the competition for a suprise win at the Hidden Beverage Playoffs</p> <p>Supercross competitors report more injuries; jumps more extreme than ever</p><p>James Steward still polite, reporters bored</p>
</div><div id="filler"><h2>On Location</h2> <p>Grass is not greener as there is no grass on most motorcross trails experts claim </p></div> <p id="disclaimer">Disclaimer! Anything you choose to do is at your own risk. Got it? Good.</p><footer><p>&copy; Copyright 2011 Motocross Extreme Publications, Inc.</p></footer></div></body></html>

现在,我们将在main.css文件中为页面元素设置样式。第一个关键样式是#container div。它应该有一个0 auto的边距和650px的宽度。接下来,#motoad div 应该被设置为右浮动,并包含一个200px的宽度来容纳视频元素。最后,#intro div 应该包含一个较短的450px宽度。这三个样式应该看起来类似于下面显示的代码块:

#container{ margin:0 auto;text-align:left; width: 650px;}
#motoad{ float:right;width:200px;}
#intro{width:450px;}

其余的样式是对填充和颜色或其他标准声明的微小调整。

现在,打开scroll.css文件来定义样式,以帮助我们的广告滚动。我们将级联#motoad的属性,形成一个可以移动的 div 块。接下来,定义#content属性的height,以及段落和h2元素的宽度。scroll.css中的样式现在应该如下所示:

#motoad {display:block;position: relative; background-color:#FC0;width:200px;padding:10px;}
#content { height:1000px;}
p {width:450px;}h2 {width:460px;}

保存文件,并准备创建我们的 jQuery 脚本。

打开或创建myAd.js,并开始输入文档就绪函数$(document).ready(function(){}和花括号。在花括号之间点击 enter,并输入滚动函数$(window).scroll(function() {。在该函数的开头花括号后键入命令:$('#motoad').stop().animate({top: $(document).scrollTop()},'slow','easeOutBack');。也要关闭脚本:" });});"。我们的 jQuery 脚本现在应该看起来像以下代码块:

$(document).ready(function(){ $(window).scroll(function() { $('#motoad').stop().animate({top: $(document).scrollTop()},'slow','easeOutBack'); }); });

保存所有文件,并在浏览器窗口中加载 HTML 页面。在开始滚动页面之前,页面应该看起来像下面的截图。

如何做...

尝试向上和向下滚动页面。广告也应该随着页面一起上下移动。结果应该看起来类似于以下截图:

如何做...

工作原理...

在创建了一个包含不同内容元素的典型 HTML 页面后,我们准备好为 CSS 页面设置样式。我们将 CSS 分成两个文件,main.cssscroll.css,这样当我们在 jQuery 脚本中调用滚动函数并积极应用它时,页面上的内容元素会收缩,以便我们的广告可以轻松移动,而不会阻挡页面上的任何信息。

我们希望在调用窗口滚动事件时,使#motoad div 标签移动。为此,我们使用别名符号$来调用 jQuery 函数,从 DOM 中获取window选择器,并将默认滚动动作参数应用于它。使用这个函数,我们然后创建了控制#motoad div 块行为的命令。我们给它了stop的动作,这样它就准备好进行动画。animate动作链接到了stop命令。我们应用到#motoad div 的animate的第一个参数是,当文档窗口中的滚动条移动时,div 会移动。slow参数控制了广告上下移动的速度,easeOutBack参数引用了一个缓动命令,以创建流畅的动画运动,而不是突然开始或停止。

还有更多...

在这个示例中,我们通过使自定义 HTML 元素对页面上的用户操作做出响应来实现了动画效果。这只是我们可以微妙地添加效果的一种方式,可以用于实际解决方案。

有 HTML 元素,就会移动

探索 jQuery UI 库,你会被许多可以操纵和样式化任何 HTML 元素的方式所启发。访问jqueryui.com查看演示和文档。

另请参阅

学习 jQuery:使用简单的 JavaScript 技术实现更好的交互设计和 Web 开发,Packt Publishing 出版。

使用 Easel.js 和 canvas 标签控制图像的显示

JavaScript 库Easel.js减少了使用canvas标签创建动画和丰富交互环境的复杂性。在这个配方中,我们将使用单个文件中名为"sprites"的一系列图像,以展示如何使用Easel.js来控制精灵中选择性显示的图形图像。

准备工作

您需要下载Easel.js库,或者使用此配方的代码文件中的副本。

如何做...

创建一个 HTML5 文件的开放标签。您的代码应该类似于以下代码块:

<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title> Animating images using BitmapSequence and SpriteSheet</title>

接下来,链接到此配方中使用的主样式表styles.css:。

接下来,我们将通过插入以下脚本文件的链接来导入Easel.js框架库:UID.js, SpriteSheetUtils.js, SpriteSheet.js, DisplayObject.js, Container.js, Stage.js, BitmapSequence.jsTicks.js。您可以在这里看到每个脚本文件的路径和链接:

<script src="img/UID.js"></script><script src="img/SpriteSheetUtils.js"></script><script src="img/SpriteSheet.js"></script><script src="img/DisplayObject.js"></script><script src="img/Container.js"></script><script src="img/Stage.js"></script><script src="img/BitmapSequence.js"></script><script src="img/Tick.js"></script>

接下来,创建并打开<script>标签,并声明以下三个变量:var canvas; var stage; var critterSheet = new Image(); 用于我们的脚本。

输入function init(){开始函数,然后输入canvas = document.getElementById("testCanvas");将页面主体中的 canvas 与 canvas 变量绑定。准备加载一个新的spriteSheet,输入critterSheet.onload = handleImageLoad;。critterSheet变量存储精灵图像的来源。输入critterSheet.src = "images/moles.png";来加载我们自己的一系列鼹鼠图像。函数块应如下代码块所示:

function init() {
canvas = document.getElementById("testCanvas");
critterSheet.onload = handleImageLoad;
critterSheet.src = "images/moles.png";}

我们将创建的第二个函数是handleImageLoad()。输入function handleImageLoad() {然后输入stage = new Stage(canvas);来创建一个新的舞台实例。输入var spriteSheet = new SpriteSheet(critterSheet, 76, 80);来创建一个新的spriteSheet。创建一个名为critter1的新位图序列变量,并定义它在舞台上的位置,使用 x 和 y 坐标来输入:var critter1 = new BitmapSequence(spriteSheet); critter1.y = 85; critter1.x = 85;。通过输入critter1.gotoAndStop(1),从我们的精灵表moles.png中添加一个小动物。接下来,使用命令stage.addChild(critter1)将其添加到舞台上。

克隆我们创建的第一个critter1变量,并通过输入var critter2 = critter1.clone()将其值传递给一个新的 critter 变量。通过添加到其当前位置值来将新变量定位在第一个 critter 的右侧,使用critter2.x += 120

输入critter2.gotoAndStop(0)来为critter2变量赋值。克隆 critter 1 和 critter 2 的代码块应如下所示:

var critter2 = critter1.clone();
critter2.x += 120;
critter2.gotoAndStop(0);
stage.addChild(critter2);

Tick 间隔Tick.setInterval(300);和监听器Tick.addListener(stage);是我们将添加到脚本的最后两个语句。关闭handleImageLoad()函数的大括号(}),然后输入一个闭合的脚本标签。

关闭</head>标签,然后输入带有onload属性的开放body标签,调用init()函数。创建一个名为"description"的 div 用于内容。添加一个名为canvasHolder的 div 来包含 canvas 元素。在页面底部显示图像文件moles.png

<body onload="init();">
<div class="description">Using <strong>BitmapSequence</strong> to animate images from a <strong>SpriteSheet</strong>.
</div>
<div class="canvasHolder">
<canvas id="testCanvas" width="980" height="280" style="background-color:#096"></canvas> </div> </p><p>The original moles.png spritesheet file with all the images:<br/><img src="img/moles.png"/></p> </body></html>

将文件保存为whack-mole-easel-test-single.html。结果可以在以下截图中看到:

如何做...

工作原理...

在我们设置好 HTML5 页面的开头之后,我们准备好导入Easel.js框架并创建我们的主要脚本。

我们创建了一个开放的<script>标签,并声明了以下全局变量:var canvas; var stage; var critterSheet = new Image(); 用于我们的脚本。

创建的init()函数将在页面加载时被调用。它包含了正在被分配选择器testCanvascanvas变量的过程,使用document.getElementById("testCanvas");将页面主体中的 canvas 与 canvas 变量绑定。接下来,我们准备通过输入critterSheet.onload = handleImageLoad加载一个新的spriteSheetcritterSheet变量存储了精灵图像的来源。输入critterSheet.src = "images/moles.png";让我们可以访问我们自己的一系列鼹鼠图像。

我们创建的第二个函数是handleImageLoad()。在这个函数中,我们做了大部分工作,首先是使用stage = new Stage(canvas)创建了一个舞台的新实例;接下来,我们使用var spriteSheet = new SpriteSheet(critterSheet, 76, 80)创建了一个新的spriteSheet

现在我们有了一个精灵图实例,我们可以创建一个新的位图序列变量,称为critter1,并定义它在舞台上的位置,使用 x 和 y 坐标来输入:var critter1 = new BitmapSequence(spriteSheet);critter1.y = 85;critter1.x = 85;。接下来,我们按数字引用要添加的帧,以便首先将正确的动作应用于 critter,然后应用于舞台。我们通过输入critter1.gotoAndStop(1)critter1变量链接到我们精灵图moles.png上的第二个图像。我们使用命令stage.addChild(critter1)将图像添加到舞台上。

我们克隆了我们创建的第一个critter1变量,并通过输入var critter2 = critter1.clone()将其值传递给一个新的 critter 变量。我们通过使用critter2.x += 120将新变量定位在第一个 critter 的右侧,将其当前位置值添加到其中。我们通过命令BitSequence去到moles.png上的第一个图像的位置并在那里停止,并将其分配给critter2变量。

我们添加了Tick.setInterval(300);,这样就在Ticks之间应用了300毫秒的时间间隔。Tick 接口充当全局定时设备,如果需要,可以返回每秒帧数(FPS)。我们向舞台添加了一个监听器Tick.addListener(stage);,它的行为类似于其他类型的监听器,它监听Ticks。这可以用来在指定的时间重新绘制舞台,或执行其他与时间相关的操作。

我们使用onload属性在body标签中调用init()函数。这会导致在页面加载时调用init()函数。

另请参阅

动画序列教程。

使用 Easel.js 和 canvas 标签来制作图像序列的动画

我们可以通过创建数组和使用Easel.js JavaScript 库的函数来制作称为精灵的图像条,然后使用canvas元素对它们进行操作。在这个教程中,我们将对同一条图像条进行动画处理,但显示两个不同时间序列。

准备工作

下载此教程的代码文件,以使用Easel.js框架库以及支持文件。您需要一个能够正确显示 HTML5 元素并测试本教程中使用的代码的最新浏览器。

操作步骤

创建一个 HTML5 文件的开头标签。您的代码应该类似于以下代码块:

<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title> Animating images using BitmapSequence and SpriteSheet</title>

链接到本教程中使用的主样式表styles.css:。

通过插入以下脚本文件的链接来导入Easel.js框架库:UID.js, SpriteSheetUtils.js, SpriteSheet.js, DisplayObject.js, Container.js, Stage.js, BitmapSequence.jsTicks.js。参考前面的示例,了解框架块应该是什么样子的。

创建一个开头的<script>标签,并声明以下三个变量:var canvas;var stage;var critterSheet = new Image();用于我们的脚本。

输入function init(){开始函数,然后输入canvas = document.getElementById("testCanvas")

准备通过输入critterSheet.onload = handleImageLoad;来加载一个新的spriteSheet。输入critterSheet.src = "images/moles.png";来加载我们自己的一系列鼹鼠图像。函数块应该如下所示的代码块:

function init() {
canvas = document.getElementById("testCanvas");
critterSheet.onload = handleImageLoad;
critterSheet.src = "images/moles.png";}

我们将创建的第二个函数是handleImageLoad()。输入function handleImageLoad() {然后stage = new Stage(canvas);创建舞台的新实例。输入var spriteSheet = new SpriteSheet(critterSheet, 80, 80);创建一个新的spriteSheet。现在我们有了一个精灵表,创建一个新的位图序列变量名为critter1,并使用 x 和 y 坐标定义其在舞台上的位置,输入:var critter1 = new BitmapSequence(spriteSheet);然后critter1.y = 100;critter1.x = 90;。接下来,我们将创建一个数组,将其映射到原始spritesheet文件上的每个图像,输入var frameData = {shymole:0, upmole:1, downmole:2, whacked:3, whackedow:4, clouds:5,tinycloud:6, cloudgroup:7};以便我们有八个名称值,每个名称值都与一个数组 ID 相关联。

到目前为止,handleImageLoad()的代码块应该如下所示:

function handleImageLoad() {
stage = new Stage(canvas);
var spriteSheet = new SpriteSheet(critterSheet, 80, 80);
var critter1 = new BitmapSequence(spriteSheet);
critter1.y = 100;
critter1.x = 90;
var frameData = {shymole:0, upmole:1, downmole:2, whacked:3, whackedow:4, clouds:5,tinycloud:6, cloudgroup:7};

通过输入:spriteSheet = new SpriteSheet(critterSheet, 80, 80, frameData);创建一个新的spriteSheet并将其用作参数。

创建一个名为critter1的新位图序列变量,并通过输入critter1gotoAndStop(0);应用图像精灵。使用stage.addchild(critter1);将critter1添加到stage

通过输入var critter2 = critter1.clone();克隆第一个critter1变量,并将其值传递给一个新的小动物变量。使用critter2.x += 120;定义新变量的x值。通过输入critter2.gotoAndStop(5);为小动物分配其自己的图像,来自moles.png图像文件。添加一个新的spriteSheet,创建critter 1和克隆critter 2的代码块应该如下所示的代码块:

spriteSheet = new SpriteSheet(critterSheet, 80, 80, frameData);
critter1.gotoAndStop(0);
stage.addChild(critter1);
var critter2 = critter1.clone();
critter2.x += 120;critter2.gotoAndStop(5);

输入:var critter3 = critter2.clone(); critter3.spriteSheet = spriteSheet;。就像我们之前创建的其他小动物变量一样,通过将10添加到其当前值来重新定义critter3x值:critter3.x += 10;。以下代码块显示了我们到目前为止所做的事情:

var critter3 = critter2.clone();
critter3.spriteSheet = spriteSheet;
critter3.x += 10;

通过输入critter3.gotoAndStop("upmole");按名称引用moles.png中的图像frames。通过克隆一个新变量并引用一个新帧,将当前的upmole帧图像替换为不同的帧:var critter4 = critter3.clone(); critter4.gotoAndStop("downmole");。通过输入critter4.x += 10;将该帧向右移动10像素。

再次交换帧并将我们的新帧向右移动10像素:var critter5 = critter4.clone(); critter5.gotoAndStop("shymole"); critter5.x += 10;。让我们看一下到目前为止我们应该有的代码块:

critter3.gotoAndStop("upmole");
var critter4 = critter3.clone();
critter4.gotoAndStop("downmole");
critter4.x += 10;
var critter5 = critter4.clone();
critter5.gotoAndStop("shymole");
critter5.x += 10;

通过输入以下内容循环播放我们的moles.png文件中的帧:

var critter6 = critter1.clone(); critter6.x = critter5.x + 100; critter6.gotoAndPlay(3);stage.addChild(critter6);.

在舞台上添加第二个动画序列,通过引用不同的起始帧来改变动画的时序,当新的小动物精灵被添加到舞台上时:var critter7 = critter1.clone(); critter7.x = critter6.x + 100; critter7.gotoAndPlay(1); stage.addChild(critter7);。

我们的两个动画序列现在应该包含以下代码:

var critter6 = critter1.clone();
critter6.x = critter5.x + 100;
critter6.gotoAndPlay(3);
stage.addChild(critter6);
var critter7 = critter1.clone();
critter7.x = critter6.x + 100;
critter7.gotoAndPlay(1);
stage.addChild(critter7);

Tick 间隔Tick.setInterval(200);和监听器Tick.addListener(stage);是我们将添加到脚本中的最后两个语句。关闭handleImageLoad()函数的大括号(})并输入一个闭合的脚本标签。

输入</head>,然后<body onload="init()">。创建一个名为"description"的 div 来容纳内容。最后一个 div 是canvasHolder,包含 canvas 元素。将宽度设置为600,高度设置为280,背景颜色设置为浅灰色(#ccc)。添加指向图像文件moles.png的链接,以便用户可以看到moles.png中引用的图像精灵。

保存文件,并在浏览器窗口中打开它。你应该在左侧看到一个静止的帧(闭着眼睛的鼹鼠头像),并在屏幕右侧看到两个动画序列循环播放。以下截图显示了两个序列如何加载相同的帧,但时间不同。

如何操作...

它是如何工作的...

创建 HTML 页面和引用画布的配方的第一步与上一个配方相同。

创建spriteSheet后,我们创建了一个新变量来保存我们的精灵帧,称为critter1,并通过输入以下内容定义了帧位置的xy坐标:var critter1 = new BitmapSequence(spriteSheet); critter1.y = 100;critter1.x = 90;。

我们创建了数组var frameData来声明八个键/值对。然后,我们能够创建一个新的spriteSheet,它接受了spriteSheet名称的参数,每个帧的默认高度和宽度,并使用frameData一次性加载moles.png中的所有帧到spriteSheet中。

接下来,我们尝试使用frameData通过数字值和名称键引用帧,创建一系列位图序列,然后用它们的克隆替换它们。

我们对序列进行了动画处理,并将它们放在了舞台上。它们都遵循相同的格式,但通过更改gotoAndPlay操作中的数字参数,它们在不同的帧上开始它们的动画序列。

最后,我们添加了Tick.setInterval(200);,它在 Ticks 之间应用了 200 毫秒的时间间隔。Tick 接口充当全局定时设备,如果需要,可以返回每秒帧数(FPS)。我们向舞台添加了一个监听器Tick.addListener(stage);,它像其他类型的监听器一样监听 Ticks。这可以用来在指定时间重新绘制舞台,或执行其他与时间相关的操作。我们使用onload属性在body标签中调用init()函数。这会导致在页面加载时调用init()函数。

还有更多...

Easel.js和其他类似的库使控制 HTML5 元素变得更加容易。不过要小心使用它们,因为有些可能不够稳定,不能在生产环境中使用。

海盗爱雏菊,你也应该爱

Easel.js的创建者被微软要求创建一个名为 Pirates love daisies 的概念性网络游戏(www.pirateslovedaisies.com),完全使用 HTML5 和 JavaScript,并且严重依赖于Easel.js库来操作canvas元素。你可以在任何网络浏览器中玩这个游戏,也许有些讽刺的是,它还为使用 Internet Explorer 9 浏览器的访问者提供了特殊功能。

老派计算机动画技术的回归

当我第一次开始在计算机上玩游戏时,游戏屏幕上有 256 种颜色和 8 位动画是一件大事。计算机动画师使用了许多技巧来复制水流动等效果。重新体验那些日子(或者第一次通过 effect games 的演示发现它们:www.effectgames.com/demos/canvascycle/

另请参阅

本书中有一整章关于 canvas 的配方。如果你跳过了它们,现在就去吞食它们。

使用 canvas 标签和 JavaScript 进行随机动画和音频

在这个配方中,我们将使用 canvas 标签来绘制和动画一系列形状。我们还将使用音频标签循环播放音频文件,同时显示动画。我们正在改编 Michael Nutt 创建的原始动画。我们将创建一个更慢、更轻松的动画,看起来像是摇曳的草。

做好准备

您将需要一个最近更新的浏览器,如 Firefox 3.6 或 Google Chrome,以及多种格式的音频文件。在 Opera 浏览器 9 和 10 中,它显示的大小会有所不同(更小)。在那些版本的 Opera 中,音频也不会播放。

如何做...

首先,打开一个新的 HTML5 页面,并命名为random-animation-with-audio.html。输入一个 HTML5 页面的开头,包括页面标题:

<!DOCTYPE html> <html lang="en"> <head><meta charset="utf-8" /> <title>Canvas Reggae</title>.

然后,添加链接到 JavaScript 和 CSS 文件,这些文件将在页面加载时导入:<script type="text/javascript" src="img/animatedlines.js"></script><link rel="stylesheet" href="css/stylesheet.css" type="text/css" media="screen" charset="utf-8" />,并使用</head>关闭 head 标签。

输入<body onLoad="init();">来在页面加载时激活init()函数。

接下来,我们创建页面的标题<header><h1>CANVAS Reggae</h1></header>,然后通过输入<canvas id="tutorial" width="480" height="360"></canvas>来添加 canvas 元素。

创建一个新的 div,其中包含一个id为 credits 的链接到 Michael 的网站:<div id="credits">Based on Canvas Party by <a href="http://nuttnet.net/">Michael Nutt</a>&nbsp;&nbsp;。然后向 div 添加一个链接,以抓取音频元素并在单击链接时应用pause()函数来暂停音乐。<a href="#" onClick="document.getElementsByTagName('audio')[0].pause();">[OFF]</a></div>

现在,输入音频标签,并将 autoplay 设置为 true,loop 设置为 loop:<audio autoplay="true" loop="loop">创建两个 source 标签来包含音频格式:<source type="audio/ogg" src="img/randomreggae.ogg" /><source type="audio/mpeg" src="img/randomreggae.mp3" />

在关闭音频标签之前,我们将添加一串文本,如果不支持音频标签,则会显示:Your browser doesn't recognize the HTML5 audio tag

关闭音频、body 和 html 标签,并保存页面。

在创建脚本之前,打开stylesheet.css页面,并输入以下内容:

body { margin: 0; background-color: #000; color: #FFF; font-family: Helvetica, sans-serif; }
a { color: #FFF; }
h1 { position: absolute; top: 0; margin: auto; z-index: 50; padding: 10px; background-color: #000; color: #FFF; }
div#credits { position: absolute; bottom: 0; right: 0; padding: 10px; }
audio { position: absolute; visibility: hidden; }

现在 HTML 和 CSS 页面已经构建完成,我们将着手处理动画脚本。创建一个新的 JavaScript 文件并命名为animatedLines.js。我们将把它放在一个名为js的新子文件夹中。

首先,我们将声明 flatten 变量并创建一个新的数组函数:var flatten = function(array) { var r = []。接下来,在函数内部,我们将创建一个for语句来声明一个以一个对象开始的数组(var i = 0),然后在数组长度大于i的情况下增加数组的大小。for(var i = 0; i < array.length; i++) {。使用push函数,我们将通过输入以下内容向数组添加新值:r.push.apply(r, array[i]);},最后通过返回数组来结束函数:return r; }

到目前为止,我们的脚本应该看起来像以下代码块:

var flatten = function(array) { var r = [];
for(var i = 0; i < array.length; i++) {
r.push.apply(r, array[i]); }
return r; }

接下来,我们将创建一个名为 shuffle 的函数,它接受一个数组作为参数。输入function shuffle(array) { var tmp, current, top = array.length。在函数内部,我们有一个 if/while 循环来遍历数组中的值。通过输入以下内容将其添加到脚本中:var tmp, current, top = array.length; if(top) while(--top) { current = Math.floor(Math.random() * (top + 1)); tmp = array[current]; array[current] = array[top]; array[top] = tmp; }。在函数末尾返回数组的值。我们的随机洗牌数组值的函数现在应该看起来像以下代码块:

function shuffle(array) {
var tmp, current, top = array.length;
if(top) while(--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp; }
return array; }

现在,我们准备创建一个全局的canvas变量和一个context变量,输入:var canvas;和var ctx;

有了这些变量,我们可以向脚本添加init()函数,所有的动作都从这里开始。输入function init() {,然后输入语句将我们的 canvas 变量与 canvas 元素关联起来:canvas = document.getElementById('tutorial')

现在,我们将创建一个if语句来设置我们的画布变量的宽度和高度属性:if (canvas.getContext) {canvas.width = window.innerWidth; canvas.height = window.innerHeight - 100; ctx = canvas.getContext('2d'); ctx.lineJoin = "round"; setInterval("draw()", 300); }。这完成了init()函数。

接下来,我们为浏览器窗口添加一个监听器,以便在调整大小时检测:window.addEventListener('resize', function() {canvas.width = window.innerWidth;canvas.height = window.innerHeight - 100; });}

我们脚本的最新添加现在应该是:

function init() {
canvas = document.getElementById('tutorial');
if (canvas.getContext) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight - 100;
ctx = canvas.getContext('2d');
ctx.lineJoin = "round";
setInterval("draw()", 300); }
window.addEventListener('resize', function() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight - 100; }); }

我们终于准备好创建一个函数来在画布上绘制形状。这个函数将包含大部分驱动形状动画的脚本。输入function draw(){ctx.globalCompositeOperation = "darker"; ctx.fillStyle = '#000'; ctx.fillRect(0, 0, canvas.width, canvas.height);ctx.globalCompositeOperation = "lighter";来设置画布背景的外观。

现在,我们将输入动画中要使用的颜色。我们将创建一个包含rgba值的数组的数组。类型:var colors = ["rgba(134, 154, 67, 0.8)", "rgba(196, 187, 72, 0.8)", "rgba(247, 210, 82, 1)", "rgba(225, 124, 20, 0.8)"];。我们颜色已经定义好了,现在我们将使用一个包含宽度和高度值的单独数组的数组来设置形状的宽度和高度:var data = [ [ [5, 20], [15, 2] ], [ [50, 12], [10, 14], [3, 21] ], [ [60, 8]], [ [30, 24], [15, 4], [10, 17] ], [ [5, 10] ], [ [60, 5], [10, 6], [3, 26] ], [ [20, 18] ], [ [90, 11], [40, 13], [15, 10] ], [ [70, 19] ], ]

现在,我们可以通过使用data = shuffle(data)来改变它们的宽度和高度来使形状动画化。

为了使形状上下以及左右移动,我们需要"压扁"或压缩它们的高度。创建一个新变量来包含var flatData = flatten(data)

现在,我们将扭曲线条,使它们看起来像是在不同方向上拉动并使用bezierCurve。这是一个大的函数块,包含在我们之前创建的draw()函数中,所以输入link()函数如下所示:

link(topPos, bottomPos, width) {
var padding = 100;
ctx.lineWidth = width;
ctx.beginPath();
var height = parseInt(canvas.height - padding);
var pull = 100;
var topLeft = topPos + (width / 2) + padding;
var bottomLeft = bottomPos + (width / 2) + padding;
ctx.moveTo(topLeft, padding);
ctx.bezierCurveTo(topLeft, pull, bottomLeft, height - pull, bottomLeft, height);
ctx.stroke(); }

现在,当我们仍然在draw()函数中时,让我们添加一个新变量来表示形状的起始点,然后添加一个for循环来创建一个可以容纳数据值集合的新变量。以下是变量和循环代码:Var topStartingPoint = 0; for(var i in data) { var group = data[i]; var color = colors[ i % colors.length ];ctx.strokeStyle = color

通过创建一个嵌套的for循环,将一组数据值传递给一个名为line的新变量来进一步操作:for(var j in group) { var line = group[j];然后我们可以在创建一个初始值为零的bottomStartingPoint变量后进行操作:var bottomStartingPoint = 0

第三个嵌套的for循环将允许我们进一步控制形状的定位和移动:for(var k in flatData) { if(flatData[k][1] < line[1]) { bottomStartingPoint += flatData[k][0] + 11;} }

最后,我们使用 link 来设置线条的顶部和底部起始点,link(topStartingPoint, bottomStartingPoint, line[0]);,然后将topStartingPoint赋值为其当前值加上线条数组。最后的语句将topStartingPoint值设置为其当前值加上五:topStartingPoint += line[0]; } topStartingPoint += 5; }}。保存脚本文件。

在浏览器中打开文件random-animation-with-audio.html,您应该会看到线条来回摆动,类似于以下截图所示:

操作步骤...

它是如何工作的...

首先,我们创建了一个 HTML5 页面,其中包含指向在页面加载时导入的 JavaScript 和 CSS 文件的链接:<script type="text/javascript" src="img/animatedlines.js"></script><link rel="stylesheet" href="css/stylesheet.css" type="text/css" media="screen" charset="utf-8" />。为了激活我们的动画序列,我们将init()函数放在 HTML 页面的 body 标签中。当页面加载时,animatedLines.js JavaScript 文件中的init()函数将通过<body onLoad="init();">进行初始化。

我们使用body样式来设置页面的全局默认margin0background-colorfont colorfont-family。我们为基本链接颜色设置了样式,然后对h1标题标签进行了样式设置,以便它以position: absolute; top: 0的方式显示在top位置,并通过将z-index设置为50始终显示在大多数其他内容块的上方。#credits div 被定位在页面的右下角,音频标签使用visibility: hidden进行隐藏。

我们创建了一个名为animatedLines.js的新脚本,并首先定义了一系列变量和函数来控制形状的行为。

我们设置了一个名为flatten的数组,它会将新值添加到自身。接下来,我们需要一个函数来随机旋转数组的值。我们使用了Math.floor(Math.random()语句来计算一个随机数,并将结果乘以变量top + 1的当前值的总和。然后我们将一个整数值返回给变量current

我们通过使用document.getElementById在页面加载时获取canvas元素的 ID 来定义canvas变量的尺寸值。我们使用 DOM 的帮助设置了canvas变量的widthheight属性:canvas.height = window.innerHeight - 100; ctx = canvas.getContext('2d');然后创建了一个语句,对canvas2d上下文应用了lineJoin,参数为round。我们使用setInterval()函数将线条在画布上绘制的速度设置为300毫秒。数字越大,动画看起来越慢。我们为浏览器窗口添加了一个监听器,以便检测窗口的大小和画布。

然后使用draw()函数将形状绘制到画布上。使用globalCompositeOperation = "darker"来使线条在相互移动时变暗。线条在画布舞台前部重叠时,使用globalCompositeOperation = "lighter"来设置画布背景的外观。

用于装饰线条的颜色需要以rgba格式。rgba 中的'a'指的是 alpha 值,控制每种颜色的可见性。每个 rgba 值集合都包含在一个数组中,然后成为数组列表。我们需要与线条相匹配的宽度和高度值集合。这些存储在数组var data中。

接下来,我们将data数组分配给从我们的shuffle()函数返回的值,以便我们可以随机化屏幕上线条的外观。然后,我们将从flatten()函数返回的值分配给变量flatData。为每条线分配一个拉动值使我们能够将其移动指定数量的像素。我们将这与bezierCurve结合起来,使线条弯曲。

还有更多...

将音频标签、画布动画和 JavaScript 结合起来,听起来像是一种有趣的方式来创建酷炫的可视化效果。然而,这些效果在很大程度上依赖于浏览器的支持,因此许多网络浏览器用户目前无法正确查看它们。我的意思是,大多数标准浏览器在一两年内都无法播放它们。

使用尖端浏览器可视化您的音频

如果您已经下载了测试版的 Firefox 4,您就可以访问 Firefox 音频和视频 API。您将能够使用类似 Spectrum Visualizer 的工具查看和创建自己的音频可视化效果:

www.storiesinflight.com/jsfft/visualizer/index.html

推动 HTML5 中音频的实现

Alexander Chen 一直在尝试使用音频和画布来移植基于 Flash 的应用程序。他在博客中详细介绍了使用多个音频文件时遇到的一些问题:

blog.chenalexander.com/2011/limitations-of-layering-html5-audio/

另请参阅

画布和

第八章:拥抱音频和视频

在这一章中,我们将涵盖:

  • 对 Flash 说不

  • 了解“音频”和“视频”文件格式

  • 为每个人显示“视频”

  • 创建可访问的“音频”和“视频”

  • 打造时髦的“音频”播放器

  • 为移动设备嵌入“音频”和“视频”

介绍

“Flash 是在 PC 时代创建的-为 PC 和鼠标。Flash 对 Adobe 来说是一个成功的业务,我们可以理解他们为什么想要将其推广到 PC 之外。但移动时代是关于低功耗设备,触摸界面和开放的网络标准,这些都是 Flash 的短板。提供其内容给苹果移动设备的媒体机构的大量增加表明 Flash 不再是观看视频或消费任何类型的网络内容的必要条件。”- 史蒂夫·乔布斯

就像我们已经看过的许多其他新技术一样,在开源 HTML5 标准中,新的“音频”和“视频”元素比以往任何时候都更加成熟和可用。这是一件好事,因为用户对多媒体的期望比以往任何时候都要高。在过去,我们使用 300 比特每秒的调制解调器下载一张照片需要 10 分钟。后来,我们使用 Napster 非法下载 MP3“音频”文件。现在,我们在移动设备上播放电视和色情内容。由于带宽管道变得越来越宽,我们对互动娱乐的需求几乎是无法满足的。现在是金钱的时刻。

多年来,QuickTime、RealPlayer 和 Flash 之间的战斗是为了在网络上播放视频的统治地位。这些浏览器插件很容易安装,通常能产生预期的结果。

随着时间的推移,QuickTime 和 RealPlayer 继续作为播放平台,但专有 Flash 工具的制造商也创建了一个强大的开发环境,不仅让设计师,还让开发人员将其视为一个可行的平台。

虽然 QuickTime 和 RealPlayer 仍然存在,但 Flash 已经赢得了这场战争。对于动画和卡通来说,Flash 是理想的工具。但它是否仍然是最好的“音频”和“视频”播放工具呢?史蒂夫·乔布斯肯定不这么认为。

2010 年,苹果电脑的负责人乔布斯划定了界限,并表示 Flash 永远不会出现在他最畅销的 iPhone 和 iPad 上。相反,他强烈支持开放的 HTML5 标准,并引发了一场在线圣战。

很快,“Flash 的死亡”宣言成为媒体和整个博客圈的头条新闻。有些人写得如此恶毒,好像一座大坝决堤,所有积累的污秽和淤泥都被允许淹没我们的集体多媒体对话。

很快,即使非网页设计师和开发人员也开始注意到,比如 C.C.查普曼,著名书籍《内容*规则》的作者,表达了他对《今日秀》在 iPad 上不可用的不满:

介绍

这个问题迅速渗透到我们的在线娱乐讨论中。你不再需要成为网页设计师或开发人员才知道这里有一个真正的问题。

C.C.简单而直接地说话,但作者知道当谈到史蒂夫创造的 Flash/HTML5“视频”战争时,他已经说错了话。有时他争论自己的观点时过于热情和勇气,但事实是像网页设计师杰西卡·邦恩这样头脑清晰的人在提醒我们时是正确的,Flash 和 HTML5“视频”可以和平共存。

自史蒂夫发表声明以来不到一年的时间,像 ABC、CBS、CNN、ESPN、Facebook、Fox News、MSNBC、国家地理、Netflix、《纽约时报》、NPR、《人物》、《体育画报》、《时代》、Vimeo、《华尔街日报》、YouTube 等网站都采用了新的 HTML5“音频”和“视频”元素。截至目前,超过 60%的网络视频现在都支持 HTML5。可以说,新的 HTML5“音频”和“视频”功能是一些最令人兴奋和期待的新发展!

支持新 HTML5“音频”和“视频”元素的浏览器包括:

介绍

在本章中,我们将看一些现实生活中的例子,拒绝 Flash,了解新的“视频”和“音频”文件格式,为所有人显示“视频”,创建可访问的“音频”和“视频”,打造时尚的“音频”播放器,以及为移动设备嵌入“音频”和“视频”。

现在,让我们开始吧!

对 Flash 说不

作者的妈妈过去常说,万事都有其时机和地点,我们相信 Flash 也有其时机和地点。只是现在,随着技术的成熟,这位作者认为 Flash 的时间和地点越来越少。

对 Flash 说不

在过去的坏日子里,如果我们想在网页中使用 YouTube 视频,比如“Neutraface”,这是排版世界对 Lady Gaga 的“Pokerface”的回应,我们必须使用一些丑陋的代码,如下所示:

<object width="640" height="390">
<param name="movie" value="http://www.youtube.com/v/xHCu28bfxSI?fs=1&amp;hl=en_US"> </param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="img/xHCu28bfxSI?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="390"></embed>
</object>

那段代码又长又丑陋,复杂,而且无法通过验证测试。它还依赖于第三方插件。呃。

多年来,我们忍受了那些垃圾,但不再了。现在我们可以重建它——我们有技术。

如何做...

现在我们可以使用更加优雅的东西,而不是臃肿的object代码:

<video src="img/videosource.ogv"></video>

这就是所需的全部。它很简短,漂亮,而且验证通过。最重要的是,它不需要插件。再告诉我,为什么我们认为 Flash 是个好主意。

为了增加一些样式和功能,让我们再加入一点代码。

<video src="img/videosource.ogv" controls height="390" width="640"></video>

它是如何工作的...

那段代码应该很简单。您可能会猜到,src是指源“视频”文件,controls表示“视频”应该使用标准的播放和音量控件播放,heightwidth是不言自明的。

现代浏览器现在具有自己的本机 HTML5“音频”和“视频”播放控件。让我们来看看每一个,从苹果 Safari 开始:

它是如何工作的...

这是 Google Chrome 显示播放控件的方式:

它是如何工作的...

微软 Internet Explorer 9 显示方式不同:

它是如何工作的...

然后,Mozilla Firefox 以不同的方式显示:

它是如何工作的...

毫无疑问,Opera 以另一种方式显示播放控件:

它是如何工作的...

每一个看起来都不同。如果每一个不同的外观都满足您的需求,那太好了!如果不是,那肯定需要更多的工作来使它们行为和外观相似。

还有更多...

还有一些可选属性我们可以包括。它们是:

  • autobuffer - 这个布尔属性告诉浏览器在用户点击播放按钮之前就开始下载歌曲或电影。

  • autoplay - 可以猜到,这告诉浏览器自动播放 HTML5“音频”或“视频”。

  • loop - 也是一个布尔属性,它会一遍又一遍地播放 HTML5“音频”或“视频”文件。

  • preload - preload 属性在播放之前开始加载文件。

  • poster - poster属性是在新的 HTML5“视频”加载时显示的静态占位图像。显然,这个属性不适用于 HTML5“音频”文件。

无论您添加了这些可选属性中的哪些,最终您都将得到一种更漂亮、更语义化、更可访问的显示“音频”和“视频”的方法,而不是依赖 Flash 为您提供它。

一些好消息

canvas章节不同,关于新的 HTML5“音频”和“视频”元素的好消息是它们是可访问的。新的 HTML5“音频”和“视频”元素具有键盘可访问性。由于浏览器现在本地处理新的 HTML5“音频”和“视频”元素,它可以像有按钮而不是键一样支持您的键盘。这一点本身就可能大大促进对这项新技术的接受。

带有样式的视频

新的 HTML5 音频视频元素可以使用 CSS 进行视觉样式设置。我们可以使用 CSS 不仅控制播放器的大小,还可以添加:hover:transform效果。此外,我们可以使用 JavaScript 来控制新的 HTML5 音频视频的行为。酷!

Cover your assets

Flash 确实提供优势的一个领域是保护您的音频视频内容。请记住,根据性质,新的 HTML5 音频视频元素是开源的,没有数字版权管理。如果保护您的音频视频文件不被下载对您来说是一个不可接受的条件,那么新的 HTML5 音频视频元素不适合您 - Flash 可能仍然适合。这并不是说 Flash 提供了绝对的防盗保护 - 只是说,Flash 默认隐藏了查找媒体轨道的能力,而新的 HTML5 <audio><video>元素则将这些文件留在了公开的地方供任何人查看。然而,Flash Media Server 可以完全保护您的资产。

还不确定是选择 HTML5 音频和视频还是 Flash?试试这个实用提示列表。

HTML5 的好处包括:

  • 可访问性: 如果可访问性对您很重要(而且应该重要),那么新的 HTML5 音频视频元素是您最好的选择。

  • iOS: 如果您希望您的音频视频能在 iPhone 或 iPad 上显示,那么 HTML5 是您唯一的选择。

  • 移动设备: 除了苹果之外的移动设备对新的 HTML5 音频视频元素有很好的支持。

  • 视频/音频 流媒体: 如果您正在流媒体的内容不是专有的,并且不需要版权管理,那么 HTML5 是您的完美选择。

Flash 的好处包括:

  • 可访问性: 如果您不关心盲人或聋人,就不要支持他们。谁在乎你是否被起诉呢?

  • 动画: 毫无疑问,使用 Flash 的最好理由是如果您的网站上有复杂的动画。像jibjab.com这样的网站如果没有 Flash 就无法存在。

  • 仅桌面开发: 如果您不需要支持移动用户。那只是一个时尚而已。

  • 视频/音频 流媒体: 如果您不想分享并且必须锁定您的音频视频,使其不容易被人们下载,那就坚持使用 Flash。

  • 网络摄像头: 如果您使用网络摄像头(除了chatroulette.com之外,还有谁这样做?),那么 Flash 是最好的选择。

真的是使用 Flash 的最具说服力的理由吗?

Cover your assets

另请参阅

想要在所有主要浏览器中播放新的 HTML5 音频视频元素,包括一直到 Internet Explorer 6?谁不想呢?如果是这种情况,请查看免费的开源 Projekktor 项目,网址为projekktor.com。Projekktor 是 Sascha Kluger 的创意,使用 JavaScript 来确保各种支持的浏览器都能正确解释和显示特定的 HTML5 视频文件格式。

了解音频和视频文件格式

有很多不同的音频视频文件格式。这些文件不仅可以包括视频,还可以包括音频和元数据 - 都在一个文件中。这些文件类型包括:

  • .avi - 这是一个过去的文件格式,音频视频交错文件格式是由微软发明的。不支持今天大多数现代的音频视频编解码器。

  • .flv - Flash 视频。这曾经是 Flash 完全支持的唯一视频文件格式。现在它还包括对.mp4的支持。

  • .mp4.mpv - MPEG4 基于苹果的 QuickTime 播放器,并需要该软件进行播放。

它是如何工作的...

之前提到的每种视频文件格式都需要浏览器插件或某种独立软件进行播放。接下来,我们将看看不需要插件或特殊软件以及支持它们的浏览器的新开源音频视频文件格式。

  • H.264 已经成为最常用的高清视频格式之一。它被用于蓝光光盘以及许多互联网视频流媒体网站,包括 Flash、iTunes 音乐商店、Silverlight、Vimeo、YouTube、有线电视广播和实时视频会议。此外,H.264 有专利,因此从定义上来说,它不是开源的。支持 H.264 视频文件格式的浏览器包括:它是如何工作的...

提示

谷歌现在部分拒绝了 H.264 格式,更倾向于支持新的 WebM 视频文件格式。

  • Ogg 可能听起来很滑稽,但我向你保证,它的潜力是非常严肃的。Ogg 实际上是两个东西:Ogg Theora,这是一个视频文件格式;和 Ogg Vorbis,这是一个音频文件格式。Theora 实际上更多地是一个视频文件压缩格式,而不是一个播放文件格式,尽管它也可以用于播放。它没有专利,因此被认为是开源的。我们将在下一节讨论 Ogg Vorbis。

提示

有趣的事实:根据维基百科,“Theora 是以 Max Headroom 电视节目中 Edison Carter 的控制器 Theora Jones 命名的。”

支持 Ogg 视频文件格式的浏览器包括:

它是如何工作的...

  • WebM 是在线视频文件格式竞赛中最新的参与者。这种开源的音频/视频文件格式开发是由谷歌赞助的。WebM 文件包含了 Ogg Vorbis 音频流和 VP8 视频流。它得到了许多媒体播放器的支持,包括 Miro、Moovidia、VLC、Winamp 等,包括 YouTube 的初步支持。Flash 的制造商表示未来将支持 WebM,Internet Explorer 9 也将支持。目前支持 WebM 的浏览器包括:它是如何工作的...

还有更多...

到目前为止,这似乎是一个音频和视频文件格式的清单,最多只有零星的浏览器支持。如果你开始有这种感觉,那么你是对的。

事实上,没有一个音频或视频文件格式被确定为统治所有的真正格式。相反,我们开发人员经常不得不以多种格式提供新的音频和视频文件,让浏览器决定它最舒适和能够播放的格式。目前这是一个麻烦,但希望未来我们能够确定更少的格式,获得更一致的结果。

音频文件格式

还有许多音频文件格式。让我们来看看那些。

  • AAC - 高级音频编码文件更为人所知为 AAC。这种音频文件格式是为了在相同比特率下比 MP3 更好地发声而设计的。苹果使用这种音频文件格式来销售 iTunes 音乐商店的音乐。由于 AAC 音频文件格式支持数字版权管理,苹果提供受保护和未受保护格式的文件。由于 AAC 有专利,因此从定义上来说,我们不能完全称其为开源的音频文件格式。所有苹果硬件产品,包括他们的移动 iPhone 和 iPad 设备以及 Flash,都支持 AAC 音频文件格式。支持 AAC 的浏览器包括:音频文件格式

  • MP3 - MPEG-1 音频层 3 文件更为人所知为 MP3。除非你一直躲在石头下,你知道 MP3 是今天最普遍使用的音频文件格式。这些文件可以播放两个声道的声音,并且可以使用多种比特率进行编码,最高可达 320。一般来说,比特率越高,音频文件的声音就越好。这也意味着更大的文件大小,因此下载速度更慢。MP3 有专利,因此从定义上来说,我们也不能完全称其为开源的音频文件格式。支持 MP3 的浏览器包括:音频文件格式

  • Ogg - 我们之前讨论过 Ogg Theora 视频文件格式。现在,让我们来看看 Ogg Vorbis 音频格式。如前所述,Ogg 文件没有专利,因此被认为是开源的。

提示

另一个有趣的事实:根据维基百科,“Vorbis”是以《蓝色星球》中的角色 Exquisitor Vorbis 命名的,由特里·普拉切特的《小神灵》中的角色 Exquisitor Vorbis 命名的。

音频文件格式

文件格式不可知论

我们花了很多时间来研究这些不同的videoaudio文件格式。每种格式都有其优点和缺点,并且受到各种浏览器的支持(或不支持)。有些比其他的更好,有些听起来和看起来比其他的更好。但好消息是:新的 HTML5 <video><audio>元素本身是文件格式不可知的!这些新元素不在乎您引用的是什么类型的videoaudio文件。相反,它们提供您指定的任何内容,并让每个浏览器做它最擅长的事情。

我们能不能有一天停止这种疯狂?

最重要的是,直到一个新的 HTML5 audio和一个新的 HTML5 video文件格式成为所有浏览器和设备的明确选择,audiovideo文件将不得不被编码多次进行播放。不要指望这种情况很快会改变。

为所有人显示视频

根据作者马克·皮尔格里姆的说法,您的 HTML5 网络video工作流程将如下所示:

  • 制作一个使用 WebM(VP8 和 Vorbis)的版本。

  • 制作另一个版本,使用 H.264 基准video和 AAC“低复杂度”audio在 MP4 容器中。

  • 制作另一个版本,使用 Theora video和 Vorbis audio在 Ogg 容器中。

  • 从单个<video>元素链接到所有三个video文件,并回退到基于 Flash 的video播放器。

Kroc Camen 在创建“面向所有人的视频”时确实做到了这一点,这是一段 HTML 代码,如果用户的浏览器可以处理它,就会显示新的 HTML5 video元素,如果不能,就会显示 Flash 电影 —— 这一切都不需要 JavaScript。让我们看看 Kroc 是如何做到的:camendesign.com/code/video_for_everybody

为所有人显示视频

如何做...

<video controls height="360" width="640">
<source src="img/__VIDEO__.MP4" type="video/mp4" />
<source src="img/__VIDEO__.OGV" type="video/ogg" />
<object width="640" height="360" type="application/ x-shockwave-flash" data="__FLASH__.SWF">
<param name="movie" value="__FLASH__.SWF" />
<param name="flashvars" value="controlbar=over&amp; image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
<img src="img/__VIDEO__.JPG" width="640" height="360" alt="__TITLE__" title="No video playback capabilities, please download the video below" />
</object>
</video>
<p><strong>Download Video:</strong>
Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
</p>

仔细看,很容易看出 Kroc 做了什么。首先,他调用了浏览器本地播放的controls,以及新的 HTML5 video元素关联的heightwidth

<video controls height="360" width="640">

接下来,Kroc 依次调用每个新的 HTML5 video源,从 MP4 文件开始。桌面浏览器不太在乎 HTML5 video文件的包含顺序,但 iPad 对于想要首先指定 MP4 文件很挑剔,所以好吧。又是你赢了,史蒂夫·乔布斯。

<source src="img/__VIDEO__.MP4" type="video/mp4" />
<source src="img/__VIDEO__.OGV" type="video/ogg" />

然后,Kroc 通过调用相同文件的 Flash video版本来为无法处理新的 HTML5 video元素的软弱浏览器打赌。

<object width="640" height="360" type="application/x-shockwave-flash" data="__FLASH__.SWF">
<param name="movie" value="__FLASH__.SWF" />
<param name="flashvars" value="controlbar=over&amp; image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
<img src="img/__VIDEO__.JPG" width="640" height="360" alt="__TITLE__" title="No video playback capabilities, please download the video below" />
</object>

最后,Kroc 通过提示用户选择下载新的 HTML5 video文件本身,无论是封闭的(MP4)还是开放的(Ogg)格式,增加了一个不错的额外功能。分享就是关怀。

<p><strong>Download Video:</strong>
Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
</p>

提示

当然,您会用自己文件的路径替换诸如“VIDEO.MP4”之类的东西。

这种方法非常成功,因为无论您使用什么网络浏览器,您都可以看到某些东西 —— 而无需使用 JavaScript 或下载 Flash。

它是如何工作的...

这个概念实际上非常简单:如果您的浏览器能够播放新的 HTML5 video元素文件,那么您将会看到它。如果它不能支持,代码堆栈中还包括了 Flash 电影,所以您应该会看到它。如果由于某种原因,您的浏览器无法原生支持新的 HTML5 video元素,Flash 播放器崩溃或不可用,您将会看到一个静态图像。每个人都有所涵盖。

使用这种方法显示新的 HTML5 video元素的浏览器包括:

它是如何工作的...

使用这种方法显示 Flash video的浏览器包括:

它是如何工作的...

还有更多...

所有其他 Flash video嵌入方法都会提示用户下载 Flash(如果尚未安装)。而“面向所有人的视频”独特之处在于它不会这样做。作者 Kroc Camen 出于设计目的这样做,他说:

“用户已经有足够的安全问题了,而不需要随机的网站提示他们安装东西-对于那些不想要或不能使用 Flash 的人来说,这更加恼人。”

浪费一个艺术家是一件可怕的事情

Kroc 提醒我们确保我们的服务器使用正确的mime-types,并建议将这些行放在你的.htaccess文件中:

AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm

外部“Video for Everybody”

现在 WordPress 有一个“Video for Everybody”插件,网址是wordpress.org/extend/plugins/external-video-for-everybody。现在你也可以在你的博客上轻松使用 Kroc 的方法。

灵活处理你的方法

稍后,我们将研究一种方法,该方法与 Kroc 的方法实现了几乎相同的效果,但这次是使用 JavaScript。记住:做对你、你的项目和最重要的是你的客户最有意义的事情。

另请参阅

Humanstxt.org 是一个项目,旨在让网站背后的开发人员更加知名。该网站鼓励开发人员包含一个小文本文件,其中包含有关为创建和构建网站做出贡献的每个团队成员的信息。请访问:humanstxt.org

创建可访问的音频和视频

我们已经非常广泛地研究了如何向人们提供在线 HTML5video,而不管他们的浏览器是什么,但是对依赖辅助技术的人却没有给予太多关注。现在结束了。

如何做到…

首先,我们将从 Kroc Camen 的“Video for Everybody”代码块开始,并研究如何使其具有可访问性,最终看起来像这样:

<div id="videowrapper">
<video controls height="360" width="640">
<source src="img/__VIDEO__.MP4" type="video/mp4" />
<source src="img/__VIDEO__.OGV" type="video/ogg" />
<object width="640" height="360" type="application/ x-shockwave-flash" data="__FLASH__.SWF">
<param name="movie" value="__FLASH__.SWF" />
<param name="flashvars" value="controlbar=over&amp; image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
<img src="img/__VIDEO__.JPG" width="640" height="360" alt="__TITLE__" title="No video playback capabilities, please download the video below" />
</object>
<track kind="captions" src="img/videocaptions.srt" srclang="en" />
<p>Final fallback content</p>
</video>
<div id="captions"></div>
<p><strong>Download Video:</strong>
Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
</p>
</div>

它是如何工作的…

你会注意到的第一件事是,我们将新的 HTML5video元素包装在一个包装器div中。虽然从语义上讲这并不是严格必要的,但它将为我们的 CSS 提供一个很好的“钩子”。

<div id="videowrapper">

下一部分的大部分内容应该是从前一部分中可以识别的。这里没有改变:

<video controls height="360" width="640">
<source src="img/__VIDEO__.MP4" type="video/mp4" />
<source src="img/__VIDEO__.OGV" type="video/ogg" />
<object width="640" height="360" type="application/ x-shockwave-flash" data="__FLASH__.SWF">
<param name="movie" value="__FLASH__.SWF" />
<param name="flashvars" value="controlbar=over&amp;
image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
<img src="img/__VIDEO__.JPG" width="640" height="360" alt="__TITLE__" title="No video playback capabilities, please download the video below" />
</object>

到目前为止,我们仍在使用向能够处理它的浏览器提供新的 HTML5video元素的方法,并将 Flash 作为我们的第一个备用选项。但是,如果 Flash 不是一个选择,接下来会发生什么很有趣:

<track kind="captions" src="img/videocaptions.srt" srclang="en" />

你可能会想,那是什么鬼。

track元素允许作者为媒体元素指定显式的外部定时文本轨道。它本身不代表任何东西。”- W3C HTML5 规范

现在我们有机会使用 HTML5 规范的另一个新部分:新的<track>元素。现在,我们可以引用kind="captions"中指定的外部文件类型。你可以猜到,kind="captions"是用于字幕文件,而kind="descriptions"是用于audio描述。当然,src调用特定文件,srclang设置新的 HTML5track元素的源语言。在这种情况下,en代表英语。不幸的是,目前没有浏览器支持新的track元素。

最后,我们允许最后一点备用内容,以防用户无法使用新的 HTML5video元素或 Flash 时,我们给他们一些纯文本内容。

<p>Final fallback content</p>

现在,即使用户看不到图像,他们至少会得到一些描述性内容。

接下来,我们将创建一个容器div来容纳我们基于文本的字幕。因此,目前没有浏览器支持新的 HTML5audiovideo元素的闭合字幕,我们必须留出空间来包含我们自己的:

<div id="captions"></div>

最后,我们将包括 Kroc 的文本提示,以下载 HTML5video的封闭或开放文件格式:

<p><strong>Download Video:</strong>
Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
</p>

还有更多…

除了新的 HTML5audiovideo元素的可选controls属性之外,还有可选的loop属性。你可能会猜到,这个例子将允许 HTML5video一直播放:

<video controls height="360" loop width="640">

始终考虑可访问性

我们默认的最终描述性内容可能是为使用辅助技术的人提供可下载链接的替代位置。这将使能够看到或听到的人无法下载,因此您应确定这种方法是否适合您。

浏览器支持

对于新的 HTML5“音频”和“视频”元素,具有最佳辅助功能支持的网络浏览器包括:

浏览器支持

查看更多

您可以在html5accessibility.com上跟踪 HTML5 的可访问性。该网站跟踪新的 HTML5 功能,如“音频”和“视频”,以及在哪些浏览器中可用。您可能会惊讶地发现,截至目前,Opera 是最不友好的可访问性网络浏览器,甚至低于微软 Internet Explorer 9。令人惊讶。

另请参阅

Video.Js 是另一个免费的开源 HTML5 视频播放器。它轻巧,不使用图像,但仍然可以通过 CSS 完全定制。它看起来很棒,并支持苹果 Safari,谷歌 Chrome,微软 Internet Explorer 9,Mozilla Firefox 和 Opera,同时还支持 IE 6-8 的回退。它甚至适用于 iPhone,iPad 和 Android 等移动设备。在videojs.com上查看。

打造时尚的音频播放器

Neutron Creations 的负责人兼联合创始人兼前端开发人员 Ben Bodien 为 Tim Van Damme 的 The Box 播客创建了定制的 HTML5“音频”播放器,网址为thebox.maxvoltar.com。Ben 的创作快速,直观且时尚。让我们更深入地了解他是如何做到的。

打造时尚的音频播放器

Ben 的自定义 HTML5“音频”播放器具有被采访者(在这种情况下是 Shaun Inman)的吸引人照片,播放/暂停按钮,显示播放进度的轨道,以及如果您选择的话,将 HTML5“音频”播放器弹出到单独的窗口的能力。就是这样。没有更多的需要。作为一个额外的触摸,注意 HTML5“音频”播放器栏的轻微透明度的细节。平滑。

如何做...

起初,Ben 的标记似乎看起来简单欺骗人:

<p class="player">
<span id="playtoggle" />
<span id="gutter">
<span id="loading" />
<span id="handle" class="ui-slider-handle" />
</span>
<span id="timeleft" />
</p>

等一下,我听到你在想,“HTML5音频标签在哪里?!”别担心。Ben 是个聪明人,对此有计划。但首先让我们看看他到目前为止做了什么。

<p class="player">

到目前为止,这很简单。Ben 创建了一个包装元素(在这种情况下是<p>)来放置他的播放器。他可以使用<div>代替吗?也许。做对你和你的项目最有意义的事情。

<span id="playtoggle" />

然后,Ben 使用这个自闭合的(注意末尾的斜杠)span来进行播放/暂停切换按钮。

<span id="gutter">
<span id="loading" />
<span id="handle" class="ui-slider-handle" />
</span>

现在,事情变得有趣起来。Ben 的“gutter”span容纳了时间轴跟踪,其中有一个指示 HTML5“音频”文件加载或缓冲进度的条形元素,以及指示播放头的圆形元素,如果您选择,可以来回“擦洗”。

<span id="timeleft" />

最后,Ben 使用另一个自闭合的span来显示剩余时间,以分钟和秒为单位。

提示

<span>元素可以胜任,但它并不是非常语义化,是吗?Patrick H. Lauke 迅速指出,使用可聚焦元素将大大提高这种方法对依赖辅助技术的人的可访问性。

它是如何工作的...

Ben 使用 jQuery 来检测对 HTML5“音频”的支持。

if(!!document.createElement('audio').canPlayType) {
var player = '<p class="player"> ... </p>\
<audio>\
<source src="img/episode1.ogg" type="audio/ogg"></source>\
<source src="img/episode1.mp3"
type="audio/mpeg"></source>\
<source src="img/episode1.wav" type="audio/ x-wav"></source>\
</audio>';
$(player).insertAfter("#listen .photo");
}

在这段代码中,我们可以看到,如果浏览器支持 HTML5“音频”,它将提供完整的 HTML5<audio>标签,包括对.ogg,.mp3.wav的回退,这是我们尚未使用过的文件格式。由于新的 HTML5<audio><video>元素是文件格式不可知的,因此.wav文件也应该可以正常工作。

Ben 创建了一个简单的 JavaScript 代码,允许浏览器做他们感觉最舒适的事情。如果这种方法对您和您的项目有意义,请考虑这种方法,但请记住,您依赖 JavaScript 来完成繁重的工作,而不是我们已经看过的其他不依赖它的方法。

提示

请注意,如果您使用<div>来包含 HTML5 的video播放器,那么 JavaScript 也必须进行调整。简单地说,<p class="player"></p>将被更改为<div class="player"></div>

还有更多...

到目前为止,我们已经为播放器设置了标记,并“嗅探”了任何特定浏览器想要的文件格式。现在,我们需要添加一些功能。

audio = $('.player audio').get(0);
loadingIndicator = $('.player #loading');
positionIndicator = $('.player #handle');
timeleft = $('.player #timeleft');
if ((audio.buffered != undefined) && (audio.buffered.length != 0)) {
$(audio).bind('progress', function() {
var loaded = parseInt(((audio.buffered.end(0) / audio.duration) * 100), 10);
loadingIndicator.css({width: loaded + '%'});
});
}
else {
loadingIndicator.remove();
}

然后添加一个函数来计算播放头的位置,以确定剩余时间,注意如果剩余时间需要,要包括前导零。

$(audio).bind('timeupdate', function() {
var rem = parseInt(audio.duration - audio.currentTime, 10),
pos = (audio.currentTime / audio.duration) * 100,
mins = Math.floor(rem/60,10),
secs = rem - mins*60;
timeleft.text('-' + mins + ':' + (secs > 9 ? secs : '0' + secs));
if (!manualSeek) { positionIndicator.css({left: pos + '%'}); }
if (!loaded) {
loaded = true;
$('.player #gutter').slider({
value: 0,
step: 0.01,
orientation: "horizontal",
range: "min",
max: audio.duration,
animate: true,
slide: function() {
manualSeek = true;
},
stop:function(e,ui) {
manualSeek = false;
audio.currentTime = ui.value;
}
});
}
});

唯一剩下的就是调用播放/暂停按钮的功能。

$(audio).bind('play',function() {
$("#playtoggle").addClass('playing');
}).bind('pause ended', function() {
$("#playtoggle").removeClass('playing');
});
$("#playtoggle").click(function() {
if (audio.paused) { audio.play(); }
else { audio.pause(); }
});

风格和内容

在简单的标记和详细的 JavaScript 之后,创建本的定制 HTML5 audio播放器,唯一剩下的就是对其进行样式设置:

.player {
display: block;
height: 48px;
width: 400px;
position: absolute;
top: 349px;
left: -1px;
-webkit-box-shadow: 0 -1px 0 rgba(20, 30, 40, .75);
-moz-box-shadow: 0 -1px 0 rgba(20, 30, 40, .75);
-o-box-shadow: 0 -1px 0 rgba(20, 30, 40, .75);
box-shadow: 0 -1px 0 rgba(20, 30, 40, .75);
border-top: 1px solid #c2cbd4;
border-bottom: 1px solid #283541;
background: #939eaa;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(174, 185, 196, .9)), to(rgba(110, 124, 140, .9)), color-stop(.5, rgba(152, 164, 176, .9)), color-stop(.501, rgba(132, 145, 159, .9)));
background: -moz-linear-gradient(top, rgba(174, 185, 196, .9), rgba(152, 164, 176, .9) 50%, rgba(132, 145, 159, .9) 50.1%, rgba(110, 124, 140, .9));
background: linear-gradient(top, rgba(174, 185, 196, .9), rgba(152, 164, 176, .9) 50%, rgba(132, 145, 159, .9) 50.1%, rgba(110, 124, 140, .9));
cursor: default;
}
#playtoggle {
position: absolute;
top: 9px;
left: 10px;
width: 30px;
height: 30px;
background: url(../img/player.png) no-repeat -30px 0;
cursor: pointer;
}
#playtoggle.playing {background-position: 0 0;}
#playtoggle:active {top: 10px;}
#timeleft {
line-height: 48px;
position: absolute;
top: 0;
right: 0;
width: 50px;
text-align: center;
font-size: 11px;
font-weight: bold;
color: #fff;
text-shadow: 0 1px 0 #546374;
}
#wrapper #timeleft {right: 40px;}
#gutter {
position: absolute;
top: 19px;
left: 50px;
right: 50px;
height: 6px;
padding: 2px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
background: #546374;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#242f3b), to(#516070));
background: -moz-linear-gradient(top, #242f3b, #516070);
background: linear-gradient(top, #242f3b, #516070);
-webkit-box-shadow: 0 1px 4px rgba(20, 30, 40, .75) inset, 0 1px 0 rgba(176, 187, 198, .5);
-moz-box-shadow: 0 1px 4px rgba(20, 30, 40, .75) inset, 0 1px 0 rgba(176, 187, 198, .5);
-o-box-shadow: 0 1px 4px rgba(20, 30, 40, .75) inset, 0 1px 0 rgba(176, 187, 198, .5);
box-shadow: 0 1px 4px rgba(20, 30, 40, .75) inset, 0 1px 0 rgba(176, 187, 198, .5);
}
#wrapper #gutter {right: 90px;}
#loading {
background: #fff;
background: #939eaa;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#eaeef1), to(#c7cfd8));
background: -moz-linear-gradient(top, #eaeef1, #c7cfd8);
background: linear-gradient(top, #eaeef1, #c7cfd8);
-webkit-box-shadow: 0 1px 0 #fff inset, 0 1px 0 #141e28;
-moz-box-shadow: 0 1px 0 #fff inset, 0 1px 0 #141e28;
-o-box-shadow: 0 1px 0 #fff inset, 0 1px 0 #141e28;
box-shadow: 0 1px 0 #fff inset, 0 1px 0 #141e28;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
display: block;
float: left;
min-width: 6px;
height: 6px;
}
#handle {
position: absolute;
top: -5px;
left: 0;
width: 20px;
height: 20px;
margin-left: -10px;
background: url(../img/player.png) no-repeat -65px -5px;
cursor: pointer;
}
.player a.popup {
position: absolute;
top: 9px;
right: 8px;
width: 32px;
height: 30px;
overflow: hidden;
text-indent: -999px;
background: url(../img/player.png) no-repeat -90px 0;
}
.player a.popup:active {background-position: -90px 1px;}Content matters

当包裹的内容引人入胜时,花时间创造有趣的东西会更容易且更有意义。Box 音频采访总是很有趣——只是遗憾的是作者 Tim Van Damme 并不经常发布它们。希望将来会有所改变。请访问thebox.maxvoltar.com查看。

注意细节

当页面上一次只有一个新的 HTML5 audiovideo元素时,这种方法效果很好。如果您需要多个,您将需要修改 JavaScript 以连接到标记中的多个“挂钩”。

另请参阅

SublimeVideo 采用了一种不同的方法来进行 HTML5 在线video播放:在这种情况下,播放器不是由您创建或托管的,而是由播放器制造商自己在云中创建的。好处是您始终拥有可能的最新、最新鲜的播放器版本。这样,当新功能可用或错误修复时,您无需做任何操作。您自动拥有最新的功能。请访问sublimevideo.net查看。

为移动设备嵌入音频和视频

到目前为止,我们只是简单地涉及了移动体验,但随着对越来越智能的移动设备的开发增加,我们需要把注意力转向如何在这些设备上显示我们的新 HTML5 audiovideo。以下是方法。

如何做...

既然我们知道如何为目标受众选择 HTML5 audiovideo文件格式,现在我们可以把注意力转向确保他们不仅可以在台式电脑和笔记本电脑上听到或观看,还可以在移动设备上听到或观看。

我们将从vimeo.com创建一个免费账户。注册完成后,在主菜单中选择上传|视频功能。您将选择要上传的文件,添加可选的元数据,然后让 Vimeo 服务器设置您的文件。接下来就是真正的激动人心的时刻:嵌入video。从 Vimeo 主菜单中选择工具|嵌入此视频

如何做...

它是如何工作的...

Vimeo 以前使用的是我们之前看过的老式 Flash 嵌入方法。现在它使用基于 iFrame 的方法,可以让 HTML5 video在 iPhone、iPad 和其他移动设备上播放。以下是一个示例,基于作者上传的video

<iframe src="img/20958090" width="400" height="300" frameborder="0"></iframe><p><a href="http://vimeo.com/20958090">Untitled</a> from <a href="http://vimeo.com/user6281288">Dale Cruse</a> on <a href="http://vimeo.com">Vimeo</a>.</p>

还有更多...

一旦您将基于 iFrame 的代码片段复制并粘贴到网页上,并在 iPhone 或 iPad 上查看它,您应该会看到一个移动友好的 HTML5 video,您可以像这样使其全屏:

还有更多...

Vimeo 提供了更多

Vimeo 还允许您从电子邮件联系人列表中添加朋友,创建video订阅,制作小部件等等。他们现在甚至提供视频学校,帮助用户了解捕捉、编辑和分享video的最有效方法。

全方位的

YouTube,世界上最受欢迎的在线视频观看网站,现在也使用基于 iFrame 的嵌入视频的方法。我们可以采用本章开头使用的“Neutraface”视频,使用新的基于 iFrame 的嵌入方法,最终得到更具语义和友好性的结果。它也通过了验证!

<iframe title="YouTube video player" width="1280" height="750" src="img/xHCu28bfxSI?rel=0&amp;hd=1" frameborder="0" allowfullscreen></iframe>

看看这样多漂亮!

我们已经完成了一整个循环,并完全改变了我们在现代浏览器中捕捉、编辑和播放视频的能力,同时支持那些依赖辅助技术和移动设备的人。这是一个可以发展的方向。

另请参阅

Adobe 是否在自掘坟墓?几乎没有。2011 年初,Adobe 推出了一个名为“Wallaby”的免费 Flash 到 HTML5 转换器。不幸的是,许多设计师和开发人员认为 Adobe 在声称 Wallaby 可以使用 Web 标准将 Flash 导出到 HTML5 时过于夸大其词。事实上,它所做的只是将在 Flash CS5 或更高版本中创建的最简单的动画转换为简单的标记和样式。它没有能力将 ActionScript 转换为 JavaScript,这种能力才会真正使该工具有价值。在 John Nack 的博客上查看有关 Wallaby 公告的信息blogs.adobe.com/jnack/2011/03/wallaby-flash-to-html5-conversion-tool-now-available.html

第九章:数据存储

在本章中,我们将涵盖:

  • 测试浏览器是否支持数据存储

  • 使用浏览器开发工具监视 Web 存储

  • 设置和获取会话存储变量

  • 设置和获取本地存储变量

  • 将本地存储字符串转换为数字使用parseInt

  • 创建 Web SQL 数据库

  • 使用 Web SQL 数据库

  • 创建缓存清单并离线使用站点

  • 使用 Geolocation API 和geo.js显示当前位置

介绍

HTML5 引入了一种新的存储信息的方式,而不使用 cookie。这为设计师和开发人员提供了更多的灵活性,以处理和显示动态内容。我们将从测试浏览器是否支持三种主要数据存储方法开始,并最终创建一个使用本地存储来存储和访问视频的 HTML5 页面。尽管这些示例都是基于彼此构建的,但您不必按照它们呈现的顺序完成它们。本章的示例文件可在www.packtpub.com/support?nid=7940上下载。

测试浏览器是否支持数据存储

知道如何快速测试浏览器是否支持您想要使用的数据存储方法将使页面和应用程序的开发更加容易。在这个示例中,我们将创建一个脚本,查询浏览器的 DOM,以测试对不同数据存储方法的支持。

做好准备

您将需要访问现代浏览器,如 Firefox 3.6,或流行浏览器的最新版本,如 Google Chrome,Opera,Safari 或 Internet Explorer。

如何做...

首先,我们将创建一个简单的 html 页面。打开一个 HTML 编辑程序或文本编辑器,并输入基本 HTML5 页面的起始代码:

<!doctype html><html lang="en"><head><title>Client-side Storage Test for HTML5</title>
<meta charset="utf-8">

现在需要对测试页面的外观进行样式设置。我们将在 HTML 页面的<head>标记中使用<style>标记,但您也可以将它们放在单独的 CSS 文件中。

<style>
#results { background-color: #ffcc99; border: 1px #ff6600 solid; color: #ff6600; padding: 5px 20px; margin-bottom: 10px; }
#results .value { font-weight: bold; }
#results h3 { color: #333333; }
</style>

输入一个关闭的head标记,然后创建一个body标记如下所示。请注意,主要区别在于我们在页面加载时调用RunTest()函数来激活。

</head><body onload="RunTest();">

创建一个段落标记,其中包含类似下面所示的描述性文本。关闭标记,并创建一个包含结果标题的<h3>标题标记。

<p>Does your browser support all storage methods?</p>
<div id="results"><h3>Browser Data Storage Support Results</h3>

现在,输入每种存储方法,然后输入一个由类值样式化的 span 标记。输入存储方法的 ID 和文本“不支持”。关闭 span 标记并添加一个换行标记,以便在浏览器窗口中将结果分开显示在单独的行上。结果显示区域应该如下代码块所示:

Session Storage: <span class="value" id="session">not supported</span><br/>
Local Storage: <span class="value" id="local">not supported</span> <br />
Database Storage: <span class="value" id="db">not supported</span> <br /></div>

我们几乎完成了创建我们的测试页面。创建一个段落来解释测试的目的。用<footer>标记结束内容区域,以包含我们接下来要添加的脚本块。描述性文本应如下代码所示:

<p>The test above shows whether the browser you are currently using supports a data storage method.</p> <footer>

现在,我们将添加script标记,以便浏览器处理一个小型测试程序:

<script language="javascript">
function RunTest() {
for (var mydata in window)
{

接下来,我们将创建一个包含每种数据存储方法的代码块的 case 语句,我们将要测试:

switch (mydata) {
case "sessionStorage": document.getElementById("session").innerHTML = "supported";
break;
case "localStorage": document.getElementById("local").innerHTML = "supported";
break;
case "openDatabase": document.getElementById("db").innerHTML = "supported";
break;
} }} </script> </footer> </body> </html>

将文件保存为data-storage-support-test.html,并在浏览器窗口中打开它。您应该看到类似以下截图的结果:

如何做...

它是如何工作的...

我们创建的 HTML5 测试页面使用了一小段 JavaScript 代码来查询浏览器是否支持特定的存储方法。我们首先编写了一个标准的 HTML5 页面,包括适当的<html><head>和其他文档标签。如果您需要复习它们,它们在本书的早期章节中有介绍。接下来,我们使用简化的<script>标签设置了 JavaScript 代码片段的开头块。HTML5 JavaScript API 在本书的其他地方有更详细的介绍。我们创建了一个名为RunTest()的函数来包含变量和代码。然后创建了两个变量。变量supp被赋予了一个空字符串的值。这将包含每种存储方法的最终支持结果。我们正在循环遍历 window 对象的属性。在每次迭代中,当前属性暂时存储在mydata变量中。这使我们能够测试属性与三种情况进行比较。

接下来,我们使用 switch 语句来测试mydata变量与我们感兴趣的特定属性。因为我们一次只测试一个值,而且列表很短,这是测试每种存储方法支持的好方法。switch语句的主体包含三种情况,每种情况对应一种存储方法。每种情况都包含一个必须评估的表达式。如果支持存储方法,则每种情况的最终操作是将文档主体中结果文本的值从“不支持”更改为“支持”,如果表达式评估为真。如果情况评估为假,则页面结果部分显示的文本将保持不变。

创建代码后,我们使用 CSS 样式控制了结果的呈现。使用一个名为 results 的 div 标签创建了一个用于显示框的容器,并指定了背景颜色、字体颜色和粗细。这是 html 页面头部的最后一个代码块。

然后创建了页面的主体部分。使用onload命令设置了页面在浏览器中加载时激活测试。编写了结果框的开头文本和标题,并将每个结果的显示文本与唯一的 ID 相关联。然后输入了闭合标签以完成页面。保存页面后,当在浏览器窗口中查看测试页面时,结果将显示在屏幕上。截图中使用的浏览器是 Firefox 3.6.13。我们看到的结果反映了 Firefox 在 3.6 和 4.0.3 版本中对存储方法的当前支持。这帮助我们确定我们可以期望 Firefox 访问者轻松查看和使用依赖本地存储和会话存储方法的网页上的任何功能。他们将无法利用任何依赖于 WebSQL 的功能。

还有更多...

测试网站和在线应用程序从未如此简单。有许多可用的工具和服务可用于在不同平台和浏览器上进行测试。

移动测试

您可以在智能设备上下载多个浏览器,如 iPod Touch 或 iPad,从而可以测试移动设备和不同浏览器上丰富媒体内容的响应性。

Adobe 浏览器实验室

不需要 Adobe CS5 即可尝试 Adobe BrowserLab,这是一个与 Adobe CS5 产品集成的在线跨浏览器测试工具。访问browserlab.adobe.com了解更多信息。

使用 BrowserShots 进行免费的跨浏览器和操作系统测试

对于预算有限且有时间的人来说,BrowserShots.org是一个替代选择。该网站允许访问者输入其网站的 URL,然后从庞大的浏览器和操作系统列表中进行选择。使用免费版本的服务可能需要几分钟才能看到结果。

使用浏览器开发工具监视 Web 存储

Web 存储可能很难测试。使用浏览器中的开发者工具,如 Safari 或 Firefox 附加组件,如 Firebug,可以更容易地诊断问题并跟踪变量的值。在这个示例中,我们将使用 Google Chrome 浏览器中的原生开发者工具来探索浏览器本地存储区中存储的键/值对。

准备工作

您需要一个最新版本的 Google Chrome 浏览器和本章的一个本地存储代码文件。

如何操作...

在 Google Chrome 浏览器窗口中打开本章中的一个本地存储练习文件。

点击查看,从查看菜单中选择开发者,然后从开发者弹出菜单中选择开发者工具

开发者窗口出现在当前页面上时,选择资源选项卡,点击 Google Chrome 开发者工具窗口导航区域中的本地存储,然后选择其中的子菜单。您应该看到类似以下截图的结果:

如何操作...

在 Google 开发者工具窗口的资源选项卡下的本地存储部分,我们可以访问每个页面的本地存储区域。它在屏幕右侧显示键和它们对应的值。如果右键单击对象,您将有删除它的选项。

工作原理...

我们加载了一个我们知道使用本地存储的页面,以测试 Google Chrome 浏览器中的 Google 开发者工具窗口如何显示键/值对。

当我们在开发者工具的左侧菜单中导航时,我们可以选择不同的 Web 存储方法和其他资源。

还有更多...

有许多免费的插件和原生浏览器工具供开发人员利用。

即使不使用 Firefox,也可以使用 Firebug 附加组件

Firefox 用户长期以来一直在使用 Firebug 附加组件(getfirebug.com/downloads)来调试和浏览网站和其他在线应用程序。Opera、Google Chrome、Safari 和 IE 6+的用户可以使用 Firebug Lite(getfirebug.com/firebuglite),并通过轻量级的书签工具体验类似的功能,他们可以轻松地添加到他们的浏览器中。

Safari 开发者工具是 Safari 浏览器的原生工具

在打开 Safari 浏览器时,点击Safari,选择首选项,然后点击高级选项卡。点击“在菜单栏中显示开发菜单”旁边的复选框,开始使用原生开发者工具。

设置和获取会话存储变量

会话存储和本地存储都共享 Web 存储 API。在这个示例中,我们将定义两个会话存储变量,然后在屏幕上显示它们。

准备工作

您需要一个支持会话存储的最新版本的浏览器。如果您在本地计算机上测试文件,Safari 和 Google Chrome 会有最佳响应。

如何操作...

首先,我们将创建一个 HTML5 页面的头部区域和一个开放的body标签:

<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Show me the session storage</title></head><body>

添加一个section和一个article标签。给 article 标签一个 ID 为“aboutyou”。

<section><article id="aboutyou"><p></p></section>

接下来,我们将使用setItem方法创建两个会话存储变量,如下面的代码块所示:

<footer><script>sessionStorage.setItem('nickname', 'Jumpin Joseph'); sessionStorage.setItem('interest', 'bike ramps and bmx racing');

现在我们将使用getElementByIDgetItem方法在屏幕上显示我们刚刚设置的会话存储变量:

document.getElementById('aboutyou').innerHTML = ("Your nickname is: " + sessionStorage.getItem('nickname') + "." + " You are interested in: " + sessionStorage.getItem('interest') + "."); </script></footer></body></html>

结果应该在浏览器中的 HTML 页面上显示,类似于以下截图中显示的方式:

如何操作...

工作原理...

在这个示例中,我们为两个会话变量设置了唯一的值。会话存储使用键/值对,因此在创建时必须为每个变量设置一个值。默认情况下,这些值都是字符串。

我们通过输入sessionStorage.setItem('为人的昵称定义了一个会话变量,然后为我们的变量添加了一个名称。

我们将变量命名为"nickname",并赋予它值“Jumpin Joseph”:'nickname', 'Jumpin Joseph')

当我们创建第二个会话变量来包含名为"interest"的变量及其值时,我们使用了与设置第一个会话变量时相同的语法格式。

尽管通常这些变量将由表单中的值填充,但我们在示例中专注于使用正确的语法。sessionStorage关键字标识了存储方法的类型。我们在关键字后面加上一个句点,附加了setItem动作到关键字上。然后声明了变量nickname并赋予了值Jumpin Joseph。当使用时,这将告诉浏览器创建一个名为nickname的新会话存储变量,并将Jumpin Joseph的值存储在其中。然后我们创建了第二个会话存储变量,只是因为我们可以。在本章的本地存储示例中,我们将使用表单来获取本地存储变量的值,以便全面了解存储方法的创建、使用和销毁的完整生命周期视图。

还有更多...

会话存储为我们提供了一种更强大的方式来提供短期客户端存储。

一个浏览器,一个会话

会话存储最适合于不需要访问者使用多个浏览器标签来浏览网站,并且需要存储是临时的情况。虽然 HTML5 规范的数据存储区域仍在不断发展,安全性在金融机构或其他需要高度安全信息的网站使用方面并没有长期的记录,但仍然有许多有用的方法可以利用会话存储。

另请参阅

设置和获取本地存储变量的教程

设置和获取本地存储变量

尽管会话存储是临时的,只在浏览器会话处于活动状态时持续。本地存储甚至在关闭浏览器后仍然存在。在这个教程中,我们将使用 HTML5 的contenteditable属性和本地存储创建一个故事写作应用程序。

准备工作

您应该使用最近更新的浏览器。这个教程在 Google Chrome 和 Safari 中效果最佳,但在 Firefox 中也可以正常运行。

如何做...

首先创建一个基本的 HTML5 页面,然后在开放和关闭的head标签之间添加一个脚本标签。脚本应该链接到 1.5.2 最小化的 jQuery 库,网址为ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js。您的代码现在应该类似于以下代码块:

<!DOCTYPE html><html lang="en"><head><script src="img/ jquery.min.js"></script> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Local Storage: Storywriter</title>

接下来,我们将添加 CSS 样式来设置文章标签的background-color和文本color,以及font-family

<style> article{background-color: #9F6;color:#333; font-family:Verdana, Geneva, sans-serif} p{} </style>

关闭head标签并为bodyheader元素创建开放标签。添加一个h1标签来显示页面标题为Storywriter,然后关闭header标签。

</head><body> <header> <h1>Storywriter</h1> </header>

sectionarticle元素创建开放标签。将article元素的 id 设置为“mypage”,并将contenteditable属性设置为“true”。

<section><article id="mypage" contenteditable="true">

接下来,创建一个包含占位文本type something的段落标签,然后关闭段落、articlesection标签。在两个em标签之间添加描述性的指令文本。您刚刚输入的内容应该如下所示的代码:

<p>type something</p> </article> </section><em>And then what happened? I'll remember next time you open this browser. </em>

创建一个script标签,然后通过键入$(function(){声明 jQuery 函数。

使用参数字符串“mypage”调用document.getElementById方法,将其分配给变量'edit'。

接下来,我们需要添加一个由“edit”元素的模糊事件触发的事件处理程序。键入$(edit).blur(function(){,然后键入localStorage.setItem('storyData", this.innerHTML);});以完成函数。

现在,由于本地存储可以使用setItem存储字符串,我们可以使用getItem通过键入if ( localStorage.getItem('storyData') ) { edit.innerHTML = localStorage.getItem('storyData'); } })将存储的字符串内容推送回页面。

脚本代码块现在应该如下所示:

<script>$(function() { var edit = document.getElementById('mypage'); $(edit).blur(function() { localStorage.setItem('storyData', this.innerHTML); }); if ( localStorage.getItem('storyData') ) { edit.innerHTML = localStorage.getItem('storyData'); } });</script>

关闭 body 和 HTML 标签,并保存文件。在浏览器窗口中打开它。现在,您应该能够开始输入自己的故事,并在页面上看到输入的文本,即使您关闭浏览器,稍后再次打开它。它应该看起来类似于以下的屏幕截图:

如何做...

它是如何工作的...

当我们将article标签的contenteditable属性设置为true时,我们告诉浏览器允许用户输入文本。大多数 HTML5 元素都可以声明contenteditable属性,然后将其设置为truefalse。然后,我们使用document.getElementById使用 IDmypage捕获输入的内容。getElementById jQuery 方法会在其参数中搜索特定 ID 名称的文档。然后,我们在blur事件上添加了一个事件处理程序,以使输入的文本看起来更加平滑。同时,我们还使用本地存储方法setItem和变量storyData存储文本。最后,我们使用getItem本地存储方法来检查storyData是否存在,如果存在,则将其加载到可编辑的 HTML 元素中,使用edit.innerHTMLgetItem

另请参阅

本书的前几章介绍了 HTML5 元素和 PACKT jQuery 书籍。

使用parseInt将本地存储的字符串转换为数字

在这个示例中,我们将从本地存储中获取一个字符串值,并将其转换为整数,以便我们可以使用parseInt进行数学运算。

准备工作

我们将使用 Modernizr (www.modernizr.com)来检测本地存储是否可用,将其托管在名为"js"的子文件夹中。您还需要至少一个最近更新的浏览器。

如何做...

按照下面的代码块创建一个新的 html 页面的开始,直到标题标签为止:

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"> <title>Using numbers with local storage</title>

接下来,添加样式来指定h1h2标签的字体族、文本颜色,以及h2标签的背景颜色和高度。

<style>body{font-family:Verdana, Geneva, sans-serif;} h1{color:#333; }h2{color:#C30;background-color:#6CF; height:30px;}</style>

添加一个由 Google 托管的 IE HTML5 shiv,并添加一个指向本地 Modernizr JavaScript 文件的链接:

<!--[if IE]><script src="img/html5.js"></script> <![endif]--><script type="text/javascript" src="img/ modernizr-1.7.min.js"></script>

使用 Modernizr 脚本来检查浏览器是否支持本地存储:

<script>if (Modernizr.localstorage) {
// window.localStorage is available!}
else {// the browser has no native support for HTML5 storage document.getElementByID('yayanswer').innerHTML = "Local Storage is not supported by your browser. Maybe it's time for an update?";}

创建一个名为storemyradius()的函数,声明一个名为myradiusToSave的变量,并将其赋值为document.getElementById('myradius').value;以便在访问者点击保存时将输入的数值传递到文本字段中。

function storemyradius() {var myradiusToSave = document.getElementById('myradius').value;

添加一个if语句来检查myradiusToSave是否为 null。在此之下,创建一个本地存储setItem方法,键为"myradius",值为"myradiusToSave"。在if语句的闭合括号和storemyradius函数的闭合括号之前,放置一个对displaymyradius()的函数调用,如下面的代码块所示:

if (myradiusToSave != null) { localStorage.setItem('myradius', myradiusToSave);displaymyradius();}}

创建一个名为displaymyradius的函数,不接受任何参数,然后添加一个名为myradius的变量。将其赋值为包含一个本地存储getItem方法的 JavaScript 函数parseInt,参数为"myradius",基数为 10。到目前为止,函数应该如下面的代码块所示:

function displaymyradius() { var myradius = parseInt(localStorage.getItem('myradius'),10);

在同一个函数中,创建一个if语句,用于检查myradius变量是否不为 null 且大于零。创建变量diameter,并将其值赋为2乘以myradius的结果。使用document.getElementByIdinnerHTML来显示直径变量的值,以及在 HTML 页面的h2标签之间显示消息"The diameter of the circle is"。

if (myradius != null && myradius > 0) {var diameter = 2 * myradius;document.getElementById('yayanswer').innerHTML = "The diameter of the circle is: " + diameter + "!";}}

创建一个名为clearmyradius的函数,不接受任何参数,然后创建一个if语句,检查本地存储getItem方法是否包含一个不为 null 的值。在if语句的括号之间,放置本地存储removeItem方法,参数为字符串"myradius",以及对本地存储clear方法的调用。关闭脚本和头标签。我们刚刚写的代码应该看起来类似于以下的代码块:

function clearmyradius() {if (localStorage.getItem('myradius') != null) {localStorage.removeItem('myradius'); window.localStorage.clear();}}</script></head>

创建开放的 body、section、hgrouph1标签,在关闭的h1标签之前输入"localStorage Number Conversion"。创建一个h2标签,并为其分配一个 ID 为"yayanswer"。关闭hgroup标签,然后为myradius文本字段添加一个标签标签。输入标签文本为"输入圆的半径:"。创建一个带有 ID 为"myradius"maxlength"4"的输入表单字段标签。创建两个输入按钮,一个带有onclick值调用函数storemyradius();另一个带有onclick值调用函数clearmyradius()。关闭 section、body 和 html 标签,并保存页面。最终的代码块应该如下所示:

<body ><section><hgroup><h1>localStorage Number Conversion</h1> <h2 id="yayanswer"></h2></hgroup><label for="myradius">Enter the radius of the circle:</label><input id="myradius" maxlength="4" /> <input onclick="storemyradius();" name="save" type="button" value="save"><input onclick="clearmyradius();" name="clear" type="button" value="clear"></section></body></html>

在 Google Chrome 浏览器窗口中,完成的 HTML 页面应该如下所示:

如何做...

它是如何工作的...

在 HTML 页面中显示的文本字段接受访问者输入并将其作为值传递给storemyradius()函数。我们声明了一个名为myradiusToSave的变量,并将其分配为document.getElementById('myradius').value;它存储了myradius中包含的值。然后,它将传递到本地存储的setItem方法中。在将值传递到本地存储之前,我们需要验证myradiusToSave实际上包含的值不是 null。如果不是 null,则有数据保存到本地存储。然后,该值作为键/值对的一部分保存到本地存储中,使用setItem。为了将myradius值作为数字使用,我们需要将其从字符串转换为整数。这是通过调用parseInt JavaScript 函数来完成的。接下来,我们创建了一个名为diameter的变量,用于保存我们的直径公式的结果,即半径值的两倍。最后,我们使用getElementbyId方法将结果返回到屏幕上。

另一个页面上的选项是清除本地存储变量的值。虽然我们本可以使用removeItem方法,但同时使用 clear 方法可以确保没有其他潜在的本地存储变量。通过打开 Google 开发者工具刷新页面,可以验证本地存储区域为空。

还有更多...

当前,默认情况下localStorage将所有数据存储为字符串。我们刚刚练习了将localStorage变量转换为整数,但它们也可以转换为数组等对象。

在 localStorage 中存储和检索数组

在许多情况下,您会希望使用localStorage与数组一起保存游戏中的进度或保留用户数据或消息。您可以使用 Douglas Crockford 的 JSON 库来简化数组的存储和检索。访问github.com/douglascrockford/JSON-js下载代码并了解更多关于 JSON 的信息。

创建一个新的 HTML5 页面,并在两个页脚标签之间添加脚本标签。声明一个名为"horsedef"的新变量数组,并将其分配为以下键/值对,如下所示:

var horsedef = {"species":"equine","legs":4,"ears":2, "purposes":{"front":"neigh","behind":"flick"}};

现在,在本地存储中设置一个名为"describehorse"的新项目,同时使用JSON将我们的数组horsedef转换为字符串,如下所示:

window.localStorage.setItem('describehorse', JSON.stringify(horsedef));

使用 JSON 解析从本地存储中检索值:

console.log( alert('A horse is a horse of course! ' + JSON.parse (localStorage.getItem('describehorse')) ); // => Object { species="equine", more...} </script>

保存页面,打开浏览器窗口。您应该看到一个警报框,显示传递给describehorsehorsedef数组中的键/值对,如下面的屏幕截图所示:

在 localStorage 中存储和检索数组

提示

在使用 JSON 时要注意跨站点回调。通常最好从自己的服务器下载并使用文件。始终直接从源下载 JSON 的副本。不要上当受骗,比如 JSONP。

创建 Web SQL 数据库

在这个示例中,我们将创建一个 Web SQL 数据库,并赋予它定义版本、名称、大小和描述的属性。

准备工作

您需要使用支持 Web SQL 数据库的当前浏览器。

如何操作...

创建一个新的 HTML5 文件,并在两个页脚标签之间放置打开和关闭脚本标签。声明一个名为db的变量,然后将openDatabase()赋给它。给openDatabase以下参数:'mymotodb', '1.0', 'Motocross Rider List DB', 2 * 1024 * 1024,然后关闭声明。代码应该看起来像以下代码片段:

<script>var db = openDatabase('mymotodb', '1.0', 'Motocross Rider List DB', 2 * 1024 * 1024);</script>

保存文件。

它是如何工作的...

所有 Web SQL 数据库都使用openDatabase方法来为数据库分配值。第一个参数“mymotodb”是数据库的名称。下一个必需的参数是版本号。这里的数字必须与用户尝试使用 Web SQL 数据库时匹配。接下来,我们定义了数据库的描述,然后是估计的大小。一旦为请求的openDatabase方法定义了所有参数,数据库就被创建了,并且进行了第一次(不可见的)事务——数据库本身的创建。

还有更多...

诸如 Web SQL 数据库之类的规范的浏览器实现一直非常不可预测,同样,Web 开发社区对这些规范本身的支持也是如此。

Web SQL 可能会被 SQLite 取代

Web SQL 数据库规范本身已不再由 W3C 维护,但在大多数浏览器中运行得相当好。可能在接下来的一年左右,足够多的主要利益相关者将会就如何实现不同的客户端数据库解决方案达成一致,比如 SQLite,但这样的事情很难预测。关注www.w3.org/TR/webdatabase/上的规范,了解使用客户端数据库的当前选项的更新。

使用 Web SQL 数据库

在这个步骤中,我们将使用前面步骤中创建的数据库,并向其中添加表和数据,然后在 HTML 页面上显示结果。

准备工作

您需要一个当前的浏览器和一个带有基本标签的 HTML5 页面,用于头部区域和主体区域。

如何操作...

在一个基本的 HTML5 页面上,添加一个h1标签来显示页面标题,然后创建一个 ID 为“status”的div标签来保存我们的结果,如下面的代码块所示:

<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Using WEB SQL Databases</title></head><body><article><section><header><h1>Today's Riders</h1></header><div id="status" name="status"></div> </section></article><footer>

如果尚未创建数据库,请按照前面的步骤开始脚本以创建数据库。创建一个名为 info 的新变量,然后创建一个包含接受参数的函数的新事务。使用传递的参数,创建一个名为 RIDERS 的带有唯一 ID 和名为ridername的行的表。代码应该类似于以下代码块:

var info;db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS RIDERS (id unique, ridername)');

将数据添加到表行中,使用唯一 ID 的数字和每个名称的文本字符串:

tx.executeSql('INSERT INTO RIDERS (id, ridername) VALUES (1, "Joe Fly")'); tx.executeSql('INSERT INTO RIDERS (id, ridername) VALUES (2, "Gira Ettolofal")'); });

执行查询以从数据库中提取数据:

db.transaction(function (tx) { tx.executeSql('SELECT * FROM RIDERS', [], function (tx, results) {

创建一个新变量和for循环,循环遍历结果并将其打印到屏幕上:

var len = results.rows.length, i; for (i = 0; i < len; i++){ info = "<p><b>" + results.rows.item(i).ridername + "</b></p>"; document.querySelector('#status').innerHTML += info; } }, null);});

关闭脚本和 HTML 页面。

</script></footer></body></html>

它是如何工作的...

当我们在浏览器中打开我们刚创建的页面时,我们将看到我们使用数据库来显示的信息。这是因为查询和循环一起查看数据库并显示适当的信息。

它是如何工作的...

还有更多...

在 HTML5 中,安全性和数据库事务可能执行不佳。在生产环境中,应该注意保护接受 SQL 查询的任何页面。

在单独的文件中保存脚本代码

为了简化本步骤,我们没有将 SQL 查询代码和 JavaScript 保存在单独的文件中。可以通过将代码保存在子文件夹中,如../js/myCode.js来完成。谨慎使用 Web SQL、Indexed DB 或任何其他类型的基于浏览器的查询 API 来获取安全信息。

在生产服务器上防范 SQL 注入

每当有可编辑字段时,都可能会有一些机器人尝试执行 SQL 注入攻击。可以通过在事务请求中使用“?”来采取基本预防措施。以下代码显示了一个例子。

store.db.transaction(function(tx) { tx.executeSql( "insert into bmxtricks " + "(time, latitude, longitude, trick) values (?,?,?,?);", [bmxtricks.time, bmxtricks.latitude, bmxtricks.longitude, bmxtricks.trick], handler, store.onError );});

另请参阅

SQL 的 Packt 图书,任何覆盖客户端数据库的 Packt HTML5 图书。

为离线存储创建缓存清单

在这个示例中,我们将创建一个缓存清单文件,以便我们能够离线存储 HTML5 页面,并仍然查看页面上显示的图像和视频。

准备工作

您将需要一个 HTML5 页面,例如本示例的代码文件中提供的页面,并且可以上传文件到服务器,然后在计算机、智能手机或其他具有浏览器的网络设备上查看它们。

如何做...

首先,我们将创建缓存清单文件。这应该在一个简单的文本编辑器中创建。它应该包含用户在离线时需要访问的所有文件和支持代码。首先列出的是当前文件类型(CACHE MANIFEST)。清单的版本号也应包括在内。请注意,我们在以下代码块中添加了所有我们希望用户在离线时访问的文件的路径:

CACHE MANIFEST
# version 0.1
itsallgooed.html
css/Brian Kent Font License.txt
css/exact-css-from-tutorial.css
css/font-stylesheet.css
css/plasdrip-webfont.eot
css/plasdrip-webfont.svg
css/plasdrip-webfont.ttf
css/plasdrip-webfont.woff
css/plasdrpe-webfont.eot
css/plasdrpe-webfont.svg
css/plasdrpe-webfont.ttf
css/plasdrpe-webfont.woff
css/style.css
images/gooed-science-logo.jpg
images/promo-bg.jpg
images/gakposter.png
movie/GakHowTo.mp4
movie/GakHowTo.ogv
movie/GakHowTo.webm

index.html页面的DOCTYPE标签和head标签之间添加一个 manifest 属性,如下所示:

<!DOCTYPE html> <html lang="en" manifest="gooed.manifest"> <head>

最后,创建一个.htaccess文件来创建正确的 MIME 类型:

AddType text/cache-manifest .manifest

页面应该显示类似于以下内容:

如何做...

它是如何工作的...

创建缓存清单为浏览器提供了一个加载离线页面时使用的清单。虽然离线存储页面的想法是它不需要频繁更新,但使用版本号允许作者在用户下次连接到互联网时推送更新。

并非所有浏览器或系统都能正确解释清单文件类型,因此包括一个.htaccess文件可以确保缓存清单被正确识别。

您可以排除您认为不重要的文件,以减小离线页面的大小并减少加载时间。

使用地理位置和 geo.js 显示当前位置

在这个示例中,我们将使用地理位置规范和geo.js来显示地图上活动用户的当前位置,并显示他们当前的纬度和经度。

准备工作

访问code.google.com/p/geo-location-javascript/下载最新版本的geo.js,或者从 wiki (http://code.google.com/p/geo-location-javascript/wiki/JavaScriptAPI)获取链接 URL 以直接在线链接到它。

如何做...

首先,我们将创建 HTML5 开头页面标签:。

然后,在 meta 标签中,我们将把 name 属性设置为“viewport”,并为 content 属性定义以下值:width = device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;

现在,声明一个带有 src 属性的脚本标签:code.google.com/apis/gears/gears_init.js

然后,调用geo.js脚本:src="img/geo.js"

到目前为止,代码块应该如下所示:

<html><head><meta name = "viewport" content = "width = device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"> <script src="img/gears_init.js" type="text/javascript" charset="utf-8"></script><script src="img/geo.js" type="text/javascript" charset="utf-8"></script>

为 Google Maps API 添加一个脚本标签:<script type="text/javascript" src="img/js?sensor=false"></script>

现在,我们将创建一个初始化地图的函数,命名为initialize_map(),然后创建一个名为myOptions的数组来存储地图属性。这些属性基于 Google Maps API。它们应该类似于以下代码块:

<script>function initialize_map(){ var myOptions = { zoom: 4, mapTypeControl: true, mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}, navigationControl: true, navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}, mapTypeId: google.maps.MapTypeId.ROADMAP }

使用google.maps.Map()方法向页面添加一个名为 map 的新地图,该方法将document.getElementById元素作为参数,该元素又传递了 id“map_canvas”。google.maps.Map接受的另一个方法是myOptions

map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);}

创建initialize()函数,并添加一个if语句来检查geo_position_js.init()函数是否激活。使用document.getElementByIdinnerHTML为 id 为“current”的 div 输入一个新状态。状态文本为“接收中…”。

function initialize(){ if(geo_position_js.init()){ document.getElementById('current').innerHTML="Receiving...";

添加帮助消息文本,以显示如果我们无法获取位置或者由于某种原因浏览器不支持获取当前位置,如下所示的代码块:

geo_position_js.getCurrentPosition(show_position,function(){document. getElementById('current').innerHTML="Couldn't get location"}, {enableHighAccuracy:true}); } else{document.getElementById('current').innerHTML="Functionality not available"; }}
function show_position(p){ document.getElementById('current').innerHTML= "latitude="+p.coords.latitude.toFixed(2)+" longitude="+p.coords.longitude.toFixed(2); var pos=new google.maps.LatLng( p.coords.latitude,p.coords.longitude); map.setCenter(pos); map.setZoom(14);

创建一个名为infowindow的新变量,用于显示google.maps InfoWindow,即在点击标记时显示的气泡。给它一个文本字符串“yes”来显示。创建一个新的标记,与用户当前位置相关联,并为标记添加标题文本,以便在鼠标悬停时显示。添加一个事件监听器来检测标记何时被点击。

var infowindow = new google.maps.InfoWindow({ content: "<strong>yes</strong>"}); var marker = new google.maps.Marker({ position: pos, map: map, title:"Here I am!" }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker);});}</script >

样式化页面以控制字体系列、填充和标题和当前 div 的外观。

<style>body {font-family: Helvetica;font-size:11pt; padding:0px;margin:0px} #title {background-color:#0C3;padding:5px;} #current {font-size:10pt;padding:5px;}</style></head>

在 body 标签中创建一个onLoad命令,初始化initialize_map()initialize()函数。创建一个新的div来显示页面标题,以及一个 id 为“current”的第二个div来显示位置获取过程的当前状态。最后,创建一个 id 为map_canvasdiv来包含地图一旦显示,并使用内联样式设置div的宽度和高度。关闭标签并保存页面。

<body onLoad="initialize_map();initialize()"><div id="title">Where am I now?</div> <div id="current">Initializing...</div> <div id="map_canvas" style="width:320px; height:350px"></div></body></html>

在浏览器窗口中打开页面,您应该会看到类似以下截图的结果:

操作步骤...

工作原理...

使用geo.js简化了在多个设备上使用地理定位的过程。它提供了准备好的错误消息,并遵循 W3C 的实现标准,以及“回退”到诸如 Google Gears 之类的工具的能力。首先,我们需要创建一个包含地图显示和处理选项数组的变量的脚本,实例化一个新的地图对象,并绘制一个标记以将用户的当前位置固定到屏幕上。在标记上悬停会显示一个带有标题文本的气泡窗口。这个文本也可以包含一个链接,用于拉取和显示驾驶方向、评论或笔记。当页面加载时,地图选项创建函数map_initialize()和主要的触发函数initialize()被调用。在使用geo.js的帮助下确定用户的当前位置并绘制地图时,会显示一个临时状态消息。

posted @ 2024-05-24 11:09  绝不原创的飞龙  阅读(2)  评论(0编辑  收藏  举报