HTML5-多媒体开发秘籍-二-

63 阅读1小时+

HTML5 多媒体开发秘籍(二)

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

译者:飞龙

协议:CC BY-NC-SA 4.0

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

在本章中,我们将涵盖:

  • 测试浏览器支持

  • 添加跳转导航

  • 添加元标记

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

  • 提供替代站点视图

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

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

  • 使用 WAI-ARIA

介绍

"良好的可访问性设计就是良好的网页设计。"

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

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

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

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

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

现在,让我们开始吧!

测试浏览器支持

让我们从使用由 Faruk Ates 和 Paul Irish 开发的开源 Modernizr 项目开始。根据该网站,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 检测浏览器支持的项目。然后它将添加类和 JavaScript API 来检测对某些功能的支持。如果给定浏览器不支持这些功能,Modernizr 就不会添加它们。

  • @font-face

  • 画布

  • 画布文本

  • HTML5 音频

  • HTML5 视频

  • rgba()

  • hsla()

  • 边框图像:

  • 边框半径:

  • 盒阴影:

  • 文本阴影:

  • 不透明度:

  • 多重背景

  • 灵活的盒模型

  • CSS 动画

  • CSS 列

  • CSS 渐变

  • CSS 反射

  • CSS 2D 变换

  • CSS 3D 变换

  • CSS 过渡

  • 地理位置 API

  • localStorage

  • sessionStorage

  • SVG

  • SMIL

  • SVG 裁剪

  • 内联 SVG

  • 拖放

  • 哈希变化

  • X 窗口消息

  • 历史管理

  • 应用缓存

  • 触摸事件

  • Web 套接字

  • Web Workers

  • Web SQL 数据库

  • WebGL

  • IndexedDB

  • 输入类型

  • 输入属性

还有更多...

在 Modernizr 2 Beta 中新增了自定义 JavaScript 下载的功能。现在,如果你不关心某个功能(比如拖放),你可以取消选择它,Modernizr 就不会检查它。详细信息请访问:modernizr.github.com/Modernizr/2.0-beta

展望未来

来自网站:

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

Modernizr 真正做的是

Modernizr 不做的是在浏览器中添加或启用本来不存在的功能。例如,如果您的浏览器不支持输入属性,Modernizr 不会自动为您的浏览器添加该功能。这是不可能的。它只是让您作为开发人员知道您可以使用什么。

出于正确的原因而这样做

有些 Web 开发人员使用 Modernizr,因为他们在某篇文章中读到他们应该使用它。这没问题,但你比他们聪明。您知道在浏览器中检测这些功能如何更好地告知您如何为不支持某些属性的浏览器提供可访问的体验。聪明又英俊的你!

参见

进一步阅读,作者 Gil Fink 为微软撰写了简单而简洁的"使用 Modernizr 检测 HTML5 功能"文章,网址为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元素来实现跳过导航的功能,而不是通过显式链接。更少的标记意味着更好的效果!

Web 标准项目网站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">,用于英语和法语。请注意,由于我们引用了多个值,因此在值周围使用引号。

你在说什么?

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

一切都归结为 SEO

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

我做到了吗?

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

另请参阅

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

在标签中为屏幕阅读器提供语义描述

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

准备好了

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

如何做...

新的 HTML5 标签包括:

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

它是如何工作的...

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

  • 页脚

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

还有更多...

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

始终改进

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

良好 SEO 的语义

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

格雷格终于学会了

语义网页开发对其他开发者也有好处。如果你用

标签编码一个区域,那么你团队中的另一个开发者或将来在你的项目上工作的开发者将立即理解你的意图。作者曾经与一个开发者合作,他用毫无意义的命名,比如<div id="banana">,用于与香蕉无关的东西。那个开发者认为这是一种通过成为唯一知道某些标签含义的方式来确保工作。不幸的是,当他几年后编辑他之前创建的东西时,这种方法对他来说变得痛苦,他无法记住它的含义。教训是什么?不要惹自己以后生气!

另请参阅

caniuse.com提供 HTML5、CSS3、SVG 等在台式机和移动浏览器中的兼容性表。该网站是了解哪些新标签可以被支持的宝贵帮助。它不断更新,不仅值得收藏,而且值得一遍又一遍地参考。

提供备用站点视图

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

准备好了

马科特在 2010 年 5 月 25 日的《A List Apart》杂志上发表了这篇文章:alistapart.com/articles/responsive-web-design。阅读这篇文章将让你提前了解本节的其余内容。

如何做...

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

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

如何做...

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

如何做...

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

如何做...

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

如何做...

它是如何工作的...

通过在样式表中使用灵活网格以及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 像素呢?简单的除法给我们留下了这个: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 是一个了不起的 30 天逐步资源,可以更多地了解 508 部分和可访问性标准。作者 Mark Pilgrim(也是diveintohtml5.org的* Dive Into HTML5*作者)提供了易于理解的技巧,可以按人员,残疾,设计原则,Web 浏览器和发布工具分类。该网站已经存在几年了,但由于多年来可访问性标准并没有发生太大变化,因此仍然是一个宝贵的免费资源。

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

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

