65.9K
CodeProject 正在变化。 阅读更多。
Home

HTML5 实践:通过新的输入类型改变 Web 表单的面貌

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2011 年 12 月 9 日

CPOL

20分钟阅读

viewsIcon

42673

HTML5 实践的章节摘录。

image002.jpg HTML5 实战

作者:Robert Crowther, Joe Lennon, 和 Ash Blue

HTML 的早期版本提供了十种不同的输入类型供您使用。这些类型的麻烦在于?它们缺乏输入数字、日期、颜色、电子邮件地址和 URL 等数据类型的特性。本文基于《HTML5 实战》第二章,将向您介绍 HTML5 定义的 13 种解决此问题的新类型——而且所有这些都无需 JavaScript。

您可能还对以下内容感兴趣…

在 HTML 中,<input> 元素用于在表单中添加文本框、复选框和单选按钮等字段。type 属性用于指示浏览器应向用户显示哪种类型的表单控件。在早期版本的 HTML 中,可以使用十种不同的类型,如表 1 所示。

表 1 早期 HTML 中有效的输入类型值

Button checkbox 文件 hidden Image
密码 radio reset submit 文本

表 1 中这些类型的问题在于,它们不提供输入数字、日期、颜色、电子邮件地址和 URL 等数据类型的任何功能。当然,您也可以只使用标准的文本输入,但这需要您使用 JavaScript 在客户端验证数据类型。如果禁用了 JavaScript,则此验证将不会执行。为了解决这个问题,HTML5 定义了十三种新的输入类型,如表 2 所示。

表 2 HTML5 中引入的新输入类型值

Color 日期 datetime 本地日期时间 电子邮件
数字 range search Tel
时间 url    

在本文中,您将了解这些新的输入类型的每一个,它们在已实现它们的浏览器中的外观,以及它们相对于使用基本文本输入类型的优势。您还将它们用于一个示例注册表单。

email, url, and tel

在 Web 表单中,文本字段最常见的用途之一是要求用户输入他们的电子邮件地址。无论是在注册表单、联系表单、用户登录、订阅新闻通讯还是在博客文章中发表评论时,大多数 Web 表单都需要输入电子邮件地址。当然,为了被认为是有效的,所有电子邮件地址都必须符合一定的格式,并且在大多数情况下,开发人员会使用某种形式的 JavaScript 正则表达式测试来检查客户端电子邮件地址的有效性。问题在于,不同的人对什么是有效电子邮件地址有不同的看法,因此,开发人员在他们的验证例程中使用各种不同的模式。HTML5 通过将验证电子邮件地址的责任转移给浏览器本身来消除这个问题。

警告

您永远不应仅依赖客户端验证,因为恶意用户可以很容易地绕过它。您的应用程序应始终在后端提供稳健的服务器端验证,客户端验证仅用于增强用户体验(并减少发送到服务器的无效请求的数量)。

使用 email 输入类型非常简单(正如大多数新的 HTML5 输入类型一样)。它的工作方式与常规文本输入完全相同,但您将使用 type="email" 而不是 type="text"。

<input type="email"
name="email_address">

很简单,对吧?当您在兼容的浏览器中查看电子邮件输入字段时,它实际上看起来与常规 HTML 文本输入没有区别。事实上,如果您在任何浏览器中查看它,它只会显示为一个标准的文本框。新的输入类型的一个好处是,如果浏览器不识别它们,它将显示一个普通的文本输入字段,因此您可以安全地将这些新字段添加到您的应用程序中,而无需担心它们会在旧浏览器中造成混乱。

这时,您可能会想:“如果这个新输入类型看起来只是一个标准文本输入,那么它有什么用呢?” email 类型的真正强大之处在于,默认情况下,当表单提交时,兼容的浏览器会检查字段的值是否为有效的电子邮件地址。如果字段值无效,表单提交将被阻止,并会向用户显示错误消息,而且无需任何 JavaScript 代码即可实现。图 1 显示了在几种不同的 Web 浏览器中出现的此错误消息。

image003.jpg

图 1 Opera 11.50、Google Chrome 12 和 Mozilla Firefox 5.01 中的原生电子邮件地址验证

除了新的 email 输入类型之外,还有两个相似的新类型:url 和 tel。url 类型与 email 类型的工作方式完全相同,尽管显示不同的错误消息以表明用户输入了无效的 URL。以下代码是一个示例,展示了如何在 HTML5 中使用 url 类型。

<input type="url"
name="web_site_address">