准备就绪

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

  • <h1>

  • <h2>

  • <h3>

  • <h4>

  • <h5>

  • <h6>

  • <p>

  • <ul>

  • <ol>

  • <li>

  • <dl>

  • <dt>

  • <dd>

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

  • <article>

  • <aside>

  • <audio>

  • <canvas>

  • <datalist>

  • <details>

  • <figcaption>

  • <figure>

  • <footer>

  • <header>

  • <hgroup>

  • <mark>

  • <meter>

  • <nav>

  • <output>

  • <progress>

  • <section>

  • <summary>

  • <time>

  • <video>

这些是否会按我们的意图传达给用户?如果是,那太棒了。但如果不是,用户会得到什么信息?这是否有意义?当然,我们会同意我们最不想做的事情就是通过我们的新标签提供更少的含义。即使盲人也能看到这将是一个史诗般的失败。

如何做...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • <datalist> - 仅在 Opera 中可通过键盘访问。

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

  • <time> - 仅在 Opera 中存在键盘访问的问题。

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

它是如何工作的...

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

另请参阅

艾米莉·刘易斯对 HTML 和 CSS 以及可用性、语义和可访问性都感到兴奋。她是我们需要更多的热情倡导者,以使前端网页开发世界蓬勃发展。请查看她出色的“Web Accessibility and WAI-ARIA Primer”,了解如何开始思考可访问性的未来,网址为msdn.microsoft.com/en-us/scriptjunkie/ff743762.aspx

使用 WAI-ARIA

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

准备就绪

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

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

准备就绪

如何做到...

还记得我们在 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

吉尔伯特森后来写了一篇关于使用 ARIA 角色为网站设计样式的绝妙资源:webmonkey.com/2011/01/styling-webpages-with-arias-landmark-roles

第五章:学会爱上表单

在本章中,我们将涵盖:

  • 显示占位符文本

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

  • 使用 HTML5 和 CSS3 样式化表单

  • 使用电子邮件输入类型

  • 使用 URL 输入类型添加 URL

  • 使用数字标签

  • 使用范围标签

  • 创建搜索字段

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

介绍

“我们已经遇到了敌人,他就是我们自己。”-波戈

无聊。乏味。无聊。为什么当在线交互表单呈现给网络用户时,他们的眼睛会变得无神和心智麻木?这位作者认为问题至少部分在于安排表单字段的信息架构师,以及在较小程度上编码它的前端开发人员。

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

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

在本章中,我们将看一些 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 在allycreative.net/contact有效地使用了他们联系表单中的autofocus能力。

如何做...

它是如何工作的...

他们是这样做的:

<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>

通过将autofocus属性应用于联系人姓名的表单字段,并添加适当的样式来更改背景颜色,Ally Creative 的开发人员创建了一个流畅、互动的表单,用户可以轻松完成。

还有更多...

新的 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 视频、Google 地图等而成为有史以来最受关注的 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">,用户可以在不必看到具体音量数字的情况下直观地增加或减少音量。

使用时要小心

不幸的是,没有非 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,占位符文本不再使用值标记。对于我们开发人员以及搜索引擎和辅助技术来说更有意义。

它是如何工作的...

指定<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上的 Never Mind The Bullets 是一个交互式在线游戏,专门用于演示 Microsoft 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 开发丰富的媒体应用程序

在本章中,我们将涵盖:

  • 设置“画布”环境

  • 了解 2D 渲染上下文

  • 动态处理形状

  • 使用“画布”为图像绘制边框

  • 圆角

  • 创建交互式可视化

  • 弹跳球

  • 创建备用内容

介绍

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

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

注意

请注意,随着时间的推移,实验性的新“画布”元素规范可能会发生变化。在出版时,可以将这组配方视为可能性的一个快照。

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

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

提示

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

支持“画布”的浏览器包括:

介绍

提示

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

在本章中,我们将看一些设置“画布”环境、了解 2D 渲染上下文、动态处理形状、使用“画布”为图像绘制边框、圆角、创建交互式可视化、弹跳球和创建备用内容的实际示例。

现在,让我们开始吧!

设置画布环境

创建新的“画布”元素很容易。

如何做...

看看这有多简单:

<!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 来控制高度和宽度,但要抵制这种诱惑。因为新的“画布”元素包含一个 2D 渲染上下文,这种方法可能会导致不可预测的行为。

还有更多...

接下来,我们将调用新的“画布”元素 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>

他很聪明

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

我在说什么?

苹果早在多年前就在 OSX Dashboard 中首次引入了新的“画布”元素。后来它在 Safari 和 Chrome 等网络浏览器中实现,其他浏览器也纷纷效仿。从那时起,它已成为 HTML5 规范的正式部分。

的下一步是什么?

现在,我们只是初步了解了新的“画布”元素可以做什么。现在和将来,我们将使用它来创建动画、图表、图表、绘图应用程序、图形和用户界面。你会梦想出什么?

另请参阅

开发者 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 轴。数值向下增加。

尊重我的权威!

万维网联盟的 HTML5 Canvas 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 为那些刚接触新的canvas元素的人,一直到最有经验的专家提供了一个提升技能的出版物。听起来像你认识的人吗?在这里查看:friendsofed.com/book.html?isbn=1430232919.