tel 输入类型旨在允许用户输入电话号码。然而,与 email 和 url 不同的是,浏览器不会原生验证 tel 输入字段,因为电话号码没有单一的有效结构。一个网站可能要求用户输入一个完整的电话号码,包括国际拨号代码和区号;其他网站可能只需要区号。此外,不同的地区可能以不同的方式显示电话号码。您可以按如下方式使用 tel 输入类型。

<input type="tel" name="phone_number">

那么,如果 tel 输入类型不提供增强的验证功能,它与标准文本输入相比有什么优势呢?使用此输入类型的一个主要原因是,在智能手机等具有虚拟键盘的设备上,浏览器可能会根据用户使用的输入字段类型显示不同的键盘。这同样适用于 email 和 url 输入类型。例如,当您在 iOS 设备上输入 email 输入类型的值时,键盘上的空格键会变小,并且旁边会出现“@”和“.”符号按钮,以便更容易输入电子邮件地址。对于 url 字段,空格键将被完全移除,并被“.”、“/”和“.com”按钮取代。对于 tel 字段,标准键盘将完全被数字键盘取代,并且可以轻松访问电话号码中常用的符号,如“+”、“*”和“#”。您可以在图 2 中看到这些更改的示例。

image004.jpg

图 2 在 iPhone 上,针对不同的输入类型(从左到右:"text"、"email"、"url" 和 "tel")会显示不同的虚拟键盘

提示

您可能已经注意到,在代码示例中,我们使用不带结束斜杠的 <input> 元素(如 <input />)。此语法在 XHTML 中引入,在 HTML5 中不再是必需的。两种方法都有效,因此如果您偏爱 XML 风格的约定,请随时在您自己的应用程序中使用它。

number and range

在 HTML 4 和 XHTML 中,当您需要数字数据输入时,您被迫使用标准的文本输入元素并使用 JavaScript 验证数据。此外,如果您想为数字字段提供不同的用户界面,例如微调器或滑块,您必须依赖第三方 UI 框架。在 HTML5 中,有两种新的输入类型用于数字数据输入:number 和 range。这两个字段的标记和配套属性集几乎相同,但它们在浏览器渲染的 UI 小部件方面有所不同。对于 number 字段,您可以期望支持的浏览器显示一个微调器。例如,以下代码

<input type="number" name="mynum">

会生成一个如图 3 所示的微调器。

注意

Mozilla Firefox(至少包括 6.0.1 版本)不支持 number 输入类型或其任何属性。要添加对 HTML5 表单功能(如微调器小部件和数字验证)的支持,您可以使用 polyfill。

image005.jpg

图 3 Mac OS X 上的 Opera 为 number 输入字段显示的微调器小部件

range 输入也存储一个数字值,但它向用户显示一个滑块小部件。以下代码

<input type="range" name="mynum">

会生成一个如图 4 所示的滑块。

image006.jpg

图 4 Mac OS X 上的 Google Chrome 为 range 输入字段显示的滑块小部件

如果您使用前面说明的 number 或 range 字段,输入无效数字时不会收到错误消息(尽管 Google Chrome 实际上会在您通过表单切换时即时将非数字值转换为数字)。但是,只有有效的数字值才能被表单提交到服务器。例如,如果您在 number 输入字段中输入值“3259a”,发送到服务器的值将是“3259”。如果您输入值“a3259;”,则发送的值将是一个空字符串。当您考虑到为什么浏览器默认不进行验证时,这是非常有道理的,因为表示数字值的方式有很多种。负值、零值、分数、小数——浏览器如何确定什么有效,什么无效?相反,您需要一种方式来告诉浏览器什么构成一个有效数字。幸运的是,这在 HTML5 中非常简单,因为 number 和 range 输入类型都支持三个新的配套属性,允许您定义用于检查数字是否有效的属性:min、max 和 step。

正如您可能期望的那样,min 属性用于指定字段中应允许的最低可接受值。同样,max 属性用于指定允许的最大可接受值。step 属性允许您设置在 min 和 max 属性之间哪些值将被视为可接受。例如,如果您有以下 number 输入

<input type="number" name="mynum"
min="0" max="50" step="10">

可接受的值将是 0、10、20、30、40 和 50。step 属性也可以是小数。例如,以这个 range 输入为例

<input type="range" name="mynum"
min="0" max="1" step="0.2">

在这种情况下,可接受的值将是 0、0.2、0.4、0.6、0.8 和 1。对于 range 输入类型,用户将无法输入无效值,因为他们看到的是一个滑块。但对于 number 输入类型,用户可以通过文本输入或使用微调控件更改值。如果用户在文本框中输入无效值并尝试提交表单,浏览器将取消提交事件并向用户显示错误消息。图 5 展示了您可能会看到的错误消息类型。

image007.jpg

图 5 浏览器(在本例中为 Opera)将验证数字,并在无效时显示如图所示的错误消息。

警告

Safari 5.1 对 number 输入类型有部分支持。它会显示带有微调器小部件的字段,但不会根据 min、max 和 step 属性的值进行数字验证。然而,这些属性在 range 输入类型中可以正常工作。

除了为 number 字段提供新的 UI 小部件和验证属性外,HTML5 还定义了三个 JavaScript API 用于与 number 字段交互:stepUp、stepDown 和 valueAsNumber。stepUp 方法允许您通过将字段的值增加定义的步数来增加其值。您将步数作为参数传递给该方法。假设您有一个名为 mynum 的 number 字段,其 step 属性值设置为 10,并且该字段的当前值为 0。执行 document.forms.myform.mynum.stepUp(2) 将把字段的值增加到 20。stepDown 方法的工作方式相同,只是方向相反。

警告

在使用 stepUp 和 stepDown 时必须小心,因为尝试超出 min 和 max 属性设置的上限和下限进行向上或向下步进将引发 INVALID_STATE_ERR 异常。另一个陷阱是,如果您尝试在字段为空时执行这些方法,也会引发此异常。

valueAsNumber 方法允许您将字段的值作为浮点数获取(与元素的 value 属性不同,后者始终是字符串)。如果您对包含非数字字符的字段使用 valueAsNumber 方法,它将返回 NaN(非数字)。

date, datetime, time, datetime-local, month, and week

如果您曾经在线预订过航班或酒店,您一定遇到过日期选择器小部件,它允许您在一个易于使用的日历中选择您想要预订的日期,该日历可以快速轻松地在月份和年份之间切换。几乎所有使用日期选择器的网站似乎都使用不同的变体,无论是包含在 ExtJS 或 YUI 等 JavaScript UI 库中的,还是来自 ASP.NET 等服务器端开发框架的,或者是网站开发人员在网上找到或自己构建的独立小部件。这存在一些问题:第一个是缺乏一致性。一些选择器会在新的浏览器窗口中作为弹出窗口打开,另一些则会出现在页面内容之上,还有一些甚至会内联显示在表单中(真糟糕!)。另一个问题是,几乎所有这些小部件(至少我们遇到的每一个)都需要 JavaScript 才能工作。如果没有 JavaScript,网站不一定会崩溃(您仍然可以像在文本框中那样输入日期),但除非您的浏览器支持并启用了 JavaScript,否则您将无法使用日期选择器。

为了解决这些问题,HTML5 定义了一系列新的日期和时间相关输入类型,可用于在 Web 表单中输入日期。不幸的是,浏览器供应商在为这些新输入类型添加支持方面进展缓慢,目前唯一为这些元素提供日期选择器的浏览器是 Opera(9 版本及更高版本)。Google Chrome 对日期类型有部分支持,尽管它会显示一个微调器控件(就像在 number 输入类型中使用的一样)。不过,Chrome 在提交时会验证值是否为有效日期。Apple Safari 则落后一步,实现了相同的微调器控件,但根本不验证值。

使用 date 输入类型很简单,如下面的代码片段所示

<input type="date"
name="date_of_birth">

在 Opera 中,此代码将生成一个下拉框,打开时会显示日期选择器小部件,而不是值列表,如图 6 所示。

image008.jpg

图 6 Mac 上的 Opera 11 中的原生日期选择器小部件

在 Google Chrome 中,相同的代码将生成一个微调器小部件,该小部件在日期之间上下步进而不是数字。Chrome 在用户提交表单时还会验证输入的日期是否有效,如图 7 所示。

image009.jpg

图 7 Google Chrome 中的日期验证

date 输入类型的格式为 YYYY-MM-DD。其他日期格式基于本地约定(例如,英国和爱尔兰使用 DD/MM/YYYY,而北美使用 MM/DD/YYYY)。试图考虑各种本地变体将是一场噩梦,因此改为使用 ISO 8601 标准的公历。除了标准的 date 输入类型外,HTML5 还定义了一系列其他日期/时间相关类型

  • datetime: 与 date 相同,但还允许您选择时间(带时区)。
  • datetime-local: 与 datetime 相同,但没有时区。
  • time: 与 datetime-local 相同,但没有日期部分。
  • month: 与 date 相同,但仅选择月份/年份,不选择日期;month 输入类型值的示例是 2011-07(2011 年 7 月)。
  • week: 与 date 相同,但仅选择周/年份,不选择日期;week 输入类型值的示例是 2011-W28(2011 年第 28 周)。