使用 canvas 为图像绘制边框

让我们更仔细地看看使用新的canvas元素绘制图像边框的超简单方法。

如何做...

首先,我们将从基本的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, 20, 100, 100);
});
</script>
</head>
<body>
<canvas id="FirstCanvas" width="800" height="600">
<!-- Fallback code goes here -->
</canvas>
</body>
</html>

如何做...

它是如何工作的...

这一行 JavaScript 告诉浏览器创建一个矩形,从新的canvas元素的左边 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是一个专门为新的canvas元素设计的图形库。它允许您轻松创建各种图表类型:条形图、双极图、圆环图、漏斗图、甘特图、水平条形图、LED 显示、折线图、仪表、里程表、饼图、进度条、玫瑰图、散点图和传统的雷达图,使用 HTML5、canvas和 JavaScript。

圆角

到目前为止,我们已经使用方形或矩形形状创建了图像和边框。接下来,我们将看看如何使用新的canvas元素通过 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 选择了一种稍微不同的调用 2dcanvas渲染上下文的方法,但他的方法也完全有效。看看:

$(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对于新的canvas元素来说就像border-radius对于 CSS 一样。它们都实现了相同的功能 - 但是通过非常不同的方式。

IE 怎么样?

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

我们正在奠定基础

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

另请参阅

Mozilla 的“HTML5 的人”视频系列展示了许多 HTML5 运动的领军人物。约翰·福利奥特是 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.

创建交互式可视化

如何做...

提示

在按照本文进行操作时,查看源代码将非常有帮助:查看源代码: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 在这种情况下没有在新的canvas元素中使用回退内容。这是一个你需要仔细权衡的方法,因为那些使用旧浏览器或辅助技术的人将什么也看不到。Carbon Five 在这个内部项目中得以成功。你能吗?

接受他的提议。

blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1上写到这个项目时,Carbon Five 的开发者 Alex Cruikshank 甚至表示愿意为前五位以合理格式提供数据的人创建可视化地图。截至出版日期,尚不清楚是否有人接受了他的提议。

另请参阅

Jacob Seidelin 用他的新 canvas 元素可视化了乐队 Radiohead 的歌曲“Idioteque”,这首歌收录在专辑“Kid A”中:nihilogic.dk/labs/canvas_music_visualization。Jacob 正在挑战canvas元素和 JavaScript 的极限,这就是为什么我们认为他很棒!

弹跳球

我们已经看过如何使用新的canvas元素绘制形状,接下来我们将把注意力转向使这些形状移动。作者 Vinci Rufus 向我们展示了如何。

如何做...

我们将从通常的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。在这里,Vinci 选择了一个稍微不同的方法来调用 2Dcanvas渲染上下文,但他的方法也完全有效。看看:

<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>

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

<!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>

并渲染这个蓝色的球:

如何做...

它是如何工作的...

到目前为止,Vinci 的代码非常简单。我们看到他如何调用 2Dcanvas渲染上下文。接下来他设置填充的颜色:

context.fillStyle="#0000ff";

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

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

但现在我们只有一个蓝色的球坐在那里。接下来,Vinci 向我们展示了如何使用变量和一个名为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>

还有更多...

正如你所看到的,球在运动,但只是在canvas的边缘画了一条直线。Vinci 解释了原因:

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

重新开始

Vinci 向我们展示了一种方法,可以擦除旧的圆圈,因为新的canvas元素绘制了每一个新的圆圈:

<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>

现在,球似乎向右下方的canvas边界外掉落。

不要把我困住

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

<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>

现在球应该在canvas的四个边上不断地弹跳。

不要把我困住

还有一个要学习的

正如 Vinci 在他引人入胜的教程中提醒我们:sixrevisions.com/html/bouncing-a-ball-around-with-html5-and-javascript,弹跳球起初可能看起来很简单,但实际上这是一个关键的技术,需要理解才能开发几乎任何新 HTML5canvas元素的游戏。

另请参阅

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

创建备用内容

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

如果有人在使用旧版浏览器并且无法识别您的编码天赋时,您的出色的新“画布”应用会发生什么?或者当有人使用辅助技术时会发生什么?让我们来看看。

如何做...

如果由于某种原因,用户的浏览器不支持新的“画布”元素,作为开发人员,我们需要给他们提供有价值的替代内容。

在这里我们可以使用图像作为备用内容。

<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标签至少会给他们一个有价值的文本标签,代表他们所错过的内容。新的“画布”元素的备用内容是一个类似的概念,但它能够做得更多,而不仅仅是一个alt标签。

还有更多...

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

谢谢,Mozilla

“如果需要备用内容,则必须使用一些 CSS 技巧来掩盖 Safari 中的备用内容(应该只呈现‘画布’),并且还要掩盖 IE 中的 CSS 技巧本身(应该呈现备用内容)。”- Mozilla.org

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

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

我们准备好使用了吗?

许多开发人员认为新的“画布”元素的可访问性是新 HTML5 规范中的最后一个难点。由于几乎没有有意义的备用功能,这个新元素似乎还没有准备好投入使用。