除了新的输入类型外,HTML5 还指定了一个新的 API 方法 valueAsDate,它允许您将输入字段的值作为 Date 对象获取。如果您想对日期进行更复杂的验证,此方法很有用。例如,您可能允许用户在表单中选择开始日期和结束日期。当然,结束日期应在开始日期或之后。过去,您必须获取表单字段的值并从该值构建一个 Date 对象。现在,您可以使用 valueAsDate 方法直接从字段本身获取 Date 对象。

search and color

在大多数动态 Web 站点和应用程序中,您会找到某种形式的搜索框,允许您查找特定页面或数据,通常使用文本输入字段实现。在 HTML5 中,有一种新的 search 输入类型,如果浏览器进一步实现它,它应该能够为您的网站搜索提供原生的增强功能,而无需您进行额外的 JavaScript 开发。使用 search 输入类型与其他任何 HTML5 表单字段的使用类似。

<input type="search" name="mysearch">

在 Opera、Chrome 和 Safari 中,您会发现 search 输入默认样式具有圆角。在 Chrome 和 Safari 中,如果您在字段中输入值,字段右侧会出现一个小“x”,按下该“x”即可清除字段内容。图 8 展示了一个示例。

image010.jpg

图 8 在 Google Chrome 和 Apple Safari 中输入 search 输入字段的值会显示一个小灰色“x”,让您可以轻松清除字段内容

HTML5 中引入的最后一个新输入类型是 color 类型。此字段类型旨在允许您接受十六进制(hex)表示法的颜色值,例如 #000000(黑色)。规范明确指出,颜色值必须

  1. 以 # 字符开头。
  2. 在 # 字符后面有六个字符,范围为 0-9、a-f 和 A-F。

警告

您不应该在 color 输入字段中使用颜色名称,因为 HTML5 仅支持十六进制表示法,并且该字段无法与其他值一起工作。

您可以按如下方式使用 color 输入类型。

<input type="color" name="mycolor">

在 Opera 以外的所有浏览器中,color 输入类型将显示为标准文本框,并且大多数浏览器不会实现任何附加功能。Google Chrome 会根据上述规则验证输入的颜色值是否有效。然而,Opera 对 color 输入类型提供了更成熟的支持,它实现了原生的颜色选择器小部件,消除了实现第三方 JavaScript 颜色选择器的需求。图 9 展示了一个 Opera 颜色选择器在 Mac OS X 上运行的示例。

image011.jpg

图 9 Mac OS X 上 Opera 颜色选择器小部件的运行情况。单击“Other…”按钮将启动原生的 Mac OS X 颜色实用程序,您可以在其中选择更广泛的颜色。

现在您已经看到了 HTML5 中提供的新输入类型,您已经准备好动手实践,并在实际示例中应用您所学到的知识。在下一节中,您将这样做,构建您在图 10 中看到的注册表单。

image012.jpg

图 10 一个示例 HTML5 注册表单,其中包含 HTML5 中引入的许多新 Web 表单功能,包括新的输入类型、验证、占位符、进度条等

向注册表单示例应用程序添加表单字段

如图 10 所示,您在本章中构建的注册表单有四个输入部分:账户信息、个人信息、公司信息和联系信息。现在您已经了解了 HTML5 中可用的各种新类型的表单字段,让我们开始构建这些部分,使用适当类型的输入字段。列表 1 提供了您为账户信息和个人信息部分所需的代码;将其添加到 index.html 中,紧随您之前添加的 <form> 元素之后。

列表 1 将账户信息和个人信息部分添加到注册表单中,使用新的日期和颜色输入类型

<fieldset>
    <legend>Account Information</legend>
    <ul>
        <li>
            <label for="username">Username*</label>
            <input name="username" id="username">
        </li>
        <li>
            <label for="password">Password*</label>
            <input type="password" name="password" id="password">
        </li>
        <li>
            <label for="confirm_password">Confirm Password*</label>
            <input type="password" name="confirm_password" id="confirm_password">
        </li>
        <li>
            <label for="credit_card">Credit Card No*</label>
            <input name="credit_card" id="credit_card">
        </li>
    </ul>
</fieldset>
<fieldset>
    <legend>Personal Information</legend>
    <ul>
        <li>
            <label for="name">Name*</label>
            <input name="name" id="name">
        </li>
        <li>
            <label for="date_of_birth">Date of Birth*</label>
            <input type="date" name="date_of_birth" id="date_of_birth">  #1
        </li>
        <li>
            <label for="color">Favorite Color</label>
            <input type="color" name="color" id="color" value="#0000FF"> #2
        </li>
        <li>
            <label for="photo">Profile Photo(s)</label>
            <input type="file" name="photo" id="photo">
        </li>
        <li>
            <label for="browser">Favorite Browser</label>
            <input name="browser" id="browser">
        </li>
    </ul>
</fieldset>
#1 date input type
#2 color input type

此时,您可能在想:“所有新的元素在哪里?这都是老旧的 HTML!” 您是对的——列表 1 中的大多数代码包含旧的输入类型。在个人信息部分,您要求用户输入他们的出生日期,为他们提供一个新的日期输入字段(#1)。表单还包括一个用于用户喜欢的颜色的字段,使用 color 输入类型(#2)。公司信息和联系信息部分的每个字段都是新的 HTML5 输入类型。让我们现在添加它们——将列表 2 中的代码插入到您之前添加的代码之后。

列表 2 将公司信息和联系信息部分添加到表单中,使用 number、range、email、tel 和 url HTML5 输入类型

<fieldset>
    <legend>Company Information</legend>
    <ul>
        <li>
            <label for="employees">No. of Employees</label>
            <input type="number" name="employees" id="employees" min="0" max="100000" step="100"> #1
        </li>
        <li>
            <label for="revenue">Estimated Revenue</label>
            <input type="range" name="revenue" id="revenue" min="0" max="1000" step="1" value="0"> #2
        </li>
    </ul>
</fieldset>
<fieldset>
    <legend>Contact Information</legend>
    <ul>
        <li>
            <label for="email">Email Address(es)*</label>
            <input type="email" name="email" id="email"> #3
        </li>
        <li>
            <label for="phone_number">Phone Number</label>
            <input type="tel" name="phone_number" id="phone_number"> #4
        </li>
        <li>
            <label for="website">Website URL</label>
            <input type="url" name="website" id="website"> #5
        </li>
    </ul>
</fieldset>
#1 number input type
#2 range input type
#3 email input type
#4 tel input type
#5 url input type

在公司信息部分,有两个字段,都使用新的 HTML5 输入类型。第一个字段是公司员工人数,定义为 HTML5 number 输入字段,最小值为 0,最大值为 100,000,并且以 100 为步长向上和向下调整(#1)。第二个字段要求用户输入公司估计收入,使用 range 输入类型,允许值为 0 到 1,000(百万)之间(#2)。您可能会注意到,您无法在滑块上看到字段的当前值(如图 11 所示)。您可以使用 <output> 元素来解决这个问题。

image013.jpg

图 11 HTML5 滑块小部件不显示 range 输入字段的当前值。

在表单的最后一个部分,联系信息,您要求用户输入他们的电子邮件地址(使用 email 输入字段 #1),电话号码(使用 tel 字段 #2),最后是他们网站的 URL(使用 url 输入字段 #3)。此时,注册表单的标记将为您提供一个类似于图 10 中看到的屏幕截图的结果。

摘要

毫无疑问,Web 表单在现代 Web 应用程序中极其重要。几乎所有存在的 Web 应用程序都在某种程度上依赖 Web 表单为用户提供功能。无论是数据输入和检索、搜索查询,还是通信和消息传递,Web 表单无处不在。HTML 早期版本对 Web 表单的支持充其量只是基础。如果您想为用户提供任何形式的反馈,或者允许他们使用合理形式的输入(例如用于输入日期的日期选择器)来输入数据,您必须依赖第三方 JavaScript 库来实现此类功能。如果您的用户使用的浏览器不支持 JavaScript,那么您就别指望能有像样的控件和客户端验证了。

HTML5 引入了许多用于改进 Web 表单的功能。不幸的是,尽管这些新功能和改进的许多方面作为 HTML5 规范的一部分存在已有一段时间,但浏览器供应商在近期的浏览器版本中实现这些功能的速度相对较慢。唯一为日期和颜色选择器实现小部件的浏览器供应商是 Opera,而且这种情况似乎不太可能很快改变。尽管存在这个问题,但有一点是肯定的——所有浏览器最终都会提供对这些新功能的完整支持,届时,您应该准备好在您的应用程序中利用它。

您可能还会对以下 Manning 图书感兴趣:

image014.jpg

你好!HTML5 和 CSS3
作者:Rob Crowther

image015.jpg

Sass 和 Compass 实战
作者:Wynn Netherland、Nathan Weizenbaum 和 Chris Eppstein

image016.jpg

JavaScript Ninja 的秘密
作者:John Resig 和 Bear Bibeault

 

© . All rights reserved.