精通-HTML5-表单-全-

精通 HTML5 表单(全)

原文:zh.annas-archive.org/md5/835835C6B2E78084A088423A2DB0B9BD

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

Web 浏览者可能永远不会了解应用程序的背景,比如 HTML5、CSS3、响应式网页设计或 PHP。他们想知道的是你的应用程序是否在他们的设备上运行,以及需要多少努力。

尽管多年来网页开发发生了变化,但创建网页的核心任务并未改变。我们创建一个文档并将其放在网上供人们查看。要将某物放在网上,我们需要学习一些在网上被接受的特殊语言。是的,我们说的是像 HTML 和 PHP 这样的脚本语言。

这本书的主要目标是确保填写你构建的表单的用户在各个方面都能享受并感到满意。这里的满意意味着表单的外观和感觉以及在导航时最小的页面调整,这可以是在台式电脑、移动设备或迷你笔记本上。

这本书的写作是考虑到读者应该享受一种逐步、示例驱动和基于视觉的学习方法。这本书将涵盖网页开发的许多方面,比如用于开发网页表单的语言,以及使网页表单看起来好看并接受访客信息的方法。

这本书将作为一个平台,让你学习如何创建美观且响应灵敏的表单,并将它们链接到数据库,表单信息将被存储在其中。

这本书涵盖了什么

第一章,表单及其重要性,解释了什么是网页表单,以及我们如何使用新的 HTML5 表单元素来创建这些表单。它还解释了网页表单的好处,以及在设计和开发表单时必须始终牢记的指南。

第二章,表单验证,解释了表单验证及其在表单中的必要性,以及新的 HTML5 元素及其属性,这些属性减少了客户端验证的工作量。它简要描述了验证约束和支持的 API,还向我们介绍了在浏览器上自定义错误消息的方法。

第三章,表单样式,解释了可以利用的 CSS3 属性,使表单更具展示性。它详细介绍了在不同浏览器中使用的供应商特定前缀,以及在增强表单外观和感觉时必须牢记的有效样式指南。

第四章,与数据库连接,简要解释了如何使用 PHP 和 MySQL 将表单链接到服务器,这是网页开发人员用来存储用户信息的工具。

第五章,响应式网页表单,解释了响应式设计和可以用来使我们的表单响应式的方法。它还讨论了制作响应式表单时应遵循的指南。

你需要为这本书准备什么

任何文本编辑器,如 Notepad++或 Bluefish 都可以用来编写 HTML 和 JavaScript 代码。在 Windows 中,Notepad 也可以用来创建一个简单的 HTML 文件,CSS 和 JavaScript 代码可以嵌入其中,然后可以在 Web 浏览器中打开。

好消息是几乎每个 Web 浏览器都配备了内置的 HTML 和 JavaScript 解释器,它在运行时在 Web 浏览器主机环境中编译代码并执行。

PHP 文件可以在用于编写 HTML、CSS 或 JavaScript 的任何编辑器中编写。在 Windows 中,Wamp 服务器用于将表单链接到服务器,phpMyAdmin 工具用于 MySQL 数据库。

这本书适合谁

这本书将帮助任何愿意提升使用 HTML5 和相关技术构建网页表单的技能的人。

这本书应该被那些有兴趣学习如何使用 HTML5、CSS3 和 PHP 来构建响应式、美观和动态网页表单的人阅读。

不同的读者会发现本书的不同部分有趣。

不必过多担心对以前的 W3C 规范和 PHP 有深入的了解,学习过 HTML 和 PHP 的初学者可以直接学习如何使用 HTML5、CSS3 和 PHP 构建网页表单,并收集客户信息。

约定

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

文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 用户名显示如下:"我们可以通过使用include指令来包含其他上下文。"

代码块设置如下:

<div class="gender">
  <label for="gender">Gender</label><br>
  <input type="radio" name="gender"><label>Male</label>
  <input type="radio" name="gender"><label>Female</label>
</div><br>

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

font-family: Helvetica, Arial, sans-serif;
  color: #000000;
  background: rgba(212,228,239,1);
  background: -moz-linear-gradient(top, rgba(212,228,239,1) 0%, rgba(134,174,204,1) 100%);
  background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(212,228,239,1)), color-stop(100%, rgba(134,174,204,1)));

新术语重要单词以粗体显示。例如,屏幕上看到的单词,比如菜单或对话框中的单词,会以这样的方式出现在文本中:"为了将表单提交到服务器,我们创建了一个提交按钮"。

在本书中,我们已经使用了约定来表示 Mozilla Firefox、Google Chrome、Safari、Internet Explorer 和 Opera。

注意

警告或重要说明会出现在这样的框中。

提示

提示和技巧会以这种方式出现。

第一章:表单及其重要性

在网页中使用表单是从用户那里收集相关数据的最有效方式。表单是用户与应用程序真正交互的方式,无论是搜索表单、登录界面还是多页注册向导。表单可以包含姓名、性别、信用卡号、密码、图片或将文件上传到表单中。

在本章中,我们将涵盖以下主题:

  • 网络表单及其好处

  • 新的 HTML5 <form>元素

  • 构建网络表单

  • 构建网络表单的指南

理解网络表单

在我们开始学习 HTML5 表单之前,让我们先了解一下什么是网络表单。

网页上的表单提供了一个接口,使客户和用户之间的信息共享更加方便和安全,相比纸质表单。它们是各种<input>类型的集合,例如textboxradiobuttoncheckbox,允许用户执行各种操作并简化决策过程。

表单一直是网络的基本组成部分。没有它们,各种网络交易、讨论和高效搜索将根本不可能。网络表单得到大多数浏览器的支持,可以用于在购买产品后提供反馈、从搜索引擎检索搜索结果、联系任何服务等等。

通过一个简单的例子,让我们了解一下什么是网络表单。假设你曾经去过一家医院,接待员给了你一张打印的表格填写。你可能会看到许多字段,收集有关患者的信息。其中一些要求你在看起来像文本框或文本区域的地方写下患者的姓名和地址,以及房间类型等其他细节;你还被要求从选项中选择一个或多个单选按钮或复选框。HTML5 表单也是遵循相同的概念。你需要填写该表单的字段,并按下按钮将此信息发送到服务器,而不是去医院将表格交给接待员。

好处

网页中的表单相比纸质表单有很多优势。除了用于在线收集数据外,网络表单为用户和表单所有者提供了便利和速度。

网络表单的一些优点包括:

  • 在线表单帮助客户与公司交流,因为它们包含数字化存储的数据,并将该数据推导为有意义的信息

  • 表单所有者可以快速构建和分发 HTML5 界面,面向大众

  • 表单所有者可以根据需要轻松更新和修改表单

  • 层叠样式表(CSS)和 JavaScript 属性允许作者使用特定样式和功能自定义表单控件

  • 网络表单节省时间和成本,因为它们不需要人力来收集信息。

  • 它们为决策提供了可见性,例如在 eBay 等网站上在线购物

  • 由于数据是由客户直接输入的,因此可以轻松地对其进行排序以获取所需的信息

即使表单有很多好处,构建它们并不是一件愉快的工作,如果涉及验证、错误处理和样式,有些表单可能会变得非常复杂,这可能会成为一个头疼的问题。我们可以使用服务器端语言验证或捕获错误,也可以使用 JavaScript,甚至两者都可以。无论哪种情况,网络表单可能会占用大量开发时间,这可能会成为一个问题。然而,通过引入新的<form>类型,HTML5 已经减轻了一些痛苦。

尽管 HTML5 有许多增强功能,但有些东西保持不变,比如:

  • 当用户单击提交按钮时,表单仍然会将值发送到服务器

  • 表单仍然被包含在<form>元素中,如下面的代码片段所示:

<form action= "#">
  <input type= "text" name= "emailaddress">
  <input type= "submit" name= "submit">
</form>
  • 表单控件仍然可以完全进行脚本处理

然而,对于 HTML5 表单,没有必要将<form>控件包含在<form>元素中。

HTML 与 HTML5 表单

HTML5 表单相对于以前的版本提供了两个主要优势。它们是:

  • 在 HTML5 的新<form>类型和内置验证的支持下,以前版本的 HTML 中需要繁琐的脚本和表单样式已经被移除,因为它将语义标记提升到了一个新的水平。

  • 即使在浏览器中禁用了脚本,用户也可以体验到 HTML5 表单的好处

表单<input>类型、元素和属性

HTML5 表单专注于增强现有的简单 HTML 表单,以包含更多类型的控件,并解决今天 Web 开发人员面临的限制。其中最好的一点是,你现在几乎可以使用所有新的输入类型、元素和属性,HTML5 表单完全向后兼容。支持新 HTML5 元素的浏览器会增强其功能,否则不支持的浏览器会将其显示为文本框。

在本节中,我们将学习新的 HTML5<form>元素,如<input>类型、元素和属性,这些元素是为了增强表单的功能而引入的。

<form> <input> types

  • date: date 类型允许用户选择没有时区的日期。

它在  types中受支持。

语法:

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

属性:

  • value: 初始值。格式为 yyyy-mm-dd

  • min, max: 可以选择的最小和最大日期的范围

  • datetime: datetime 类型允许用户选择带有 UTC 时区设置的日期和时间。

格式为 yyyy-mm-dd HH:MM。

它在  types中受支持。

语法:

<input type= "datetime" name= "#">
  • datetime-local: datetime-local 类型允许用户选择没有时区的日期和时间。使用的格式是 yyyy-mm-dd HH:MM。

它在  types中受支持。

语法:

<input type= "datetime-local" name= "#">
  • color: color 类型会打开一个颜色选择器弹出窗口,用于选择<input>类型的颜色#rrggbb(十六进制值)。它可以用色块或轮式选择器表示。

选择的值必须是有效的简单颜色的十六进制值,如#ffffff

它在  types中受支持。

语法:

<input type= "color" id= "#"name= "#">

属性:

  • value: 初始值

  • number: number 类型允许用户输入整数浮点数

它也被称为微调器。

我们可以对接受的数字设置限制。

它在  types中受支持。

语法:

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

属性:

  • value: 初始值

  • min, max: 可以使用上/下箭头选择的最小和最大值的范围

  • step: 当滚动微调器时告诉我们要改变值的量

  • range: range 类型允许用户从一系列数字中输入整数浮点数。它以滑块的形式显示。

使用这个,除非使用 JavaScript,否则不会显示确切的值,所以如果你希望用户选择确切的值,使用<input type="number" />

我们可以对接受的数字设置限制。

它在  types中受支持。

语法:

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

属性:

  • value: 初始值。默认值是滑块的中间值。

  • min, max: 可以选择的最小和最大值的范围。最小值的默认值为 0,最大值为 100。

  • step: 当滚动微调器时告诉我们要改变值的量。默认值为 1。

  • email: email 类型允许用户以电子邮件地址格式email@example.com输入文本。

点击提交按钮时,输入的文本会自动验证。

如果指定了多个属性,则可以输入多个电子邮件地址,用逗号分隔。

它在  types中受支持。

语法:

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

属性:

  • value: 初始值(合法的电子邮件地址)

接受使用多个属性,即多个电子邮件 ID,并且每个属性由逗号分隔。

  • 搜索<input>类型搜索允许用户输入要搜索的文本。

搜索字段的行为类似于标准文本字段,并具有内置的清除文本功能,例如 WebKit 浏览器中的交叉按钮。

它在 类型中得到支持。

语法:

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

属性:

  • :初始值

  • 电话tel类型允许用户输入电话号码。tel不提供任何默认语法,因此如果您想确保特定格式,可以使用pattern进行额外验证。

目前尚无浏览器支持。

语法:

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

属性:

  • :初始值为电话号码

  • 月份月份类型允许用户选择一个月和一个没有时区的年份。

它在 类型中得到支持。

语法:

<input type= "month" name= "#" >

属性:

  • :初始值。格式为 yyyy-mm。

  • 最小值最大值:可以选择的最小和最大值范围。

  • 时间时间类型允许用户选择一个具有小时、分钟、秒和没有时区的分数秒的时间值。

它在 类型中得到支持。

语法:

<input type= "time" name= "#">
  • 网址网址类型允许用户输入绝对 URL。

单击提交按钮时,输入的文本会自动验证。

它在 类型中得到支持。

语法:

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

属性:

  • :初始值为绝对 URL

  • 类型允许用户选择一周和一年,没有时区。

它在 类型中得到支持。

语法:

<input type= "week" name= "#">

属性:

  • :初始值。格式为 yyyy-mmW。

到目前为止,我们已经了解了各种<input>类型。现在让我们看看新的 HTML5<form>元素。

<form>元素

  • <datalist><datalist>元素为用户提供了一个预定义选项列表,以便在输入数据时为表单控件提供自动完成功能。它用于在<form>元素上提供自动完成功能。

例如,如果用户在文本字段中输入一些文本,将会显示一个下拉列表,其中包含他们可以选择的预填充值。

它在元素中得到支持。

例如:

<input list= "browsers" name= "browser">
<datalist id= "browsers">
  <option value= "Internet Explorer">
  <option value= "Firefox">
</datalist>
  • <keygen><keygen>元素用于提供一种安全的用户认证方式。

当表单提交时,私钥存储在本地密钥库中,公钥打包并发送到服务器。

它在元素中得到支持。

例如:

<form action= "keygen.html" method= "get"><input type= "text" name= "username"><keygen name= "security"><input type= "submit">
</form>
  • <output><output>元素表示执行的计算结果,类似于脚本执行的计算结果。

它在元素中得到支持。

例如:

<form onsubmit="return false" oninput="o.value=parseInt(a.value)+parseInt(b.value)"><input name="a" type="number" step="any">+<input name="b" type="number" step= "any">
=<output name="o"></output></form>

现在让我们看看新的 HTML5<form>属性。

<form>属性

  • 自动完成autocomplete属性允许用户根据先前的输入完成表单。我们可以为表单设置自动完成on选项,为特定输入字段设置off选项,或者反之亦然。

它适用于<form><input>类型,如文本框日期选择器范围颜色网址电话搜索电子邮件

它在属性中得到支持。

例如:

<input type="text" name="city" autocomplete="on">
  • 自动聚焦:当添加autofocus属性时,<input>类型在页面加载时会自动获得焦点。

例如,当我们打开 Google 主页或任何搜索引擎时,焦点会自动转到文本框,用户在其中输入文本以执行搜索。

它适用于<input>类型,文本框搜索网址电子邮件电话密码

它在属性中得到支持。

例如:

<input type="text" name="city">
<input type="text" name="state" autofocus>
  • 占位符placeholder属性为用户提供了描述<input>字段预期值的提示。

当单击控件或获得焦点时,它会消失。

它应该仅用于简短的描述,否则使用title属性。

它适用于textboxsearchurlemailtelpassword类型的<input>

它在属性中得到支持。

例如:

<input type="text" name="name" placeholder="First Name">
  • minmaxminmax属性用于指定<input>类型的最小值和最大值。

它适用于numberrangedatedatetimedatetime-localmonthtimeweek类型的<input>

它在属性中得到支持。

例如:

<input type="number" min="1" max="5">
  • listlist属性指的是包含<input>元素的预定义选项的<datalist>元素。

它用于在<form>元素上提供autocomplete功能。

例如,如果用户在文本字段中输入一些文本,将会出现一个下拉列表,其中包含预填充的值供他们选择。

它适用于textboxsearchurlemailtel类型的<input>

它在属性中得到支持。

例如:

<input list= "browsers" name= "browser">
<datalist id= "browsers">
  <option value= "Internet Explorer">
  <option value= "Firefox">
</datalist>
  • formnovalidateformnovalidate属性指定在提交时不应验证表单。它覆盖了<form>元素的novalidate属性。

它适用于submitimage类型的<input>

它在属性中得到支持。

例如:

<input type="email" name="email"><input type="submit" formnovalidate value="Submit">
  • formform属性指定一个或多个表单,一个<input>类型属于这些表单,或者说,它允许用户将任何孤立的表单控件与页面上的任何<form>元素关联起来。

它在属性中得到支持。

例如:

<body>
  <form action="form.html" id="form1"><input type="text" name="fname"><br><input type="submit" value="Submit"></form>
  <p>The "Last name" field below is outside the form element, but it is still a part of the form</p>
  <input type="text" name="lname" form="form1">
</body>
  • formactionformaction属性指定将提交表单的文件或应用程序的 URL。

它适用于submitimage类型的<input>

它在属性中得到支持。

例如:

<input type="submit" value="Submit" formaction="form.html">
  • formenctypeformenctype属性指定提交到服务器时如何对表单数据进行编码。

它仅适用于post方法。

它适用于submitimage类型的<input>

它在属性中得到支持。

例如:

<input type="submit" value="Submit" formenctype="multipart/form-data">
  • formmethodformmethod属性指定用于提交表单数据的 HTTP 方法,如GETPOSTPUTDELETE

它适用于submitimage类型的<input>

它在属性中得到支持。

例如:

<input type="submit" value="Submit" formmethod="post">
  • formtargetformtarget属性指定提交表单后用于显示接收到的响应的目标窗口。

它适用于submitimage类型的<input>

它在属性中得到支持。

例如:

<input type="submit" value="Submit" formtarget="_self">

值:

  • blank

  • 自身

  • parent

  • top

  • 框架名称

  • multiplemultiple属性允许用户为<input>类型输入多个值。

它适用于emailfile类型的<input>

它在属性中得到支持。

例如:

<input type= "file" name= "image"multiple>
  • novalidatenovalidate属性指定在单击提交按钮时不应验证表单。

它在属性中得到支持。

例如:

<form action= "form.html" novalidate>
  <input type= "text" name= "city">
  <input type= "text" name= "state" autofocus>
</form>
  • step:让我们通过一个例子来理解step属性。如果step= 2,合法的数字可以是20246

它适用于<input>类型,包括numberrangedatedatetimedatetime-localmonthtimeweek

它在属性中得到支持。

例如:

<input type= "range" name= "#" step= "2">
  • required:添加required属性后,强制要求在提交表单之前必须填写输入字段。

目前,错误消息是特定于浏览器的,无法通过 CSS 控制。

它取代了用 JavaScript 实现的基本<form>验证,从而节省了开发时间。

它在属性中得到支持。

例如:

<input type= "text" name= "city"required>
  • pattern:使用 pattern 属性,您可以使用 正则表达式regex)声明自己的验证要求。

它适用于 <input> 类型,如 textsearchurltelemailpassword

如果用户输入的值不符合模式,它将显示一个浏览器通用的消息。

它在  属性 中得到支持。

例如:

<input type= "text" name= "country_code" pattern= "[A-Za-z]{3}" placeholder= "Three letter country code">

构建 HTML5 表单

到目前为止,我们所学习的关于 HTML5 表单的只是理论知识,但现在是时候将这些知识提升到下一个水平了。将其提升到下一个水平意味着在这一部分,我们将构建一个带有对它们的结构和新的 <form> 类型的一些理解的样本表单,这些我们已经讨论过了。

在样式或功能(如设计和验证)方面,我们将花费更少的时间,而更多地关注 HTML5 的新 <form> 类型的核心。这种表单在支持 HTML5 特性的浏览器中得到最好的支持。

在这个例子中,我们将构建一个健康调查表单。

这个例子演示了一个简单的表单,使用了基本的 HTML 元素和新的 <form> 元素,代码应该是不言自明的。

现在,让我们来看看代码。以下代码是表单的 CSS,它保存在一个扩展名为 .css 的单独文件中(外部 CSS 文件),并链接到主 HTML 页面。拥有单独的 CSS 文件也是一个好的做法。

html {
  background-color: #333;
  margin: 0px;
  padding: 0px;
}
body {
  font-size:12px;
  width: 517px;
  padding: 20px;
  margin: 10px auto;
  background-color: #eee;
  font-family: Helvetica, Arial, sans-serif;
  color: #333;
}
label{
  font-weight:bold;
}

/* General Form */
.heading{
  font-size:20px;
}
.gender{
  position:relative;
  top:-42px;
  left:185px;
}
.selectOption{
  width:239px;
}
.textboxAddress{
  width:474px;
}
.textboxAddressDetail{
  width:232px;
}
.legend{
  font-weight:bold;
  font-size:14px;
}
.submit{
  text-align:center;
}

以下代码是我们构建表单结构的主要 HTML 页面。<fieldset> 标签被包含在 <form> 标签内。

结构被分成了几个部分,以便更好地理解。此外, <form> 类型被加粗显示。

以下是用于显示个人信息表单的代码片段:

<fieldset>
  <legend class="legend">Personal Information</legend>
  <div>
    <label for="name">Name</label><br>
    <input type="text" placeholder="First" autofocus>
    <input type="text" placeholder="Last">
  </div><br>
  <div>
    <label for="dob">Date of Birth</label><br>
    <input type="date" value="">
  </div>
  <div class="gender">
    <label for="gender">Gender</label><br>
    <input type="radio" name="gender"><label>Male</label>
    <input type="radio" name="gender"><label>Female</label>
  </div><br>
  <div>
    <label for="address">Address</label><br>
    <input type="text" class="textboxAddress" placeholder="Street Address"><br>
    <input type="text" class="textboxAddress" placeholder="Address Line 2"><br>
    <input type="text" class="textboxAddressDetail" placeholder="City">  
    <input type="text" class="textboxAddressDetail" placeholder="State/Province"><br>
    <input type="text" class="textboxAddressDetail" placeholder="Pincode">
    <select class="selectOption">
      <option value="Country">Select Country</option>
    </select>
  </div><br>
  <div>
    <label for="contact">Phone Number</label><br>
    <input type="tel" class="textboxAddressDetail" placeholder="Home"> 
    <input type="tel" class="textboxAddressDetail" placeholder="Work">
  </div><br>
  <div>
    <label for="email">Email Address</label><br>
    <input type="email" class="textboxAddressDetail" placeholder="email@example.com">
  </div>
</fieldset>

提示

下载示例代码

您可以从您在 www.packtpub.com 购买的所有 Packt 图书的帐户中下载示例代码文件。如果您在其他地方购买了本书,您可以访问 www.packtpub.com/support 并注册,以便直接通过电子邮件接收文件。

代码的输出如下:

构建 HTML5 表单

这一部分询问受访者有关他们的个人信息,如姓名、地址和其他详细信息。我们使用了带有描述性文本的 <label> 并将其与表单控件绑定。

我们还在第一个文本框上使用了 autofocus 属性,这样当页面加载时,<input> 元素会自动获得焦点。placeholder 属性在第一个文本框中多次使用,作为First来提示受访者所需的内容。对于出生日期,我们使用了 <input> 类型 date,它会以日历形式打开。

还使用了基本的 HTML 元素 <input> 类型,如 radiobuttontextbox 和下拉列表。

同样,对于电话号码字段,使用了 <input> 类型 tel,对于电子邮件地址字段,使用了 <input> 类型 email

以下是用于显示一般信息表单的代码片段:

<fieldset>
  <legend class="legend">General Information</legend>
  <div>
    <label for="info">What is your</label><br>
    <input type="text" placeholder="Age?"> 
    <input type="text" placeholder="Weight?"> 
    <input type="text" placeholder="Height?">
  </div><br>
  <div>
    <label for="exerciceinfo">Do you regularly engage in any of the following exercises?</label><br>
    <div><input type="checkbox" name="smoke"><label>Walking</label><br>
    <input type="checkbox" name="smoke"><label>Running</label></div>
    <div><input type="checkbox" name="smoke"><label>Swimming</label><br>
    <input type="checkbox" name="smoke"><label>Biking</label></div>
    <div><input type="checkbox" name="smoke"><label>Others</label><br>
    <input type="checkbox" name="smoke"><label>I don't exercise</label></div>
  </div><br>
  <div>
    <label for="sleep">On average, how many hours a day do you sleep?</label><br>
    <input type="number" class="textboxAddressDetail">
  </div><br>
  <div>
    <label for="smoking">Have you ever smoked cigarettes, pipes or cigars?</label><br>
    <input type="radio" name="smoke"><label>Yes</label>
    <input type="radio" name="smoke"><label>No</label>
  </div><br>
  <div>
    <label for="drugs">Are you currently using or do you have a history of illegal drug use?</label><br>
    <input type="radio" name="drugs"><label>Yes</label>
    <input type="radio" name="drugs"><label>No</label>
  </div><br>
  <div>
    <label for="alcohol">Do you consume alcohol?</label><br>
    <input type="radio" name="alcohol"><label>Yes</label>
    <input type="radio" name="alcohol"><label>No</label>
  </div>
</fieldset>

代码的输出如下:

构建 HTML5 表单

表单的顶部部分询问受访者一般信息,如年龄、体重、身高以及其他关于他们日常生活的信息。

在这里,我们使用了基本的 HTML <form> <input> 类型,如 textboxradiobuttoncheckbox,以及新的 <form> 属性,如 placeholder,来从受访者那里获取输入。

以下代码片段显示了一个存储医疗信息的表单:

<fieldset>
  <legend class="legend">Medical Information</legend>
  <div>
    <label for= "disease">Check all that apply to you or your immediate family?</label><br>
    <input type="checkbox" name="disease"><label>Asthma</label><br>
    <input type="checkbox" name="disease"><label>Cancer</label><br>
    <input type="checkbox" name="disease"><label>HIV and AIDS</label><br>
    <input type="checkbox" name="disease"><label>Diabetes</label><br>
    <input type="checkbox" name="disease"><label>Hypertension</label><br>
    <input type="checkbox" name="disease"><label>Malaria</label><br>
    <input type="checkbox" name="disease"><label>Seizure Disorder</label><br>
    <input type="checkbox" name="disease"><label>Psychiatric Disorders</label><br>
    <input type="checkbox" name="disease"><label>Mental Health</label><br>
    <input type="checkbox" name="disease"><label>Stroke</label><br>
    <input type="checkbox" name="disease"><label>Others</label><br>
    <input type="checkbox" name="disease"><label>Not Applicable</label>
  </div><br>
  <div>
    <label for= "symptons">Checkall symptoms you are currently experiencing</label><br>
    <input type="checkbox" name="symptoms"><label>Allergy</label><br>
    <input type="checkbox" name="symptoms"><label>Eye</label><br>
    <input type="checkbox" name="symptoms"><label>Lymphatic</label><br>
    <input type="checkbox" name="symptoms"><label>Fever</label><br>
    <input type="checkbox" name="symptoms"><label>Eating Disorder</label><br>
    <input type="checkbox" name="symptoms"><label>Hemtalogical</label><br>
    <input type="checkbox" name="symptoms"><label>Musculoskeletal Pain</label><br>
    <input type="checkbox" name="symptoms"><label>Skin</label><br>
    <input type="checkbox" name="symptoms"><label>Gastrointestinal</label><br>
    <input type="checkbox" name="symptoms"><label>Weight Loss</label><br>
    <input type="checkbox" name="symptoms"><label>Others</label><br>
    <input type="checkbox" name="symptoms"><label>Not Applicable</label>
  </div><br>
  <div>
    <label for="allergy">Please list any medication allergies that you have</label><br>
    <textarea name="allergy" rows="4" cols="57">
    </textarea>
  </div><br>
  <div>
    <label for="medications">Please list any medications you are currently taking</label><br>
    <textarea name= "medications" rows="4" cols="57">
    </textarea>
  </div><br>
  <div>
    <label for="pregnancy">If you are a woman, are you currently pregnant, or is there a possibility that you are pregnant?</label><br>
    <input type="radio" name="pregnancy"><label>Yes</label>
    <input type="radio" name="pregnancy"><label>No</label>
    <input type="radio" name="pregnancy"><label>Not Applicable</label>
  </div><br>
  <div>
    <label for="healthrating">In general, would you say your health is</label><br>
    * Taking 1 to be poor and 5 to be excellent<br>
    <input type="number" name="healthrating" min="1" max="5">
  </div><br>
    <label for="ratinghealth">When you think about your health care, how much do you agree or disagree with this statement: "I receive exactly what I want and need exactly when and how I want and need it."</label><br>
    * Taking 1 to be strongly dis-agree and 5 to be strongly agree<br>
    1<input type="range" name="ratinghealth" min="1" max="5">5
  </div> 
</fieldset>

<div class="submit">
  <input type="submit" value="Submit">
</div>

代码的输出如下:

构建 HTML5 表单

我们表单的最后部分询问受访者有关他们的医疗信息。为了获取受访者所患各种疾病或症状的信息,我们使用了基本的 HTML <form> <input> 类型 checkbox

Textarea是一个自由文本字段,其中包含详细的文本,在我们的情况下,允许受访者输入信息,例如药物过敏和药物。textarea的行和列确定了表单中textarea文本字段的可显示大小。我们还可以通过设置maxlength来限制受访者输入详细信息。

radiobutton用于限制受访者从多个选项中选择一个选项。

使用<input>类型number,我们创建了一个微调器,这是一个精确的控件,用于选择由数字表示的字符串。在这里,我们通过将最小值设置为1和最大值设置为5来设置限制。

使用<input>类型range,我们创建了一个滑块,这是一个不精确的控件,用于将值设置为表示数字的字符串。在这里,我们通过将最小值设置为1和最大值设置为5来设置限制。

最后,<input>类型submit将数据发送到服务器。

指导方针

一个良好的实践或指导方针是设计和开发一个标准的方法,这总是表现出更好的结果。

创建有效表单的一些最佳实践如下:

  • 使用相关内容分组来组织表单

  • 最小化填写表单所需的帮助和提示的数量

  • 采用灵活的数据输入

  • 对于长表单,显示进度并保存选项

  • 保持一致的方法

  • 保持初始选择选项之间的清晰关系

  • 使用内联验证输入,可能具有较高错误率

  • 提供可操作的补救措施来纠正错误

  • 在用户单击提交按钮后禁用提交按钮,以避免多次提交

  • 清楚地传达关于数据提交的信息并提供反馈

  • 保持 CSS 和 JavaScript 的单独文件

使用最佳实践:

  • 提高跨浏览器兼容性

  • 提高性能

  • 节省时间并降低成本

  • 项目理解变得容易

  • 代码维护变得容易

总结

在本章中,我们了解了表单及其使用的好处。我们已经看到了基本的 HTML 表单和 HTML5 表单之间的区别。

我们了解了新的<form>控件,dateweektelemailrangenumbers等等,我们不必依赖 JavaScript,以及它们在现代浏览器中的工作方式。

我们还构建了一个示例表单,以便熟悉表单,并在本章末尾学习了创建有效网络表单的最佳实践。

总的来说,我们已经看到了如何通过 HTML5 的帮助来减少脚本编写和开发时间,当用户需要创建具有完整功能的表单时。

第二章:表单验证

自从 Web 诞生以来,表单验证一直是开发人员头疼的问题。在 HTML5 出现之前,开发人员为了验证表单以获取用户所需的信息而编写了大量代码。

在本章中,我们将涵盖以下主题:

  • 验证、它们的好处和类型

  • 用于验证的 HTML5 <input>和属性

  • JavaScript 和 HTML5 验证的区别及示例

  • 验证约束和支持的 API(应用程序编程接口)

  • 浏览器显示的默认错误消息

表单验证

表单验证是一系列检查和通知,指导用户在向服务器提交信息时需要输入什么。我们也可以说,这是一种检查输入数据是否符合特定标准或要求的过程。

表单验证是检测无效控件数据并向最终用户显示这些错误的过程。该术语具有以下几个好处:

  • 提供必要的指示和提示

  • 提供元素的逻辑阅读和导航顺序

  • 用户可以轻松地了解他们在输入数据时所犯的错误

  • 确保可以使用键盘完成并提交表单

  • 节省用户在 HTTP 请求或网络调用上的等待时间

  • 节省服务器所有者的时间和内存,不必处理错误的输入

验证确保用户提供了足够的数据,例如在线购物通常包括地址、电子邮件地址等许多必需的细节,以便完成交易。

有许多方法可以执行表单验证,可以归类为以下几种:

  • 客户端表单验证

  • 服务器端表单验证

客户端表单验证

客户端验证可以在支持 HTML5 属性的浏览器上执行,甚至可以借助 JavaScript 在其他浏览器上执行。与繁琐的 JavaScript 验证相比,HTML5 属性减少了验证的工作量。

客户端表单验证的优点如下:

  • 它通过在客户端快速响应来增强用户体验

  • 在用户填写<form>控件后,验证可以在将表单提交到服务器之前发生

  • 这种方法非常简单,因为它确保用户已经填写了必需的字段,并且填写表单时也会指导用户正确操作

  • 这是一种快速的验证形式,因为它不需要任何服务器端脚本。

客户端表单验证的缺点如下:

  • 它可以在客户端的浏览器中禁用,并且不提供任何安全机制

  • 这种方法无法保护我们的应用程序免受在网络上传输数据时的各种安全问题

  • 客户端验证提供的安全性较低,因为它很容易被篡改或绕过

服务器端表单验证

各种脚本语言,如 PHP、ASP 或 Perl,用于在服务器端对用户提交的数据进行筛选和过滤。

当我们知道某些检查只能在服务器端执行时,就会使用这种方法,因为需要安全性,比如在线购物,用户输入卡片详细信息进行付款。

服务器端表单验证的优点如下:

  • 可以提交有效和完整的信息,而无需进行错误恢复消息和警告。

  • 用户在浏览器中看到的每个页面都会下载到计算机上,其中包括具有验证代码的 JavaScript。因此,黑客可以创建一个新版本的页面,没有任何验证,并且可以通过输入无效数据来愚弄我们的服务器。在这种情况下,服务器端验证是有帮助的。

  • 服务器端验证更安全,不容易被篡改或绕过。

服务器端表单验证的缺点如下:

  • 这种方法需要更多的响应时间,导致用户体验不佳。

  • 服务器端处理代码重新提交页面,以显示错误消息

  • 为了最小化请求-响应生命周期,它同时验证所有表单字段

或多或少,我们都依赖 JavaScript 来验证表单。此外,我们应该始终记住,客户端表单验证不能替代完备的服务器端验证和处理错误。这是一种有效的方式,在客户端为用户输入提供即时反馈。在在线购物的情况下,用户选择了总件数,但在一定限制后,用户看到了超出限制的错误。所有这些验证都需要高端的服务器端验证,这在客户端是不可能的。请记住,在表单的情况下,请使用服务器端验证。

HTML5 表单验证

引入 HTML5 验证的目的是通知用户页面包含一些必填信息,需要填写或使用浏览器内置的处理纠正用户的任何错误。我们应该利用浏览器具有的所有功能和知识,在将表单发送到服务器之前,捕捉表单中的错误。此外,我们不需要担心网络往返的时间和费用,或者从服务器获取关于某些愚蠢错误的响应。

新的<input>属性,如requiredpattern,与 CSS 伪类选择器结合使用,使得编写检查和向用户显示反馈变得更加容易。还有其他高级验证技术,允许您使用 JavaScript 设置自定义有效性规则和消息,或确定元素是否无效以及原因。

在深入了解 HTML5 验证之前,让我们看看使用 JavaScript 执行客户端验证时的区别,以及我们如何使用 HTML5 <form> 控件进行验证。在下面的示例中,我们正在验证一个用户必须填写的简单文本框。

代码 1-使用 JavaScript 验证文本框

以下代码将使用 JavaScript 验证文本框:

<head>
<script>
  function validateField()
  {
    var x=document.forms["Field"]["fname"].value;
    if (x==null || x==""){
      alert("Please enter your name");
      return false;
    }
  }
</script>
</head>
<body>
  <form name="Field" action="#" onsubmit="validateField()"method= "post">
  First name: <input type= "text" name= "fname">
  <input type= "submit" value= "Submit">
</form>
</body>

上述代码的输出将如下截图所示:

代码 1-使用 JavaScript 验证文本框

代码 2-使用 HTML5
控件验证文本框

以下代码将使用 HTML5 验证文本框:

<head>
<script>
</script>
</head>
<body>
  <form name= "Field" action= "#">
  First name: <input type= "text" name= "fname" required>
  <input type= "submit" value= "Submit">
</form>
</body>

上述代码的输出将如下截图所示:

代码 2-使用 HTML5 控件验证文本框

在前两个代码示例中,我们看到第一个代码中的<script>部分被 HTML5 <form>控件的单个属性所取代,这不仅减少了代码行数,还消除了 JavaScript 的范围。

约束验证

浏览器在提交表单时运行的算法称为约束验证。为了约束数据或检查有效性,该算法利用了新的 HTML5 属性,如minmaxsteppatternrequired,以及现有属性,如maxlengthtype

在 HTML5 中,基本约束有两种不同的声明方式:

  • 通过为<input>元素的type属性选择最语义化的值

  • 通过在验证相关属性上设置值,并允许以简单的方式描述基本约束,而无需使用 JavaScript

HTML5 约束验证 API

如今,越来越多的浏览器支持约束验证 API,并且变得越来越可靠。然而,HTML5 约束验证并不能消除服务器端验证的需要。

在高层次上,此 API 涵盖以下功能:

  • 表单字段具有有效性属性

  • 表单字段还有一个通用的checkValidity()方法

  • 最后,还有一个setCustomValidity()方法

validity 对象

validity对象是一组键和布尔值,表示特定表单的有效性。简单来说,我们可以说它告诉了特定表单缺少什么。

让我们以数字字段类型为例来理解这一点。使用数字字段类型,我们可以指定表单字段应该是数字,并且我们可以设置限制;例如,数字应该大于 0 并且小于 25。validity属性实际上可以告诉您值是否不是数字,或者太低或太高。

DOM 节点的validity对象返回一个包含与节点中数据的有效性相关的多个布尔属性的ValidityState对象。在ValidityState对象中,每当我们获取对它的引用时,我们可以保持对它的控制,并且返回的有效性检查将根据需要进行更新,如下面的代码示例所示:

<head>
<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validity.customError;
    var result1=document.getElementById('result1').innerHTML = bool1;
  }
</script>
</head>
<body>
  <input type= "text" id="handbook1">
  <div>
  <label>Result1:</label><output id="result1" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

checkValidity 方法

调用checkValidity方法来检查此方法返回的值,以了解成功和不成功的验证场景。它返回一个布尔值,当不需要知道字段为何无效时,或者在我们深入validity属性之前使用此方法来了解字段为何无效时,我们可以使用此方法。

该方法允许我们在没有用户输入的情况下检查表单的验证。

在用户或脚本代码提交表单时检查表单的验证,但该方法允许在任何时候进行验证,如下面的代码示例所示:

<head>
<script>
  function validateInput(){
    //false
    var bool2=document.getElementById('handbook2').checkValidity(); //true
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
</head>
<body>
  <input type= "text" id="handbook1" required>
  <input type= "text" id="handbook2" value="handbook">
  <div>
  <label>Result1:</label><output id="result1"></output>
  </div>
  <div>
  <label>Result2:</label><output id="result2"></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截图所示:

checkValidity 方法

setCustomValidity()方法

setCustomValidity()方法让我们可以逻辑地决定并创建自定义验证错误消息,并在提交无效输入到表单时显示它。这使我们可以使用 JavaScript 代码来建立除标准约束验证 API 提供的验证失败之外的验证失败。在报告问题时显示消息。

该方法还允许我们设置消息,并默认将字段设置为错误状态。如果参数是空字符串,则自定义错误将被清除或被视为有效。当我们不使用setCustomValidity()方法自定义错误消息时,将显示内置错误消息,如下面的代码示例所示:

<script>
  function check(input){
    if (input.value != document.getElementById('email_addr').value) {
      input.setCustomValidity('Both the email addresses must match.');
    }
    else{
      input.setCustomValidity('');
    }
  }
</script>
<body>
  <form id="myForm">
  <div>
  <label>Enter Email Address:</label>
  <input type="email" id="email_addr" name="email_addr">
  </div>
  <div>
  <label>Repeat Email Address:</label>
  <input type="email" id="email_addr_repeat" name="email_addr_repeat">
  </div>
  <input type="submit" value="Validate" onclick="check(this)">
</form>

上述代码的输出将如下截图所示:

setCustomValidity()方法

willValidate 属性

willValidate属性指示元素是否将根据表单的验证规则和约束进行验证。如果控件上设置了任何约束,例如required属性或pattern属性,willValidate字段将告诉您验证检查将被强制执行。

该属性在表单提交时返回true,如果元素将被验证;否则,它将返回false,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').willValidate; //true
    var bool2=document.getElementById('handbook2').willValidate; //undefined
    var bool3= document.getElementById('handbook3').willValidate; //false
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
    var result3=document.getElementById('result3').innerHTML = bool3;
  }
</script>
<body>
  <input type= "text" id="handbook1" required value= "handbook">
  <div id= "handbook2" type="text">
  <input type= "text" id="handbook3" disabled>
  <div>
  <label>Result1:</label><output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label><output id="result2" ></output>
  </div>
  <div>
  <label>Result3:</label><output id="result3" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截图所示:

willValidate 属性

validationMessage 属性

validationMessage属性允许我们以编程方式查询本地化的错误消息,该控件不满足。如果控件不符合约束验证的条件,或者元素的值满足其约束,validationMessage设置为空字符串。

例如,如果必填字段没有输入,浏览器将向用户呈现其默认错误消息。一旦支持,这就是validationMessage字段返回的文本字符串,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validationMessage;
    var bool2=document.getElementById('handbook2').validationMessage;
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
<body>
  <input type= "text" id="handbook1" required/>
  <input type= "text" id="handbook2" value= "handbook">
  <div>
  <label>Result1:</label><output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label><output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截图所示:

validationMessage 属性

HTML5 为我们提供了多种方式来强制表单的正确性;也就是说,HTML5 为任何给定的<form>控件提供了多种有效性约束。

如前所述,本节讨论了任何给定的<form>控件上的多种有效性约束。

patternMismatch 属性

patternMismatch属性用于在<form>控件上设置任何模式规则,并返回<input>值是否与pattern属性定义的规则匹配。

validity.patternMismatch 属性

  • 如果元素的值不匹配提供的pattern属性,则返回true;否则,返回false

  • 当返回true时,元素将匹配:invalidCSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validity.patternMismatch; //false
    var bool2= document.getElementById('handbook2').validity.patternMismatch; //true
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
<body>
  <input type= "text" id="handbook1" pattern="[0-9]{5}"  value="123456">
  <input type= "text" id="handbook2" pattern="[a-z]{3}"  value="xyz">
  <div>
  <label>Result1:</label>	<output id="result1"></output>
  </div>
  <div>
  <label>Result2:</label>	<output id="result2"></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截屏所示:

validity.patternMismatch 属性

customError 属性

customError 属性用于处理由应用程序代码计算和设置的错误。此属性验证是否设置了自定义错误消息。

它用于调用setCustomValidity()属性将表单控件置于customError状态。

validity.customError 属性

如果元素有自定义错误,则返回true;否则,返回false,如下面的代码示例所示:

<script>
  function validateInput(){
    Var bool1=document.getElementById('handbook1').validity.customError; //false
    var bool2= document.getElementById('handbook2').setCustomValidity('Invalid Message');
    var bool3= document.getElementById('handbook2').validity.customError; //true
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
    var result3=document.getElementById('result3').innerHTML = bool3;
  }
</script>
<body>
  <input type= "text" id="handbook1">
  <input type= "text" id="handbook2">
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <div>
  <label>Result3:</label>  <output id="result3" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截屏所示:

有效性.customError 属性

rangeOverflow 属性

rangeOverflow属性用于通知<form>控件的输入值大于最大值或输入值超出范围。

此属性检查max属性,以确保<form>控件具有最大输入值。

validity.rangeOverflow 属性

  • 如果元素的值高于提供的最大值,则返回true;否则,返回false

  • 当返回true时,元素将匹配:invalid:out-of-rangeCSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validity.rangeOverflow; //false
    var bool2=document.getElementById('handbook2').validity.rangeOverflow; //true
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
<body>
  <input type= "number" id="handbook1" max="3" value="1">
  <input type= "number" id="handbook2" max="3" value="4">
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截屏所示:

有效性.rangeOverflow 属性

rangeUnderflow 属性

rangeUnderflow属性用于通知<form>控件的输入值低于最小值。

此属性检查min属性,以确保<form>控件具有最小输入值。

有效性.rangeUnderflow 属性

  • 如果元素的值低于提供的最小值,则返回true;否则,返回false

  • 当返回true时,元素将匹配:invalid:out-of-rangeCSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validity.rangeUnderflow; //true
    var bool2= document.getElementById('handbook2').validity.rangeUnderflow; //false
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
<body>
  <input type= "number" id="handbook1" min="3" value="1">
  <input type= "number" id="handbook2" min="3" value="4">
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截屏所示:

有效性.rangeUnderflow 属性

stepMismatch 属性

stepMismatch属性确保<input>值符合minmaxstep值的规则或标准。例如,如果步长值为五,输入值为三,则在这种情况下会有步长不匹配。

有效性.stepMismatch 属性

  • 如果元素的值不符合step属性给定的规则,则返回true;否则,返回false

  • 当返回true时,元素将匹配:invalid:out-of-rangeCSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validity.stepMismatch; //true
    var bool2= document.getElementById('handbook2').validity.stepMismatch; //false
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
<body>
  <input type= "number" id="handbook1" step="3" value="1">
  <input type= "number" id="handbook2" step="3" value="6">
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

上述代码的输出将如下截屏所示:

有效性.stepMismatch 属性

tooLong 属性

此属性确保<input>字段不包含太多字符。

我们通过在<form>控件上添加maxlength属性来确保这一点。

validity.tooLong 属性

  • 如果元素的值长于提供的最大长度,则返回true;否则,返回false

  • 当返回true时,元素将匹配:invalid:out-of-range CSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1=  document.getElementById('handbook1').validity.tooLong; //false
    var bool2=    document.getElementById('handbook2').validity.tooLong; //true
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
    }
</script>
<body>
  <input type="text" id="handbook1" maxlength="5" value="12345678"/>
  <input type="text" id="handbook2" maxlength="5" value="xyz"/>
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

先前代码的输出将如下屏幕截图所示:

validity.tooLong 属性

typeMismatch 属性

typeMismatch属性用于通知<input>值与<form>控件不匹配,例如电子邮件、URL 和数字,并确保值的类型与其预期字段匹配。

validity.typeMismatch 属性

  • 如果元素的值不符合正确的语法,则返回true;否则返回false

  • 当返回true时,元素将匹配:invalid CSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validity.typeMismatch; //false
    var bool2= document.getElementById('handbook2').validity.typeMismatch; //true
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
<body>
  <input type="email" id="handbook1" value="handbook@books.com">
  <input type="email" id="handbook2" value="handbook">
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

先前代码的输出将如下屏幕截图所示:

validity.typeMismatch 属性

valueMissing 属性

valueMissing属性确保在<form>控件上设置了一些值。为了确保这一点,将required属性设置为true

validity.valueMissing 属性

  • 如果元素没有值但是必填字段,则返回true;否则返回false

  • 当返回true时,元素将匹配:invalid CSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1=document.getElementById('handbook1').validity.valueMissing; //false
    var bool2= document.getElementById('handbook2').validity.valueMissing; //true
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;
  }
</script>
<body>
  <input type= "text" id="handbook1" required value="handbook">
  <input type= "text" id="handbook2" required value="">
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

先前代码的输出将如下屏幕截图所示:

validity.valueMissing 属性

valid 属性

valid属性用于检查字段是否有效。

validity.valid 属性

  • 如果元素的值没有有效性问题,则返回true;否则返回false

  • 当返回true时,元素将匹配:invalid CSS 伪类,如下面的代码示例所示:

<script>
  function validateInput(){
    var bool1= document.getElementById('handbook1').validity.valid; //true
    var bool2= document.getElementById('handbook2').validity.valid; //false
    var result1=document.getElementById('result1').innerHTML = bool1;
    var result2=document.getElementById('result2').innerHTML = bool2;;
  }
</script>
<body>
  <input type= "text" id="handbook1" required value="handbook">
  <input type= "text" id="handbook2" required value="">
  <div>
  <label>Result1:</label>  <output id="result1" ></output>
  </div>
  <div>
  <label>Result2:</label>  <output id="result2" ></output>
  </div>
  <input type="button" value="Validate" onclick="validateInput()">
</body>

先前代码的输出将如下屏幕截图所示:

validity.valid 属性

以下表格显示了各种属性及其可能的值和相关违规:

属性 支持属性的类型 可能的值 约束描述 相关违规
required 日期、月份、周、复选框、单选按钮、URL、电话、电子邮件、文本、密码、搜索、时间、范围、数字和标签,如<select><textarea>checkboxradiobutton 返回布尔值None;存在时返回true,不存在时返回false 必须填写值 约束违规:缺失
min 数字和范围 必须是有效数字 填写的参数必须大于或等于定义的值 约束违规:下溢
月、日期和周 必须是有效日期
datetime-local、time 和 datetime 必须是有效的日期和时间
maxlength <textarea>等标签和属性为textpasswordsearchtelurlemail 必须是整数长度 属性的值不能大于填写的字符数 约束违规:太长
max 数字和范围 必须是有效数字 填写的参数必须小于或等于定义的值 约束违规:溢出
月、日期和周 必须是有效日期
datetime-local、time 和 datetime 必须是有效的日期和时间
pattern 文本、搜索、URL、电话、电子邮件和密码 它是使用 JavaScript 定义的正则表达式 属性的值必须完全匹配定义的模式 约束违规:模式不匹配
step 必须是整数月数 直到step的值设置为任何文字(在step菜单中可用的值),值将是min值加上step的整数倍 约束违规:步骤不匹配
日期 必须是整数天数
必须是整数周数
日期时间、本地日期时间和时间 必须是整数秒数
数字和范围 必须是整数

错误消息

现在,所有现代浏览器都支持大部分 HTML5 的功能。所有浏览器中功能的功能性是相同的,但也存在一些差异;其中之一就是浏览器显示的默认错误消息。

各种浏览器显示的默认错误消息如下截图所示:

错误消息

但是,我们可以通过setCustomvalidity来更改浏览器的默认错误消息。让我们通过一个例子来理解这一点。

以下代码将把浏览器的默认错误消息更改为自定义消息:

<script>
  function check() 
  {
    varhtmlObject=document.getElementById("input");
    if (!htmlObject.checkValidity()) {
      htmlObject.setCustomValidity('This field is mandatory');
    }
  }
</script>
<body>
  <form id="myForm">
  <input id="input" type="text" required />
  <input type="submit" onclick="check(this)">
  </form>
</body>

上述代码将产生以下输出:

错误消息

总结

在本章中,我们学习了表单验证及其类型。我们还了解了不同类型验证的好处。我们还看到了在表单验证中使用的各种类型和属性。

我们通过构建一个示例代码,看到了 JavaScript 验证和 HTML5 验证之间的区别。

接下来,我们学习了 HTML5 支持的约束验证和各种 API。

最后,我们看到了各种特定于浏览器的默认错误消息,并学习了如何更改浏览器的默认错误消息。

第三章:为表单添加样式

在早期的章节中,我们学习了如何使用 HTML5 构建表单,但是 web 设计师和开发人员使用 CSS3 来为 web 表单赋予丰富和优雅的外观。有了对 CSS3 的基本理解,本章我们将学习如何改善表单的外观和感觉。

在本章中,我们将涵盖以下主题:

  • CSS3 及其模块

  • 为表单添加样式

  • 有效样式表单的指南

用于 web 表单的 CSS3

CSS3 为我们带来了无限的新可能性,并允许样式化更好的 web 表单。CSS3 为我们提供了许多创建表单设计影响的新方法,带来了一些重要的变化。HTML5 引入了有用的新表单元素,如滑块和微调器,以及旧元素,如textboxtextarea,我们可以通过创新和 CSS3 使它们看起来非常酷。使用 CSS3,我们可以将旧的无聊表单变成现代、酷炫和吸引人的表单。

CSS3 完全向后兼容,因此我们不需要更改现有的表单设计。浏览器已经并且将始终支持 CSS2。

CSS3 表单可以分为模块。一些最重要的 CSS3 模块包括:

  • 选择器(带伪选择器)

  • 背景和边框

  • 文本(带文本效果)

  • 字体

  • 渐变

表单的样式始终根据要求和 web 设计师或开发人员的创新而变化。在本章中,我们将研究那些可以为我们的表单添加样式并赋予其丰富和优雅外观的 CSS3 属性。

CSS3 的一些新属性需要供应商前缀,因为它们经常被使用,因为它们帮助浏览器读取代码。一般来说,对于某些属性,如border-radius,在 CSS3 中不再需要使用它们,但当浏览器无法解释代码时,它们会发挥作用。以下是主要浏览器的所有供应商前缀的列表:

  • -moz-:Firefox

  • -webkit-:Safari 和 Chrome 等 WebKit 浏览器

  • -o-:Opera

  • -ms-:Internet Explorer

在我们开始为表单添加样式之前,让我们快速复习一下表单模块,以便更好地理解和为表单添加样式。

选择器和伪选择器

选择器是用于选择要样式化的元素的模式。选择器可以包含一个或多个由组合符分隔的简单选择器。CSS3 选择器模块引入了三个新的属性选择器;它们被分组在子字符串匹配属性选择器的标题下。

这些新选择器如下:

  • [att^=val]:以...开始选择器

  • [att$=val]:以...结尾选择器

  • [att*=val]:包含选择器

这些新选择器中的第一个,我们将称之为“以...开始”选择器,允许选择具有指定属性(例如,超链接的href属性)以指定字符串(例如,http://https://mailto:)开始的元素。

同样,额外的两个新选择器,我们将称之为“以...结尾”和“包含”选择器,允许选择具有指定属性的元素,其中指定的属性要么以指定的字符串结尾,要么包含指定的字符串。

CSS 伪类只是选择器的附加关键字,告诉要选择的元素的特殊状态。例如,当用户悬停在选择器指定的元素上时,:hover将应用样式。伪类和伪元素可以将样式应用于元素,不仅与文档树的内容相关,还与外部因素相关,例如浏览器历史记录,如:visited,以及其内容的状态,例如:checked,在某些表单元素上。

新的伪类如下:

类型 详情
:last-child 用于匹配作为其父元素的最后一个子元素的元素。
:first-child 用于匹配作为其父元素的第一个子元素的元素。
:checked 用于匹配已选中的元素,如单选按钮或复选框。
:first-of-type 用于匹配指定元素类型的第一个子元素。
:last-of-type 用于匹配指定元素类型的最后一个子元素。
:nth-last-of-type(N) 用于匹配指定元素类型的倒数第 N 个子元素。
:only-child 用于匹配其父元素的唯一子元素的元素。
:only-of-type 用于匹配其类型的唯一子元素的元素。
:root 用于匹配文档的根元素。
:empty 用于匹配没有子元素的元素。
:target 用于匹配文档 URL 中标识符的当前活动元素的目标。
:enabled 用于匹配已启用的用户界面元素。
:nth-child(N) 用于匹配父元素的每第 N 个子元素。
:nth-of-type(N) 用于匹配父元素的每第 N 个子元素,从父元素的最后一个开始计数。
:disabled 用于匹配已禁用的用户界面元素。
:not(S) 用于匹配未被指定选择器匹配的元素。
:nth-last-child(N) 在父元素的子元素列表中,用于根据它们的位置匹配元素。

背景

CSS3 包含几个新的背景属性;此外,在 CSS3 中,还对背景的先前属性进行了一些更改;这些更改允许更好地控制背景元素。

添加的新背景属性如下。

背景剪切属性

background-clip属性用于确定背景图像的允许区域。

如果没有背景图像,则此属性仅具有视觉效果,例如当边框具有透明区域或部分不透明区域时;否则,边框会覆盖差异。

语法

background-clip属性的语法如下:

background-clip: no-clip / border-box / padding-box / content-box;

background-clip属性的值如下:

  • border-box:使用此选项,背景延伸到边框的外边缘

  • padding-box:使用此选项,不会在边框下绘制背景

  • content-box:使用此选项,背景在内容框内绘制;只有内容覆盖的区域会被绘制

  • no-clip:这是默认值,与border-box相同

背景原点属性

background-origin属性指定背景图像或颜色相对于background-position属性的定位。

如果背景图像的background-attachment属性为固定,则此属性无效。

语法

以下是background-attachment属性的语法:

background-origin: border-box / padding-box / content-box;

background-attachment属性的值如下:

  • border-box:使用此选项,背景延伸到边框的外边缘

  • padding-box:使用此选项,不会在边框下绘制背景

  • content-box:使用此选项,背景在内容框内绘制

背景大小属性

background-size属性指定背景图像的大小。

如果未指定此属性,则将显示图像的原始大小。

语法

以下是background-size属性的语法:

background-size: length / percentage / cover / contain;

background-size属性的值如下:

  • 长度:指定背景图像的高度和宽度。不允许负值。

  • 百分比:以父元素的百分比来指定背景图像的高度和宽度。

  • cover:指定背景图像尽可能大,以完全覆盖背景区域。

  • contain:指定图像尺寸最大化,使其宽度和高度可以适应内容区域。

除了添加新属性,CSS3 还增强了一些旧的背景属性,如下所示。

background-color 属性

如果元素的背景图像的底层图层不能使用,我们可以指定一个回退颜色,除了指定背景颜色。

我们可以通过在回退颜色之前添加一个斜杠来实现这一点。

background-color: red / blue;

background-repeat 属性

在 CSS2 中,当图像在末尾重复时,图像经常被切断。CSS3 引入了新的属性,我们可以用它来解决这个问题:

  • space:通过在图像瓦片之间使用此属性,等量的空间被应用,直到填满元素

  • round:通过使用此属性,直到图块适合元素,图像被缩小

background-attachment 属性

有了新的可能值 local,我们现在可以在元素内容滚动时设置背景滚动。

这适用于可以滚动的元素。例如:

body{background-image:url('example.gif');background-repeat:no-repeat;background-attachment:fixed;}

注意

CSS3 允许网页设计师和开发人员使用简单的逗号分隔列表来拥有多个背景图像。例如:

background-image: url(abc.png), url(xyz.png);

边框

border 属性允许我们指定元素边框的样式和颜色,并且借助 CSS3,我们已经迈入了下一个级别。

使用 CSS3,我们可以创建圆角边框,添加阴影,并使用图像作为边框,而不需要使用诸如 Photoshop 等各种设计程序。

添加的新边框属性如下。

border-radius 属性

使用 CSS 创建圆角边框从来都不容易。有许多可用的方法,但没有一种方法是直接的。此外,为了正确应用样式,必须同时使用 WebKit 和 Mozilla 的供应商前缀。

border-radius 属性可用于自定义按钮。我们还可以将 border-radius 应用于单个角落。有了这个属性的帮助,我们可以轻松地创建圆角边框。

语法

border-radius 属性的语法如下:

border-radius: 1-4 length / % ;

以下是 border-radius 属性的值:

  • length:定义圆的半径大小

  • %:使用百分比值定义圆的半径大小

box-shadow 属性

box-shadow 属性允许设计师和开发人员轻松创建多个下拉阴影。这些可以是盒子的外部或内部,指定颜色、大小、模糊和偏移的值。

通过简单地声明 box-shadow 一次,我们可以使用 outerinset 版本,用逗号分隔。

语法

box-shadow 属性的语法如下:

box-shadow: h-shadow v-shadow blur spread color inset;

以下显示了 box-shadow 属性的值:

  • inset:将外部(outset)阴影更改为内部阴影

  • <h-shadow><v-shadow>:指定阴影的位置

  • <blur>:这个值越大,模糊越大

  • <spread>:指定阴影的大小

  • <color>:指定阴影的颜色

border-image 属性

border-image 属性有点棘手,但它允许我们创建具有自定义边框的框。有了这个功能,您可以定义一个图像来用作边框,而不是普通的边框。

我们可以使用图像甚至渐变来创建装饰性边框,而不仅仅是简单的圆角。

这个功能实际上分成了几个属性:

  • border-image

  • border-corner-image

语法

border-image 属性的语法如下:

border-image: <source><slice><width><outset><repeat>;

border-image 属性的值如下:

  • source:指定用于边框的图像。

  • slice:指定边框的内部偏移量。

  • width:指定边框的宽度。

  • outset:指定边框图像区域延伸到边框框之外的程度。

  • repeat:指定边框是否应该被拉伸。如果是,那么它是圆形的还是拉伸的。

文本效果

我们已经看到许多具有各种文本效果的网站,它们正在迅速成为良好表单设计的当前和未来趋势。借助 CSS3,这些效果最好的一点是它们可以通过纯 CSS 实现,也就是说,不再需要图像替换和图像密集的设计。在本节中,我们将学习 CSS3 提供的一些新的文本效果。

新的文本特性如下。

text-shadow 属性

text-shadow属性用于对文本内容应用阴影效果。我们可以通过使用一个简单的逗号为单个文本添加一个或多个效果。

这些效果包括阴影颜色、阴影效果的 x/y 偏移和阴影效果的模糊半径。效果可以重叠,但为了清晰起见,它们不应该重叠在文本内容上。

语法

text-shadow属性的语法如下:

text-shadow: <color><offset-x><offset-y><blur-radius>;

word-wrap 属性

word-wrap属性由浏览器用于在单词内部断开行,以防止文本超出边界,否则它将超出边界。它强制文本换行,即使必须在单词中间分割它。

语法

word-wrap属性的语法如下:

word-wrap:break-word / normal;

word-wrap属性的值如下:

  • word-break:允许不可断开的单词被断开

  • normal:仅在允许的断点处断开单词

CSS3 提供的一些新的文本属性如下:

  • hanging-punctuation:指定标点符号字符是否可以放在行框外部

  • punctuation-trim:指定标点符号是否应该被修剪

  • text-align-last:描述块的最后一行或强制换行前的行如何对齐

  • text-emphasis:将强调标记应用于元素的文本,并将前景色应用于强调标记

  • text-justify:当text-alignjustify时,指定使用的对齐方法

  • text-outline:指定文本的轮廓

  • text-overflow:指定文本溢出包含元素时需要采取的操作

  • text-wrap:指定文本的断行规则

  • word-break:对于非 CJK 脚本,指定断行规则

字体

在 CSS2 中,字体模块用于定义文本的大小、行高和粗细,以及其他属性,如样式和系列。

在 CSS 中,我们只能使用计算机上可用的预定义字体系列,但是 CSS3 为我们提供了使用用户定义字体的功能,这些字体可以用于设计网页表单。

@font-face 规则

字体在决定页面或页面特定部分外观方面起着重要作用,这就是网页设计师和公司受益的地方,比如品牌营销。

@font-face属性已经将字体的使用带到了一个新的水平。

这个规则允许用户在网页表单或页面上指定任何真实的字体。更准确地说,这个规则允许从服务器下载特定的字体,并在网页表单或页面中使用它,如果用户尚未安装该特定字体。

语法

@font-face属性的语法如下:

@font-face{
  font-family: <family-name>;
  src: <url>;
  unicode-range: <urange>;
  font-variant: <font-variant>;
  font-feature-settings: normal / <feature-tag-value>;
  font-stretch: <font-stretch>;
  font-weight: <weight>;
  font-style: <style>;
}

字体描述符

CSS3 提供了可以在@font-face规则内定义的新字体描述符。可以使用的各种字体描述符如下。

src 字体描述符

src字体描述符用于定义字体的 URL。

值:URL

font-style 字体描述符

font-style字体描述符用于定义要使用的字体的样式。这是一个可选字段,默认值为normal

值:normalitalicoblique

font-stretch 字体描述符

font-stretch字体描述符用于定义字体应该被拉伸多少。这是一个可选字段,默认值为normal

值:normalcondensedultra-condensedextra-condensedsemi-condensedexpandedsemi-expandedextra-expandedultra-expanded

字体族字体描述符

font-family字体描述符用于定义字体的名称或类型。

值:name

unicode-range 字体描述符

unicode-range字体描述符用于定义字体支持的 Unicode 字符范围。这是一个可选字段,默认值为U+0-10FFFF

值:Unicode-range

字重描述符

font-weight字体描述符用于定义字体的粗细程度。这是一个可选字段,默认值为normal

值:normalbold100200300400500600700800900

渐变

CSS3 的一个令人惊奇的颜色特性是渐变。它们允许颜色之间的平滑过渡。

它们使用background-image属性声明,因为它们没有特殊属性。

渐变允许我们通过将颜色hex转换为rgba模式来创建透明度。

尽管有许多增强功能,但供应商前缀用于使表单与浏览器兼容,以便浏览器可以解释样式。

语法

渐变的语法如下:

linear-gradient (<angle><to [left / right || top / bottom]><color [percentage/length]><color [percentage/length]>)

渐变的值包括以下内容:

  • angle:这指定了渐变的方向角度

  • color:这指定了颜色值,可选的选项是停止位置

样式化表单

快速复习了新的 CSS3 属性后,现在是时候自定义旧的和无聊的表单了。

在第一章中,我们构建了一个健康调查表。我们将重复使用该表单示例来讨论新的 CSS3 以及基本的 CSS 属性以及它们如何在表单中增强创造力。

为了进行样式设置,我们只需取表单的第一部分,即个人信息。经过一些不需要解释的小改动,以下是 HTML 代码:

<form id="masteringhtml5_form">
  <label for="heading" class="heading">Health Survey Form</label>
  <fieldset class="fieldset_border">
    <legend class="legend">Personal Information</legend>
    <div>
      <label for="name">Name</label><br>
      <input  type="text" class="name txtinput" name="name" placeholder="First" autofocus>
      <input  type="text" class="name txtinput" name="name" placeholder="Last">
    </div><br>
    <div class="div_outer_dob">
      <div class="div_dob">
        <label for="dob">Date of Birth</label><br>
        <input type="date" value="date of birth" class="txtinput dateinput">
      </div>
      <div class="gender">
        <label for="gender">Gender</label><br>
        <input type="radio" name="gender"><label>Male</label>
        <input type="radio" name="gender"><label>Female</label>
      </div>
    </div>

    <div class="div_outer_address" >
      <label for="address">Address</label><br>
      <input type="text" class="txtinput textbox address_img" placeholder="Street Address"><br>
      <input type="text" class="txtinput textbox address_img" placeholder="Address Line 2"><br>
      <input type="text" class="txtinput  address_img" placeholder="City">
      <input type="text" class="txtinput  address_img" placeholder="State/Province"><br>
      <input type="text" class="txtinput  address_img" placeholder="Pincode">
      <select class="txtinput select address_img" >
        <option value="Country" class="select"  >Select Country</option>
        <option value="India" class="select"  >India</option>
        <option value="Australia" class="select"  >Australia</option>
      </select>
    </div><br>
    <div>
      <label for="contact">Phone Number</label><br>
      <input type="tel" class="txtinput  home_tel" placeholder="Home">
      <input type="tel" class="txtinput  work_tel" placeholder="Work">
    </div><br>
    <div>
      <label for="email">Email Address</label><br>
      <input type="email" class="txtinput  email" placeholder="email@example.com">
    </div>
    </fieldset>
    <br>

  <div class="submit">
    <input type="submit" class="submit_btn" value="Submit">
  </div>
</form>

由于我们的主要重点是样式,让我们来看看表单的 CSS。以下代码保存在一个带有.css扩展名的单独文件中(外部 CSS 文件),它链接到主 HTML 页面。应该遵循使用单独的 CSS 文件,因为它可以提高代码的可读性,同时也更容易维护样式。

此外,新属性和字体类型以粗体显示:

/* General Form */
html{
  margin: 0px;
  padding: 0px;
  background: #000000;
}
@font-face{
  font-family: 'Conv_azoft-sans-bold-italic';
  src: url('fonts/azoft-sans-bold-italic.eot');
  src: url('fonts/azoft-sans-bold-italic.woff') format('woff'),  
  url('fonts/azoft-sans-bold-italic.ttf') format('truetype'), url('fonts/azoft-sans-bold-italic.svg') format('svg');
  font-weight: normal;
  font-style: normal;
}

body{
  font-size:12px;
  height: 100%; 
  width: 38%;
  padding: 20px;
  margin: 10px auto;
  font-family: Helvetica, Arial, sans-serif;
  color: #000000;
  background: rgba(212,228,239,1);
  background: -moz-linear-gradient(top, rgba(212,228,239,1) 0%, rgba(134,174,204,1) 100%);
  background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(212,228,239,1)), color-stop(100%, rgba(134,174,204,1)));
  background: -webkit-linear-gradient(top, rgba(212,228,239,1) 0%, rgba(134,174,204,1) 100%);
  background: -o-linear-gradient(top, rgba(212,228,239,1) 0%, rgba(134,174,204,1) 100%);
  background: -ms-linear-gradient(top, rgba(212,228,239,1) 0%, rgba(134,174,204,1) 100%);
  background: linear-gradient(to bottom, rgba(212,228,239,1) 0%, rgba(134,174,204,1) 100%);
}

input[type="radio"]{
  cursor:pointer;
}

#masteringhtml5_form .fieldset_border{
  border-color:#ffffff;
  border-style: solid;
}

#masteringhtml5_form .txtinput{ 
  font-family: Helvetica, Arial, sans-serif;
  border-style: solid;
  border-radius: 4px;
  border-width: 1px;
  border-color: #dedede;
  font-size: 18px;
  padding-left: 40px;
  width: 40%;
  color: #777;
  cursor:pointer;
}

#masteringhtml5_form .name{
  background: #fff url('images/user.png')  no-repeat;
}

#masteringhtml5_form  label{
  font-weight:bold;
  font-size:17px;
}

#masteringhtml5_form .legend{
  font-size: 18px;
  font-family: 'Conv_azoft-sans-bold-italic',Helvetica, Arial, sans-serif;
}

#masteringhtml5_form .heading{
  font-size: 24px;
  font-family: 'Conv_azoft-sans-bold-italic',Helvetica, Arial, sans-serif;
}

#masteringhtml5_form .txtinput.textbox{
  width:89%;
}

#masteringhtml5_form .address_img{
  background: #fff url('images/home.png')  no-repeat;
  background-position-y: -5px;
}

#masteringhtml5_form .txtinput.select{
  width:49%;
  color:#777777;
}

#masteringhtml5_form .div_outer_dob{
  width:100%;
}

#masteringhtml5_form .dateinput{
  width:79%;
  background: #fff url('images/date.png')  no-repeat;
  background-position-x: 1px;
  background-size: 29px 29px;
}

#masteringhtml5_form .home_tel{
  background: #fff url('images/tel.png')  no-repeat;
  background-position-x: 1px;
  background-size: 29px 29px;
}

#masteringhtml5_form .work_tel{
  background: #fff url('images/work.png')  no-repeat;
  background-size: 27px 25px;
}

#masteringhtml5_form .email{
  background: #fff url('images/email.png')  no-repeat;
}

#masteringhtml5_form .div_dob{
  width:50%;
  float:left;
}

#masteringhtml5_form .gender{
  width:50%;
  float:left;
}

#masteringhtml5_form .gender span{
  font-size:18px;
}

#masteringhtml5_form .div_outer_address{
  clear:both;
}

.legend{
  font-weight:bold;
  font-size:14px;
}

#masteringhtml5_form .submit{
  text-align:center; 
}

#masteringhtml5_form .submit_btn{
  color:#ffffff;
  cursor:pointer;
  border-radius:5px;
  width: 17%;
  height: 100%;
  font-size: 21px;
  height:100%;
  box-shadow: 5px 5px 10px 5px #888888;
  background: rgb(149,149,149);
  background: -moz-linear-gradient(top,  rgba(149,149,149,1) 0%, rgba(13,13,13,1) 46%, rgba(1,1,1,1) 50%, rgba(10,10,10,1) 53%, rgba(78,78,78,1) 76%, rgba(56,56,56,1) 87%, rgba(27,27,27,1) 100%); 
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(149,149,149,1)), color-stop(46%,rgba(13,13,13,1)), color-stop(50%,rgba(1,1,1,1)), color-stop(53%,rgba(10,10,10,1)), color-stop(76%,rgba(78,78,78,1)), color-stop(87%,rgba(56,56,56,1)), color-stop(100%,rgba(27,27,27,1))); 
  background: -webkit-linear-gradient(top,  rgba(149,149,149,1) 0%,rgba(13,13,13,1) 46%,rgba(1,1,1,1) 50%,rgba(10,10,10,1) 53%,rgba(78,78,78,1) 76%,rgba(56,56,56,1) 87%,rgba(27,27,27,1) 100%); 
  background: -o-linear-gradient(top,  rgba(149,149,149,1) 0%,rgba(13,13,13,1) 46%,rgba(1,1,1,1) 50%,rgba(10,10,10,1) 53%,rgba(78,78,78,1) 76%,rgba(56,56,56,1) 87%,rgba(27,27,27,1) 100%); 
  background: -ms-linear-gradient(top,  rgba(149,149,149,1) 0%,rgba(13,13,13,1) 46%,rgba(1,1,1,1) 50%,rgba(10,10,10,1) 53%,rgba(78,78,78,1) 76%,rgba(56,56,56,1) 87%,rgba(27,27,27,1) 100%); 
  background: linear-gradient(to bottom,  rgba(149,149,149,1) 0%,rgba(13,13,13,1) 46%,rgba(1,1,1,1) 50%,rgba(10,10,10,1) 53%,rgba(78,78,78,1) 76%,rgba(56,56,56,1) 87%,rgba(27,27,27,1) 100%); 
}

前面的 HTML 和 CSS 代码的结果如下:

样式化表单

如果我们将新的 CSS3 表单与我们在第一章中构建的表单的第一部分进行比较,表单及其重要性,我们将看到两种表单的外观和感觉上的差异。

为了更好地比较,在第一章中表单的第一部分,表单及其重要性,如下所示:

样式化表单

现在,我们意识到了 CSS3 的强大之处,使用它我们很容易地将一个简单和无聊的表单转换成时尚和吸引人的东西。

让我们看看表单的 CSS 中使用的各种选择器及其重要性:

  • <body>:应用于<body>标签的 CSS 属性充当回退或默认属性,因为它充当包含其中多个其他标签的父标签。CSS 的回退属性包括font-familyfont-size等。

使用background这样的属性,利用颜色(以 RBG 表示),并结合linear-gradient来设置。linear-gradient是用 RBG 颜色值描述的,从顶部开始,直到底部定义为百分比。它们是为了不同的浏览器支持而描述的,包括-webkit-O-ms等起始值。它显示了表单的蓝色背景。除此之外,还使用了各种其他 CSS 属性,如font-sizeheightwidth

  • headinglegend:对于我们的表单标题(健康调查表)和传奇标题(个人信息),我们实现了一个新的字体类型Conv_azoft-sans-bold-italic,它在headinglegend类中使用@font-face属性定义了font-family属性。

我们导入了字体类型文件.eot.woff.ttf.svg,以支持不同浏览器,使用了@font-face属性。

此外,对于legend标签,我们利用了fieldset_border类来改变边框颜色和样式。

  • dateinputdiv_dob:这两个类都是为了<input>类型date,让用户从下拉日历中选择他/她的出生日期。div_dob类是为了通过使用float属性在屏幕左侧排列元素。除此之外,dateinput类还用于使用backgroundbackground-positionbackground-size属性来放置日期图标,以便正确渲染。

  • txtinputtxtinput类用于样式化表单中使用的文本输入,并且除了使用以前的 CSS 属性,如font-familyborder-style之外,我们还使用了一个名为border-radius的新属性,以使文本输入在所有边上都有圆角边框。

我们还为cursor类型添加了一个属性,作为指针,当鼠标指针移动到输入字段上时显示一个手点击图标。

nameaddress_imghome_telwork_telemaildropdowncalendar类用于为文本输入字段设置背景图像,具体取决于<input>类型。我们利用了背景的各种属性,如backgroundbackground-positionbackground-size,以便正确渲染图标图像。

autofocus属性用于名字文本输入,以便在表单加载时自动聚焦光标。

  • radiobutton<input>类型radio是一个旧的 HTML 输入,这里用于选择性别。我们还使用了float属性来将单选按钮对齐到出生日期的右侧。

我们还为cursor类型添加了一个属性,作为指针,当鼠标指针移动到输入字段上时显示一个手点击图标。

  • submit:为了将表单提交到服务器,我们创建了一个提交按钮。在submit_btn类中,我们使用了以前版本的属性,如颜色、宽度和高度,以及 CSS3 属性,如border-radius来使按钮的所有边都变圆,box-shadowbackground与颜色属性一起使用linear-gradients来提供所需的效果。

我们还为cursor类型添加了一个属性,作为指针,当鼠标指针移动到输入字段上时显示一个手点击图标。

指南

在本节中,我们将看到用于有效样式化表单的 CSS3 指南。

CSS3 的一些最佳实践如下:

  • 尽量避免使用内联样式表。应该使用外部 CSS 文件进行样式设置。

  • 尽可能使用压缩的 CSS 文件,这是一种去除代码中不必要字符以减小文件大小的做法。

  • 使用合并的 CSS 文件。

  • 尽可能避免使用多个声明。

  • 始终考虑渐进增强。

  • 厂商前缀应该被组织和注释得很好。

  • 对于与背景相关的属性,请使用回退。

  • 在使用排版时,不应影响文本的可读性。

  • 启用回退并在每个浏览器中测试表单。

  • 尽量使用高效的 CSS 选择器。

  • 尽量避免使用 CSS 表达式。

  • 指定图像尺寸以提高网页的渲染速度。

  • 使用 CSS 精灵以加快图像的渲染速度。

总结

在本章中,我们学习了 CSS3 的基础知识以及我们可以将 CSS3 分类为表单的模块,例如厂商前缀、渐变和背景。

然后,通过一个代码示例,我们学习了大多数可以用于改善表单外观和感觉的 CSS3 属性的实际实现。

最后,我们学习了有效样式化表单的最佳实践。

第四章:数据库连接

在前几章中,我们学习了表单,比如表单是什么,我们如何验证它们,以及我们如何改进它们的外观和感觉,但是表单有什么用,直到它们存储信息?在本章中,我们将学习如何使用 PHP 和 MySQL 将用户输入的数据存储到数据库中。

在本章中,我们将涵盖以下主题:

  • PHP 是什么

  • MySQL 是什么

  • 欺骗和伪造表单

  • 将表单链接到数据库

PHP

PHP 也被用作通用编程语言,基本上是一种服务器端脚本语言,专门设计用于网页开发。通过 PHP 处理器模块,PHP 代码由 Web 服务器解释,生成网页。

与调用外部文件来处理数据不同,PHP 命令可以直接嵌入到 HTML 代码中。它可以用于独立的图形应用程序,并且可以部署在几乎所有操作系统和平台的大多数 Web 服务器上。

在 PHP 中,所有变量是区分大小写的,但用户定义的函数、类和关键字(如 if、else、while、echo 等)是不区分大小写的。

在服务器上,首先执行 PHP 脚本,然后将 HTML 结果发送回浏览器。

通过 HTML 表单,PHP 轻松操纵用户提交的信息的能力是其受欢迎的原因之一。

要使用 PHP,我们必须执行以下步骤:

  1. 获取支持 PHP 和 MySQL 的 Web 服务器。

  2. 在本章中,我们将使用 WAMP(用于 Windows 操作系统)软件,它会自动安装 Apache 服务器,配置 MySQL 数据库,并安装 PHP 支持应用程序,以便进行简单的维护和配置。

  3. 然后,安装 PHP 和 MySQL。

语法

PHP 文件的默认扩展名是.php,PHP 脚本以<?php开头,以?>结尾。

<?php
  // PHP script
?>

包含一些 PHP 脚本代码,PHP 文件通常包含 HTML 标记。分号用于终止 PHP 语句,我们不需要使用分号来终止 PHP 块的最后一行。

表单处理

$_GET$_POST PHP 超全局变量(在所有范围中始终可用的内置变量)用于收集用户单击提交按钮时提交的表单数据。

GET 方法

GET方法中,表单中的信息对所有人都是可见的;例如,所有变量名和值都显示在 URL 中。此外,使用GET方法对可发送的信息量有限制,这个限制因浏览器而异。

当我们需要将网页加入书签时,这种方法就很有用,因为变量会显示在 URL 中。

我们不能使用GET方法发送敏感数据,比如密码或信用卡信息。

以下代码是一个简单的 HTML 页面:

<html>
<body>
<form action="example.php" method="get">
  Name: <input type="text" name="name"><br>
  Age: <input type="text" name="age"><br>
  <input type="submit">
</form>
</body>
</html>

当用户填写上述表单并单击提交按钮时,表单数据将被发送到名为example.php的 PHP 文件进行处理。表单数据将使用method="get"发送。

example.php文件将类似于以下代码:

<html>
<body>
  Hello! <?php echo $_GET["name"]; ?>!<br>
  You are <?php echo $_GET["age"]; ?> years old.
</body>
</html>

POST 方法

POST方法中,表单中的信息对所有人都是不可见的;例如,在 HTTP 请求的正文中,所有变量名和值都被嵌入。此外,使用POST方法对可发送的信息量没有限制。

当我们需要将网页加入书签时,这种方法就不太有用,因为变量不会显示在 URL 中。

此外,在将文件上传到服务器时,POST方法还支持高级功能,比如支持多部分二进制输入。

我们可以使用POST方法发送敏感数据,比如密码或信用卡信息。

以下代码是一个简单的 HTML 页面:

<html>
<body>
<form action="example.php" method="post">
  Name: <input type="text" name="name"><br>
  Age: <input type="text" name="age"><br>
  <input type="submit">
</form>
</body>
</html>

当用户填写上述表单并单击提交按钮时,表单数据将被发送到名为example.php的 PHP 文件进行处理。表单数据将使用method="post"发送。

example.php文件如下所示:

<html>
<body>
  Hello! <?php echo $_POST["name"]; ?>!<br>
  You are <?php echo $_POST["age"]; ?> years old.
</body>
</html>

GETPOST方法都分别填充$_GET$_POST数组。由于这些是超全局变量,无论作用域如何,它们始终是可访问的,并且可以从任何类、函数或文件中访问,而无需进行任何特殊操作。这些数组描述如下:

  • $_GET: 这是一个变量数组,通过 URL 参数传递给当前脚本

  • $_POST: 这是一个变量数组,通过 HTTP POST 方法传递给当前脚本

注意

POST是发送表单数据的最常用方式,因为有安全方面的考虑。

过滤方法

filter方法通过验证或净化输入字段来过滤数据。当数据源包含未知数据时,如自定义输入或用户提供的输入时,它起着非常重要的作用并且非常有用。

例如,通过 HTML 表单输入的数据,如调查表单和新注册。

有两种主要类型的过滤:

  • 验证

  • 净化

输入数据的过滤是安全问题的主要关注点之一。外部数据包括来自用户、cookies、web 服务数据或数据库查询结果的输入数据。由于所有的 web 表单和应用程序都依赖于外部输入,因此通过过滤输入数据,我们可以确保我们的应用程序从用户那里得到有效的输入。

以下的filter函数可以用来过滤一个变量:

  • filter_var_array(): 获取多个变量,并使用相同或不同的过滤器对它们进行过滤

  • filter_id(): 返回指定过滤器的 ID 号

  • filter_var(): 使用指定的过滤器过滤单个变量

  • filter_input(): 通过名称获取一个输入变量,并可选择地对其进行过滤

  • filter_has_var(): 检查指定输入类型的变量是否存在

  • filter_input_array(): 获取多个输入变量,并使用相同或不同的过滤器对它们进行过滤

  • filter_list(): 返回所有支持的过滤器的列表

在下面的例子中,我们使用filter_var()函数验证一个整数:

<?php
  $int = 'g819';
  if(!filter_var($int, FILTER_VALIDATE_INT))
  {
    echo("Entered integer is invalid");
  }
  else
  {
    echo("Entered integer is valid");
  }
?>

在上面的代码中,使用FILTER_VALIDATE_INT过滤器来过滤变量。由于整数无效,上面代码的输出将是整数无效,但如果我们尝试使用一个整数变量,比如 819,输出将是整数有效

验证用户输入数据

filter方法用于验证用户输入数据。成功时返回值为true,失败时返回值为false

严格的格式规则用于验证 IP 地址、URL、变量或电子邮件类型。

现在,在下面的例子中,我们将验证表单的一个输入字段。在开始之前,我们将首先检查所需输入数据的存在。然后,使用filter_var()函数,我们将验证输入数据。

  <?php
  if(!filter_has_var($_GET"url"l))
  {
    echo("Input type is not present");
  }
  else
  {
  if (!filter_var($_GET["url"l, FILTER_VALIDATE_URL))
  {
    echo "Entered URL is invalid";
  }
  else
  {
    echo "Entered URL is valid";
  }
  }
?>

在上面的例子中,使用GET方法发送了一个输入url。它首先检查GET类型的输入email变量是否存在。当输入变量存在时,它验证 URL。

净化用户输入数据

净化的主要目的是允许或不允许字符串中的指定字符。它始终返回一个字符串值。它不遵循任何数据格式规则。

在下面的例子中,我们将验证表单的一个输入字段。在开始之前,我们将首先检查所需输入数据的存在。然后,使用filter_var()函数,我们将净化输入数据。

<?php
  if(!filter_has_var(($_POST['string'l))
  {
    echo("Input type is not present");
  }
  else
  {
    $string = filter_var($_POST['string'l, FILTER_SANITIZE_STRING);
  }
?>

在上面的例子中,使用POST方法发送了一个输入string。它首先检查POST类型的输入string变量是否存在。当输入变量存在时,它验证字符串。

当用户输入一个坏的输入字符串,比如MasteringååHTML5ååForms,经过净化后,同样的字符串会变成MasteringHTML5Form

FILTER_CALLBACK 过滤器

使用FILTER_CALLBACK过滤器,可以调用用户定义的函数并将其用作过滤器。使用这个方法可以完全控制数据过滤。

与指定选项类似,指定要用于过滤的函数。

我们可以使用现有的 PHP 函数,也可以创建我们自己的用户定义函数。

在下面的例子中,我们将创建一个用户定义的函数,用于将所有的*符号替换为空格:

<?php
  function towhitespace($string)
  {
    return str_replace("*", " ", $string);
  }
  $string = "Converting*To*Whitespace*Characters";
  echo filter_var($string, FILTER_CALLBACK,       
  array("options"=>"towhitespace"));
?>

上述代码的输出是:

![FILTER_CALLBACK 过滤器

在上面的例子中,字符串中的任何位置,无论多少次,所有的*符号都被替换为空格字符。

在上面的代码中,我们首先创建了一个函数,用于将所有的*符号替换为空格。然后,调用filter_var()函数,使用FILTER_CALLBACK过滤器和包含函数的数组。

过滤多个输入

如今,几乎每个网络表单都包含多个输入字段,比如注册页面。当一个表单包含多个输入字段时,为了验证或清理,对每个输入字段调用filter_var()filter_input()函数不仅增加了代码的大小,还增加了复杂性。解决这个问题的方法是使用filter_var_array()filter_input_array()函数。

在下面的例子中,我们将验证表单的两个输入字段。我们将使用filter_var_array()函数来过滤这些变量,并使用POST方法。输入是年龄和电子邮件地址。

<?php
  $filters = array
  (
    "age" => array
    (
      "filter"=>FILTER_VALIDATE_INT,
      "options"=>array
        (
        "min_range"=>1,
        "max_range"=>99
      )
    ),
    "email"=> FILTER_VALIDATE_EMAIL
  );
  $output = filter_var_array($_POST, $filters);

  if (!$output["age"])
  {
    echo("Entered age must be between 1 and 99");
  }
  elseif(!$output["email"])
  {
    echo("Entered email is invalid");
  }
  else
  {
    echo("Entered inputs are valid");
  }
?>

在上面的例子中,输入字段是使用POST方法发送的。在这里,设置了一个包含输入变量名称(如ageemail)的数组。我们还对这些输入变量使用了过滤器。

首先,我们使用filter_var_array()函数和我们设置的数组以POST方法输入变量。然后,我们在$output变量中验证了ageemail变量的无效输入。

filter_input_array()filter_var_array()函数的第二个参数可以是单个过滤器 ID 或数组。当参数是单个过滤器 ID 时,输入数组中的所有值都将被指定的过滤器过滤。

如果参数是一个数组,则必须遵循以下规则:

  • 数组值必须是过滤器 ID 或指定标志、过滤器和选项的数组

  • 必须有一个包含输入变量的关联数组,如emailage输入变量

MySQL

数据库是一个结构化和组织良好的数据集合。每个前端应用程序都需要一个兼容的数据库,作为应用程序的后端。它是为了有效的存储和检索数据而组织的,而不是根据数据的性质或集合或检索方法。将数据库添加到网站提供了动态内容、灵活性和可管理性,以及各种用户交互,如果没有这个,将很难实现。

为了处理相应的数据,数据库管理系统应用程序与用户、其他应用程序和数据库本身进行交互。这个应用程序将作为管理所有数据的后端。有许多著名的数据库管理系统,包括 Microsoft SQL Server、Oracle、Sybase、MySQL、PostgreSQL、SQLite、Microsoft Access、dBASE、FoxPro、IBM 的 DB2、Libre Office Base 和 FileMaker Pro。

PHP 的 MySQL

在使用 PHP 时,MySQL 是最兼容的数据库系统。这个数据库是几乎每个开源 PHP 应用程序的重要组成部分。

MySQL 是以MyMichael Widenius的女儿My的名字命名的,后者是 MySQL 的联合创始人。它由 Oracle Corporation 开发、分发和支持。这是一个免费的、易于下载的开源数据库管理系统。它非常快速、可靠,并支持标准的结构化查询语言SQL)。

SQL 用于从称为数据库的存储区域访问和修改数据或信息。它以快速处理、可靠性和易用性和灵活性而闻名。由 IBM 开发,它是一种类似英语的语言,它以记录组的形式处理数据,而不是一次处理一条记录。以下是 SQL 的一些功能:

  • 存储数据

  • 修改数据

  • 检索数据

  • 删除数据

  • 创建表和其他数据库对象

MySQL 中的数据存储在表中。表是相关数据的集合,所有数据都按列和行排列。在存储信息分类时,数据库非常有用。

MySQL-PHP 连接

在使用任何数据库时,首先出现的问题是“我们如何从数据库中访问数据?”要访问任何数据库,我们首先必须连接到该数据库。

打开到 MySQL 服务器的连接

要建立连接,我们首先必须打开到 MySQL 服务器的连接。在 PHP 中,可以使用mysqli_connect()函数来实现。这个函数返回一个资源,这个资源是指向数据库连接的指针。它也被称为数据库句柄。

mysqli_connect()函数的语法是:

mysqli_connect(server,username,password,dbname);

它支持以下值:

  • 服务器:它可以是 IP 地址或主机名。

  • 密码:这是用于登录的密码,是可选的。

  • 用户名:这是 MySQL 用户名,是可选的。此外,MySQL 可以有多个用户。

  • dbname:这是在执行查询时要使用的默认数据库,是可选的。

例如:

<?php
  $username = "your_name";
  $password = "your_password";
  $hostname = "localhost";
  $dbname = "your_db"; 
  $dbconnect = mysqli_connect($hostname, $username, $password,$dbname)
  //Connects to the database
?>

关闭连接

PHP 将在脚本结束时自动关闭连接。但是如果我们想在结束之前关闭连接,我们可以使用mysqli_close()函数。

例如:

<?php
  mysqli_close($dbhandle);
  //Closes the connection
?>

创建或选择一个数据库

一旦我们成功创建了与数据库的连接,下一步就是创建或选择将与我们的应用程序一起使用的任何数据库。

创建一个数据库

要创建数据库,我们使用CREATE DATABASE语句在 MySQL 中创建数据库表。

例如:

<?php
  $createDB="CREATE DATABASE personal_info";
  //Creates a database with name as "personal_info"

  mysqli_query($createDB)
  //Executes the create database query
?>

选择一个数据库

要选择已经存在的数据库,我们使用MYSQLI_SELECT_DB语句在 MySQL 中选择数据库。

例如:

<?php
  $dbconnect = mysqli_connect("host name", "username", "password", "dbname")
  //Connects to the database

  $dbselected = mysqli_select_db("personal_info",$dbconnect)
  //Selects the database to work with
?>

创建一个表

一旦我们创建或选择了一个数据库,下一步就是在数据库内创建一个表。

CREATE TABLE用于在 MySQL 中创建表。

例如:

<?php
  $createTB="CREATE TABLE TbDummy(
    Firstname VARCHAR(255) NOT NULL,
    Lastname VARCHAR(255) NOT NULL);
  //Creating a table in MySQL with name as "TbDummy"

  mysqli_query($createTB)
  //Executing the create table query
?>

主键

为了增加表的灵活性和可靠性,必须存在主键字段。

一个表由许多记录组成,为了唯一标识每个记录,使用主键。每个记录必须有一个唯一的值,这个唯一的值将作为主键。此外,主键值不能为 null,因为为了定位记录,数据库引擎需要一个值。主键是列的组合,唯一标识记录。

例如:

让我们看一下包含组织中每个员工记录的Employee表:

员工 ID 名字 职位 地点
101 Gaurav Gupta 程序分析师 浦那
102 Gaurav Gupta 程序分析师 浦那

该表包含两条记录,名称、职位和地点相同。员工的唯一员工 ID 号将是Employee表中主键的一个很好的选择。因此,我们将Employee ID列设置为此表的主键。

以下片段是一个示例代码,用于将列定义为主键来创建表:

<?php
  $createDB="CREATE DATABASE DBEmployee";
  //Creates a database with name as "DBEmployee"

  mysqli_query($createDB)
  //Executes the create database query

  $createTB="CREATE TABLE Employee(
    Employee_ID INT NOT NULL,
    Name VARCHAR(255),
    Designation VARCHAR(255),
    Location VARCHAR(255),
    PRIMARY KEY(Employee_ID));
  //Creating a table with name as "Employee" and defining a column "Employee_ID" as a primary key

  mysqli_query($createTB)
  //Executing the create table query
?>

欺骗和伪造表单

如今,每个网站都有一个 HTML 表单供用户完成注册,以便用户可以访问该特定网站。由于互联网犯罪不断增加,我们如何验证完成表单的用户是通过您的网站完成的?因此,有必要知道没有人伪造我们的表单提交。

在我们看到如何保护我们的表单免受欺骗之前,让我们看看如何欺骗一个表单。通过以下两种方式,我们可以改变表单提交:

  • 伪造 HTTP 请求

  • 欺骗提交

伪造 HTTP 请求

我们可以使用 telnet 访问端口 80 来输入我们自己的请求。因此,通过这种方法,我们可以克服为每种类型的攻击生成或修改表单的麻烦,因为它可能只是使用原始 HTTP 来更改表单数据。由于这个原因,我们可以说这种方法比其他方法更复杂。

伪造 HTTP 请求是一种更高级的自动化攻击形式。

在以下示例中,我们要求登录到示例论坛:

  POST /index.php?act=Login&CODE=01&CookieDate=1 HTTP/1.1
  Host: forums.example.com
  Connection: close
  Referrer: http://forums.example.com/
  Cookie: session_id=7819
  Content-Type: application/x-www-form-urlencoded
  Content-Length: 44

  UserName=myname&PassWord=mypass&CookieDate=1

要使用前面提到的请求,您需要更改一些项目,包括:

  • myname更改为我们的用户名

  • mypass更改为我们的密码

  • session_id更改为必要的值

  • Content-Length更改为POST数据的新长度

欺骗提交

假设以下 HTML 表单位于http://sampledomain.com/form.php

<form action="/example.php" method="post">
  <select name="browser">
  <option value="chrome">Chrome</option>
  <option value="firefox">Firefox</option>
  </select>
  <input type="submit">
</form>

我们假设我们将能够引用$_POST['browser'],并且它将具有两个选项chromefirefox中的一个值。现在,如果用户选择chrome,请求将类似于以下内容:

  POST /example.php HTTP/1.1
  Host: sampledomain.com
  Content-Type: application/x-www-form-urlencoded
  Content-Length: 8

  browser=chrome

用户可以将表单从浏览器保存到本地机器(台式机或笔记本电脑),然后打开保存的 HTML 文件并对其进行以下更改:

  • 修改action标签,使其现在具有表单的完整 URL

  • 在表单中删除select标签,并用textarea标签替换它

现在我们的表单将类似于以下代码:

<form action=http://sampledomain.com/example.php method="post">
  <textarea name="myvar"></textarea>
  <input type="submit">
</form>

用户现在可以通过对表单进行这些简单更改来提交任何值$_POST['myvar']。此外,没有办法阻止操纵我们的表单的用户提交意外的表单变量或任何可以通过 HTML 表单实现的内容。

有解决方案可用于防止表单欺骗。从严格的协议角度来看,我们唯一知道的是 HTTP 请求和响应来回传递。没有明确而简洁的方法来确定表单提交是否被欺骗。

通过以下两种方式,我们可以防止表单欺骗,因为它们减少了通过遵循处理数据和表单的一般架构提交的不需要的值的可能性:

  • 共享秘密

  • 设定期望

共享秘密

共享秘密也被称为一次性令牌或哈希。我们创建一个只有服务器和用户知道的秘密。在这方面,实现方式各不相同,但它们共享的特征是对用户透明且难以利用。

其中一种实现方法是,在用户会话中,我们将把秘密存储如下代码所示:

  $secret = md5(uniqid(rand(), true));
  $_SESSION['secret'] = $secret;

现在,它可以作为表单中的隐藏表单变量使用,如下所示:

  <input type="hidden" name="secret" value="<? echo $secret; ?>" />

每次显示表单时,我们都会重新生成这个秘密,以便用户始终具有当前和正确的秘密值。这有助于防止CSRF(跨站点请求伪造)。

打开的页面可以通过比较表单发送的秘密和存储在相应会话变量中的秘密来检查这一点。

进一步进行,我们甚至可以通过限制超时窗口而不是依赖会话超时来增强此方法的安全性,后者可能对您的需求来说太大。

设定期望

具有最佳架构的应用程序总是假设:

  • 我们知道我们正在发送什么:这意味着我们应该跟踪我们在网站上上传的表单,并制定接受表单提交的政策,例如超时、每个用户 ID 的多个表单、多次提交以及不接受我们不期望的表单。这可以使用令牌来实现。

  • 我们知道返回值将是什么:这很重要,因为<select>字段包含某些值,我们可能会得到完全不同的东西,比如 PHP 代码、SQL 或其他内容:

  • 要接受表单为有效,我们必须知道需要返回的字段

  • 我们必须严格限制我们接受的输入值

  • 我们必须始终最小化从表单或外部来源获取数据并直接在数据库查询或应用程序的其他内部部分中使用它

将表单链接到服务器

表单的基本目的是接受用户数据或存储用户数据,可以通过各种方式访问,例如调查、新注册、付款等。因此,在本节中,我们将学习如何将用户的输入数据存储到数据库中。

我们将重用我们在第三章中设计的表单,美化表单

我们将使用phpMyAdmin(用于处理 MySQL 管理的开源工具)将表单数据存储到 MySQL 数据库中。

对于诸如 Linux 之类的操作系统,我们使用 XAMPP 服务器。

以下是在同一 HTML 页面中编写的服务器端脚本代码,但 HTML 文件扩展名.html已更改为.php

<?php
  mysqli_connect("localhost", "root", "");

  mysqli_select_db("DBpersonal_info");
  if(isset($_REQUEST['submit']))
  {
    $errorMessage = "";
    $Gender ="";
    $Firstname=$_POST['Firstname'];
    $Lastname=$_POST['Lastname'];
    $Dob=$_POST['Dob'];
    $Gender=$_POST['Gender'];
    $Saddress=$_POST['Saddress'];
    $City=$_POST['City'];
    $State=$_POST['State'];
    $Pincode=$_POST['Pincode'];
    $Country=$_POST['Country'];
    $Home=$_POST['Home'];
    $Work=$_POST['Work'];
    $Email=$_POST['Email'];
    $Aaddress = $_POST['Aaddress'];

    //Field validation
    if(empty($Firstname)) {
      $errorMessage .= "<li>You forgot to enter a first 
      name!</li>";
    }
    if(empty($Lastname)) {
      $errorMessage .= "<li>You forgot to enter a last 
      name!</li>";
    }
    if(empty($Dob)) {
      $errorMessage .= "<li>You forgot to select a date of 
      birth!</li>";
    }
    if(empty($Gender)) {
      $errorMessage .= "<li>You forgot to select your 
      Gender!</li>";
    }
    if(empty($Saddress)) {
      $errorMessage .= "<li>You forgot to enter street 
      address!</li>";
    }
    if(empty($City)) {
      $errorMessage .= "<li>You forgot to enter city!</li>";
    }
    if(empty($State)) {
      $errorMessage .= "<li>You forgot to enter state!</li>";
    }
    if(empty($Pincode)) {
      $errorMessage .= "<li>You forgot to enter pincode!</li>";
    }
    if(empty($Country)) {
       $errorMessage .= "<li>You forgot to select country!</li>";
    }
    if(empty($Home)) {
       $errorMessage .= "<li>You forgot to enter home phone 
       number!</li>";
    }
    if(empty($Work)) {
      $errorMessage .= "<li>You forgot to enter work phone 
      number!</li>";
    }
    if(empty($Email)) {
      $errorMessage .= "<li>You forgot to enter email id!</li>";
    }

    //Check if the number field is numeric
    if(is_numeric(trim($Pincode)) == false ) {
    $errorMessage .= "<li>Please enter numeric pincode value!</li>";
    }
    if(is_numeric(trim($Home)) == false ) {
      $errorMessage .= "<li>Please enter numeric home phone number!</li>";
    }
    if(is_numeric(trim($Work)) == false ) {
      $errorMessage .= "<li>Please enter numeric workphone number!</li>";
    }

    //Check if the length of field is upto required
    if(strlen($Pincode)!=6) {
      $errorMessage .= "<li>Pincode should be 6 digits only!</li>";
    }
    if(strlen($Work)!=10) {
      $errorMessage .= "<li>Work phone number should be 10 digits 
      only!</li>";
    }

    //Check for valid email format
    if(!filter_var($Email, FILTER_VALIDATE_EMAIL)) {
      $errorMessage .= "<li>You did not enter a invalid 
      email!</li>";
    }
        if ($errorMessage != "" ) {
      echo "<p class='message'>" .$errorMessage. "</p>" ;
    }
    else{  
      //Inserting record in table using INSERT query
      $insertTB="INSERT INTO `personal_info`.`personal`
      (`Firstname`, `Lastname`, `Dob`, `Gender`, `Saddress`, 
      `Aaddress`, `City`, `State`, `Pincode`, `Country`, `Home`,   
      `Work`, `Email`) VALUES ('$Firstname', '$Lastname', '$Dob',  
      '$Gender', '$Saddress', '$Aaddress', '$City', '$State', 
      '$Pincode', '$Country', '$Home', '$Work', '$Email')";

      mysqli_query($insertTB); 
    }
  }
?>

在执行代码之前,我们的先决条件是首先创建和选择一个数据库,然后创建一个表来存储信息。之后,我们对表单输入执行一些验证,最后,我们实现Insert查询以存储用户的输入数据。

以下是用户未输入任何数据并提交表单时显示的错误消息的屏幕截图:

将表单链接到服务器

以下是 HTML 代码。代码保持不变,但我们在<form>标签中添加了method="POST"属性和在<input>类型中添加了name属性:

<form id="masteringhtml5_form" method="POST">
<label for="heading" class="heading">Health Survey Form</label>
  <fieldset class="fieldset_border">
  <legend class="legend">Personal Information</legend>
  <div>
  <label for="name">Name</label><br>
<input type="text" name="Firstname" class="name txtinput" placeholder="First" autofocus>
<input type="text" name="Lastname" class="name txtinput" placeholder="Last">
  </div><br>
  <div class="div_outer_dob">
  <div class="div_dob">
  <label for="dob">Date of Birth</label><br>
<input type="date" name="Dob" value="date of birth" class="txtinput dateinput">
  </div>
  <div class="gender">
  <label for="gender">Gender</label><br>
<input type="radio" name="Gender" value="male"> <span>Male</span>
<input type="radio" name="Gender" value="female"> <span>Female</span>
  </div>
  </div>    
<div class="div_outer_address">
  <label for="address">Address</label><br>
<input type="text" name="Saddress" class="txtinput tb address_img" placeholder="Street Address"><br>
<input type="text" name="Aaddress" class="txtinput tb address_img" placeholder="Address Line 2"><br>
<input type="text" name="City" class="txtinput tb1 address_img" placeholder="City">
<input type="text" name="State" class="txtinput tb1 address_img" placeholder="State/Province"><br>
<input type="text" name="Pincode" class="txtinput tb1 address_img" placeholder="Pincode">
  <select name="Country" class="txtinput select address_img" >
<option value="Country" class="select" >Select Country</option>
  <option value="India" class="select" >India</option>
  <option value="Australia" class="select" >Australia</option>
  </select>
  </div><br>
  <div>
  <label for="contact">Phone Number</label><br>
<input type="tel" name ="Home" class="txtinput tb1 home_tel" placeholder="Home">
<input type="tel" name="Work" class="txtinput tb1 work_tel" placeholder="Work">
  </div><br>
  <div>
  <label for="email">Email Address</label><br>
<input type="email" name="Email" class="txtinput tb1 email" placeholder="email@example.com">
  </div>
  </fieldset><br>
  <div class="submit">
<input type="submit" name="submit" class="submit_btn" value="Submit">
  </div>
</form>

通过点击提交按钮,我们可以将用户重定向到新页面,或在屏幕上显示消息,或简单地在屏幕上写一条消息,确认我们的表单已成功提交。

以下是用户在表单中输入数值后的屏幕截图:

将表单链接到服务器

以下是 MySQL 代码片段:

//Creates database
CREATE DATABASE personal_info

//Creates table
CREATE TABLE personal(
Firstname VARCHAR(255) NOT NULL,
Lastname VARCHAR(255) NOT NULL,
Dob VARCHAR(255) NOT NULL,
Gender VARCHAR(255) NOT NULL,
Saddress VARCHAR(255) NOT NULL,
Aaddress VARCHAR(255) NOT NULL,
City VARCHAR(255) NOT NULL,
State VARCHAR(255) NOT NULL,
Pincode INT(11) NOT NULL,
Country VARCHAR(255) NOT NULL,
Home VARCHAR(255) NOT NULL,
Work VARCHAR(255) NOT NULL,
Email VARCHAR(255) NOT NULL)

在上述代码中,首先我们创建了一个数据库,然后创建了一个表来存储用户的输入数据。

以下是点击提交按钮后存储在数据库中的数值的屏幕截图:

将表单链接到服务器

总结

在本章中,我们学习了如何将数据存储到数据库中。我们还学习了用于存储用户输入数据的 PHP 和 MySQL 的基础知识。我们还了解了一些欺骗表单的方法以及如何防止表单的欺骗。

然后,借助一些代码,我们学习了通过重用我们在早期章节中构建的示例来存储表单数据的实际实现。

第五章:响应式网页表单

在之前的章节中,我们了解了表单:表单是什么,我们如何验证它们,我们如何改善表单的外观和感觉,以及如何将通过表单收集的信息存储到数据库中。但是,随着技术的提升,不同分辨率的不同设备需要不同的布局。因此,在本章中,我们将学习如何使我们的表单具有响应性。

在本章中,我们将涵盖以下主题:

  • 什么是响应式设计

  • 什么是媒体查询

  • 什么是流体网格

  • 如何使我们的表单具有响应性

  • 使响应式表单更有效的指南

响应式设计

响应式设计这个术语是由作家和网页设计师 Ethan Marcotte 在 2010 年 5 月的一篇名为《响应式网页设计》的文章中引入的,该文章发表在《A List Apart》上。

基本上,响应式设计意味着内容如何显示在各种屏幕上,如手机、平板电脑或桌面上。响应式设计是一种方法,通过该方法,网站或特定页面会根据特定的屏幕分辨率动态调整自身,以提供最佳的用户体验。它确保了良好的用户体验,因为它可以独立地在各种设备和分辨率上运行。

使用流体、比例为基础的网格、灵活的图片和 CSS3 媒体查询,使用响应式网页设计设计的网站会自动调整布局以适应特定设备的分辨率。

网页设计曾经是简单的。网页设计师会为最流行的桌面屏幕尺寸设计,创建一个适用于大多数设备的单个布局,这使我们可以轻松地将设计分成各种网格,以便我们可以拥有一个布局良好、连贯和和谐的页面。

但随着技术的提升和各种设备的推出,如智能手机、平板电脑,甚至迷你笔记本电脑,网页布局和设计的整体体验发生了变化。

Web 的变化也改变了人们使用互联网的方式。在早期的网页设计方法中,很难在移动设备上使用互联网,因为专为桌面设计的特定网站需要滚动并且需要放大或缩小以阅读文本,浪费时间。例如,在桌面上查看的页面可能具有基于文本的紧凑链接,难以点击。但是通过响应式设计,我们可以利用 HTML5 和 CSS3 的可用功能和能力来解决这些问题。

如果该网站或页面是响应式的,文本将更大,所有内容将适合屏幕,并且导航将经过移动优化。

响应式网页设计中的断点是具有媒体查询声明的浏览器宽度,一旦达到声明的范围,就会改变网站或网页的布局。

谷歌对响应式设计的看法

谷歌建议构建智能手机优化的网站,并支持以下三种配置:

  • 设计为响应式的网站为所有设备提供相同的 URL,每个 URL 向所有设备呈现相同的 HTML,并只利用 CSS 来更改页面在设备上的呈现方式

  • 这些网站动态为所有设备提供相同的 URL,但每个 URL 根据用户代理是桌面还是移动设备提供不同的 HTML(和 CSS)。

  • 有些网站有单独的移动和桌面 URL

使用响应式设计的好处

使用响应式设计网站的一些好处如下:

  • 对于特定内容使用单个 URL 使用户更容易与内容交互,分享和链接。

  • 与为桌面和移动设备开发和维护多个网站不同,我们只需要一个网站来开发和维护,适用于所有类型的设备。

  • 由于不需要重定向即可获得设备优化的视图,加载时间减少。此外,基于用户代理的重定向可能会降低网站的用户体验,并且更容易出现错误。

  • 它是未来友好的;这意味着它允许我们适应新技术,并随着时间的推移逐渐增强我们的网站。

除了改变布局,响应式设计还有很多其他方面。我们可以超越设备的视图大小,可以专注于设备的功能或能力。在某些情况下,我们的网站使用悬停功能,但我们需要为不支持悬停功能的触摸屏设备更改它,我们可以为不同的图像服务或在更改屏幕分辨率时裁剪图像。此外,我们还可以检查设备的位置是否可追踪,或者设备是否在互联网上工作,或者 WIFI,等等。

响应式设计如何工作

网页布局取决于或者我们可以说是由以下网络语言抽象地控制:

  • HTML

  • CSS

  • JavaScript

HTML 描述内容是什么,CSS 负责内容的外观,而使用 JavaScript 我们可以做一些非常酷的事情,比如回退机制。网站被设计为适用于各种屏幕尺寸和设备,根据条件自适应和改变自身,采用内容优先的方法。这是通过使用媒体查询实现的,它允许我们拥有特定的 CSS,用于根据我们的需要定制布局。我们将在本章后面讨论媒体查询。

屏幕分辨率

不同的设备在横向和纵向模式下具有不同的屏幕分辨率。以下是一些设备和设备支持的横向和纵向视图的屏幕分辨率:

设备 纵向视图 横向视图
iPhone 3G/3GS 320 x 480 480 x 320
三星 Galaxy S Duos 480 x 800 800 x 480
iPhone 4 640 x 960 960 x 640
iPad 768 x 1024 1024 x 768
设备 分辨率
--- ---
大多数上网本 1024 x 600
MacBook Air 08 1280 x 800
一些笔记本电脑 1366 x 768
MacBook Pro 15" 1440 x 900

除了这些分辨率,今天的最新设备,如三星 Galaxy S4 或 iPhone 5,在移动设备领域具有非常高的分辨率。

视口

元数据是关于数据的数据(信息)。<meta> 标签提供了关于 HTML 文档的元数据。元数据不会显示在页面上,但可以被机器解析。

元素通常用于指定页面描述、关键词、文档最后修改的作者以及其他元数据。

元数据可以被浏览器(如何显示内容或重新加载页面)、搜索引擎(关键词)或其他网络服务使用。

对于响应式设计,在移动设备上设置视口宽度和初始缩放,通常使用以下 <meta> 标签。尽管是响应式设计,但在我们最终确定适合或重新启动的方法之前,我们也可以在非响应式设计中使用此标签。事实上,如果我们正在构建一个响应式网站或任何移动网站,我们仍然需要以下标签:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

媒体查询

媒体查询是 CSS3 模块,允许内容适应各种屏幕分辨率,如智能手机、平板电脑和高清屏幕。

为了为不同的设备提供不同的样式,媒体查询是实现这一目标的绝佳方式,为每种类型的用户提供最佳体验。作为 CSS3 规范的一部分,媒体查询扩展了控制样式应用方式的 media 属性的作用。

媒体查询由一个或多个表达式和涉及导致真或假的特征的媒体类型组成。此外,当媒体查询为真时,将应用相关的样式表或样式规则,遵循常规的级联规则。

以下片段是一个非常简单的例子,当设备宽度大于 500 像素时适用:

@media screen and (min-width: 500px)
{
  /* some css here */
}

媒体类型

media属性的值指定了链接文档(外部 CSS)将应用的设备。在 HTML 文档的头部使用<link>元素内的media属性,可以声明媒体类型。在 XML 处理指令中,可以声明媒体类型,并且可以使用@import at-rule 和@media at-rule。

CSS2 定义的其他媒体类型包括:

  • projection:用于投影演示,如幻灯片

  • embossed:用于盲文打印机

  • all:用于所有媒体类型设备

  • aural:用于声音和语音合成器

  • tv:用于电视类型设备

  • screen:用于计算机屏幕

  • braille:用于盲文触觉反馈设备

  • handheld:用于手持设备或小型设备

  • print:用于打印机

  • tty:用于使用固定间距字符网格的媒体,如电传打印机和终端

样式表的一个重要特性是它们指定了文档在不同媒体上的呈现方式,比如在纸上、屏幕上使用语音合成器,或者在盲文设备上。

我们可以根据页面视图所使用的媒介应用不同的样式。借助media属性,可以将内部和外部样式表与媒体类型关联起来。

内部媒体查询

这些查询是在 HTML 页面内的<style>标签中编写的。

内部媒体查询的优点如下:

  • 不需要额外的 HTTP 请求

  • 在更新旧文件时保持可见且不被遗忘

内部媒体查询的缺点如下:

  • 如果用户需要下载,文件大小会增加

  • 为了使其在较旧版本的 Internet Explorer 浏览器中工作,我们必须使用 JavaScript

语法

内部媒体查询的语法如下:

body{
  background: blue;
}

@media screen and (max-width: 480px){
  body{
    background: black;
  }
}

最初,它将背景颜色设置为蓝色。但在最大宽度为 480 像素时,它将背景颜色设置为黑色,覆盖了 CSS 样式。

外部媒体查询

这些查询是在单独的文件或外部 CSS 文件中编写和维护的。

外部媒体查询的优点如下:

  • 这在广泛使用时很容易保持和维护 CSS

  • 使用条件注释,可以在旧版本的 Internet Explorer 中使用外部媒体查询

  • 对于不支持的浏览器,文件大小较小

外部媒体查询的缺点如下:

  • 需要额外的 HTTP 请求来应用它

  • 在更新旧文件时很容易被忘记

扩展链接元素或@import规则的现有媒体部分:

<link href="example.css" rel="stylesheet" media="only screen and (max-width:480px)">
@import url(example.css) only screen and (max-width:480px);

媒体特性

媒体特性在语法上类似于 CSS 属性,因为它们有名称并接受某些值,或者我们可以说它们是我们可以自定义响应式设计的条件。

以下表格列出了一些媒体特性:

特征 接受最小/最大前缀 描述
device-width 长度 无论浏览器窗口的宽度如何,这确定了设备整个屏幕的宽度。
device-height 长度 这确定了设备屏幕的高度。
orientation 纵向或横向 这确定了设备的方向。两种方向模式是横向和纵向。
width 长度 这确定了可显示区域的宽度。在大多数移动浏览器中保持不变,因为无法调整浏览器大小,但在台式电脑上,当用户调整浏览器大小时,宽度会改变。
height 长度 这确定了显示区域的高度。
grid 1 或 0 这检测输出设备是位图还是网格。基于网格的设备返回值为 1,所有其他设备返回值为 0。
device-aspect-ratio 比率 这确定了device-width媒体与device-height媒体的值的比率。
resolution 分辨率 这确定了像素密度或输出设备的分辨率。
color 整数 这确定了设备每个颜色分量的位数。当设备不是彩色设备时,该值为零。
color-index 整数 在输出设备的颜色查找表中,这确定了条目的数量。
monochrome 整数 这确定了单色帧缓冲区中每像素的位数。对于非单色设备,该值为0
aspect-ratio 比率 这确定了width媒体与height媒体的值的比率。
scan 逐行或隔行 逐行或隔行,这确定了电视的扫描过程。

不同的屏幕分辨率

在这个特定的部分,我们将专注于设置一般和特定设备屏幕分辨率的最小或最大宽度的语法。我们还将讨论设备的方向。

我们无法使用 CSS 设置浏览器的屏幕分辨率。

小屏幕设备

我们可以使用以下代码来处理最大设备宽度为 480 像素的小屏幕设备:

@media screen and (max-device-width: 480px)
{
  /* some CSS here */
}

媒体查询中的任何 CSS 都将应用于宽度为 480 像素或更小的设备。使用max-device-width而不是device-width的目的是,device-width指的是设备的宽度,但不指的是显示区域的宽度。在我们可以改变分辨率的浏览器中,如果用户调整大小,分辨率可以改变,因此我们使用了max-device-width

除非屏幕分辨率或浏览器大小(在可以更改浏览器大小的情况下)为 480 像素或更小,否则媒体查询不会生效,这基本上为我们留下了移动设备。

苹果移动设备的高分辨率显示

苹果推出了 iPhone 5 和 iPad 3 等设备。在早期的设备中,如 iPhone 4 和 4S,他们引入了视网膜显示的概念。在视网膜显示中,设备的屏幕分辨率加倍。苹果支持一个名为-webkit-device-pixel-ratio的专有属性,返回设备的像素密度。因此,该设备返回值为2

针对高分辨率设备

我们可以使用以下代码来处理通用的苹果设备高分辨率:

@media screen and (-webkit-min-device-pixel-ratio: 1.5)
{
  /* some css here */
}

针对小屏幕高分辨率设备

我们可以使用以下代码来处理小屏幕高分辨率设备,如 iPhone 4:

@media screen and (-webkit-min-device-pixel-ratio: 2) and (max-device-width: 480px)
{
  /* some css here */
}

针对大屏幕高分辨率设备

我们可以使用以下代码来处理大屏幕高分辨率设备,如 iPad 3:

@media screen and (-webkit-min-device-pixel-ratio: 2) and (min-device-width: 768px)
{
  /* some css here */
}

由于高分辨率,图像是最受欢迎的选择,可以针对视网膜显示进行优化,根据设备的不同,我们可以提供图像的两个不同版本。对于视网膜显示,我们将原始图像的尺寸和分辨率加倍,但在使用此图像时,我们对其尺寸施加约束,使其与原始图像的尺寸相同,并允许视网膜设备显示每个像素的两个像素,结果得到了一个超清晰的图像。

以下代码是背景图片的示例:

normal background for the browsers:

div#featuredbox{
  width: 80%;
  height: 350px;
  background: url(normal_background.jpg) center no-repeat;
}

retina devices with larger screens:

@media screen and (-webkit-min-device-pixel-ratio: 2) and (min-device-width: 768px){
div#featuredbox{
  -webkit-background-size: 50% auto;
  background: url(highresolution_background.jpg) center no-repeat; 
  }
}

在上面的示例中,-webkit-background-size: 50% auto;将图像缩小了实际尺寸的 50%,与原始图像的尺寸相匹配。background: url(highresolution_background.jpg) center no-repeat;是高分辨率图像,它将原始图像的尺寸或分辨率加倍。

横向和纵向模式的设备

除了处理屏幕尺寸,处理媒体查询之前设备的方向是棘手的,但是媒体查询的引入简化了开发人员的生活:

@media screen and (orientation: portrait)
{
  /* some CSS here */
}

前面的代码将针对所有屏幕高度大于宽度的设备。在用户可能使用方向很重要的小屏设备的情况下更进一步。

仅限纵向模式的小屏设备

我们可以使用以下代码来适应最大宽度为 480 像素分辨率的纵向模式屏幕:

@media screen and (max-device-width: 480px)and (orientation: portrait)
{
  /* some CSS here */
}

仅限横向模式的小屏设备

我们可以使用以下代码来适应最大宽度为 640 像素分辨率的横向模式屏幕:

@media screen and (max-device-width: 640px) and (orientation: landscape)
{
  /* some CSS here */
}

在响应式网页设计的技术支柱中,媒体查询是最成熟和支持最好的。此外,它们从设计的角度提供了可靠的回报,并且可以应用于现有应用程序以产生良好的效果。

流体网格

流体是一种在受到剪切应力时不断改变其形状和形式的物质。

在网页设计方面,流体指的是我们根据屏幕分辨率进行调整的设计,而剪切应力则指流体组件根据屏幕分辨率进行调整。流体设计中的组件会根据环境或屏幕分辨率进行调整和流动。

对于响应式设计,我们可以说这是一种元素的组合,其中一个是流体网格,另一个是使用媒体查询根据屏幕尺寸和类型加载 CSS;所以我们可以说流体网格本身并不完全是响应式设计。

为了保持布局清晰,并且可以轻松地将网格划分为特定数量的列,流体网格中定义了最大布局尺寸。每个网格内的元素都是按比例宽度和高度设计的,以便根据父容器进行调整。当屏幕尺寸改变时,元素将根据其所在的容器调整宽度和高度。

由于流体网格随着尺寸变化自然流动,我们必须对不同的屏幕尺寸和设备类型进行有限的调整。而在自适应网格的情况下,我们必须定义明确的基于像素的尺寸,并且必须在设备视口中手动调整元素的高度和宽度。在流体网格中,我们可以调整max-width,这非常重要,因为现在的移动设备更加强大,所以一个人可能会花费大部分时间使用移动设备执行各种任务。

流体网格生成器

流体网格并不容易,从头开始创建它们需要付出努力和时间,是一项繁琐的任务。由于大多数网格框架都具有先进的内置功能,并且已经在各种主要浏览器中进行了测试,因此明智的选择是选择现有的 CSS 网格框架或网格生成器作为我们布局创建和设计的基础。我们可以使用的一些 CSS 网格系统和生成器包括:

  • 流体网格系统

  • 微型流体网格

  • 通过计算器的流体网格

  • 通过 bootstrap 的流体网格

当我们有一个 CSS 框架时,创建具有流体列的网格很容易,但并非所有设计都会直截了当。我们可能需要在其他列和行内创建列和行。嵌套列是包含在父列中的列。

960 网格系统

从桌面作为主要焦点开始,960 网格系统是由Nathan Smith设计的,如果你正在寻找桌面解决方案,它是相当不错的。Smith 最近也努力将框架移植到移动设备上。

该系统提供了一个工具,包括用于处理快速原型设计和发布的 CSS 和 JavaScript 文件,以及许多流行设计环境的模板,如 Omnigraffle、Fireworks、Balsamiq 和 Photoshop,以便为桌面和移动设备提供一个单一的解决方案。

960 网格系统对细节的关注已经激发了弹性和流体变体,主题以及适应我们自己的 CSS 偏好的系统。因此,我们可以说,通过这个系统,我们可以设置我们喜欢的列数,列宽和间距宽度,同时享受 960 网格系统社区的好处。

960 网格系统的优点如下:

  • 创建者还发布了其他基于 960 的解决方案,这简化了其集成

  • 它具有用于自定义 CSS 的自定义 CSS 生成器

  • 960 网格系统有很多列配置,因为它有很多除数——28 及以上

960 网格系统的缺点如下:

  • 它包含比其他解决方案更多的标记

  • 与其他解决方案相比,它的 CSS 文件大小更大

  • 它包含非语义类名

Bootstrap

Bootstrap 是一个 HTML,CSS 和 JavaScript 框架,可用作创建网站或 Web 应用程序的基础。如果您今天从事 Web 开发,您一定听说过 Twitter 和 GitHub,所以当您听说一个在 Twitter 开始生活并且是 GitHub 上最受欢迎的存储库的框架时——甚至超过了 jQuery 和 Node.js——您会对 Bootstrap 所带来的病毒式传播有所了解。换句话说,它是一个流畅,直观和强大的前端框架,可加快和简化 Web 开发。

简而言之,它代表了响应式网页设计背后的驱动力,使开发人员能够快速发布将用户需求置于首位的应用程序。

由于其响应特性足够强大,可以独立存在,Bootstrap 及其组件库是最佳解决方案之一。我们可以利用流体嵌套和偏移,这有助于使该框架脱颖而出。虽然我们会避免利用许多开发人员采用 Bootstrap 的组件样式,但网格的轻松实现会让您渴望探索框架的其他特性。

Bootstrap 的优点如下:

  • 它可以完全定制,包括我们需要使用的功能

  • 它已经经过开发人员的严格测试

  • Bootstrap 很受欢迎,这意味着开发人员熟悉它

  • 它可以帮助在短时间内在网络上做出令人惊叹的事情

Bootstrap 的缺点如下:

  • 它包含比其他解决方案更多的标记

  • 与其他解决方案相比,它的 CSS 文件大小更大

  • 它包含非语义类名

但使用响应式 CSS 框架并不会使我们的设计响应式,而且响应式设计并不那么简单。除非我们仔细规划设计,用户在使用流体网格时在较小的设备上浏览内容时总会遇到问题。

为了实现完美的响应式设计,我们不能依赖流体网格,但我们可以根据设计需要调整流体网格,以为用户提供最佳的浏览体验。

自适应图片

自适应图片根据客户端自适应加载不同类型的图片。它们检测用户的设备屏幕大小,并自动创建缓存并传递适当类型的 HTML 网页图像。它们的基本目的是用于响应式设计,并与流体图像技术结合使用。这是因为我们的网站不仅在较小的设备上查看,而且在速度较慢且带宽较低的设备上查看。因此,特别是在这些设备上,我们的基于桌面的图像加载速度较慢,这会导致更多的用户带宽,增加成本,并且用户界面的渲染需要时间。所有这些问题都可以通过自适应图片来解决。

自适应图片遵循相同的语义和结构模型,用于<img><audio><video>元素。此外,<source>元素应该有支持 CSS3 媒体查询的media属性,这些查询会在给定设备上呈现相应的元素。

例如:

<imgsrc="img/header.png" width="480" height="240" alt="head" media= "handheld and (max-device-width: 480px)">
<source src= "header.png" type="image/png" media= "screen and (max-device-width: 800px)">
<source src= "header.png" type="image/png" media="screen and (max-device-width: 1600px)">
</img>

特点

自适应图片的一些特点如下:

  • 它不需要标记更改

  • 它可以轻松配置或定制

  • 它可以很好地与任何 CMS 一起使用,也可以在没有 CMS 的情况下使用

  • 它可以轻松地在我们现有的网站上使用

  • 它遵循先移动设备的哲学,这意味着首先覆盖移动设备的设计,然后是更大的屏幕。

  • 它可以在几分钟内启动和运行

它是如何工作的

使用自适应图像的步骤如下:

  1. .htaccessadaptive-images.php文件添加到document-root文件夹中。

  2. 我们可以从github.com/mattwilcox/Adaptive-Images下载这些文件。

  3. 将 JavaScript 添加到网页的<head>中。以下是需要复制的 JavaScript:

<script>
document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';
</script>
  1. 对于苹果设备的视网膜显示屏,我们可以使用以下行:
<script>
document.cookie='resolution='+Math.max(screen.width,screen.height)+("devicePixelRatio" in window ? ","+devicePixelRatio : ",1")+'; path=/';
</script>
  1. 在 PHP 文件中向$resolutions添加 CSS 媒体查询值。

定制

我们还可以通过查看 PHP 文件(adaptive-images.php)顶部的配置部分来更改默认值。以下要点可以相应地进行自定义:

  • 我们可以设置断点以匹配 CSS 媒体查询

  • 我们可以更改ai-cache文件夹的名称和位置

  • 我们可以更改保存的任何生成的 JPG 图像的质量

  • 我们可以设置浏览器缓存图像的时间

  • 为了保持细节,我们可以锐化重新缩放的图像

使我们的表单响应

在前几章中,从表单的基础知识中,我们学习了如何样式化,验证和将我们的表单与数据库链接。在本节中,我们将学习如何使我们的表单响应。

我们将重复使用之前样式化的表单,并将看到新的技术,以使我们的表单响应。

HTML 代码保持不变,只是将以下链接添加到 HTML 页面的<head>标签中。

以下第一行提到的是视口<meta>标签:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

第二行是外部媒体查询(例如解释)。该代码保存在一个单独的文件中,但媒体查询是写在<head>标签中的。

下面提到的 CSS 文件将被包含,并在设备屏幕分辨率宽度低于或等于 520 像素时生效,但一旦设备分辨率超过 520 像素宽度,媒体查询就不再生效。

在样式中,我们将输入文本元素的宽度设置为 85%。我们还清除了标有性别类的表单元素单选按钮的值为 none。对提交按钮的样式进行了调整,字体大小设置为 15 像素,并将宽度增加到 23%。出生日期的类div_dob也被清除为 none,以便按顺序排列在同一行上。

<link rel='stylesheet' media='screen and (max-width: 520px)' href='Css/Internal_MediaQuery.css' />

以下是 CSS 中的代码:

#masteringhtml5_form .txtinput.textbox{
  width: 85%;
}
#masteringhtml5_form .txtinput{
  width: 85%;
}
#masteringhtml5_form .gender{
  float:none;
}
#masteringhtml5_form .gender span{
  font-size: 14px;
}
#masteringhtml5_form .txtinput.select{
  width: 97%;
}
#masteringhtml5_form .submit_btn{
  font-size:15px;
  width:23%;
  padding-top: 3px;
  padding-bottom: 3px;
}
#masteringhtml5_form .div_dob{
  width: 100%;
  float:none;
}

前面的 CSS 代码已经在第三章中解释过了,但这里重要的一点是内部媒体查询,使我们的表单对小屏幕设备响应。

第三行是链接到主 HTML 页面的外部媒体查询文件:

<link href="Css/External_MediaQuery.css" rel="stylesheet" />

以下片段是保存在单独文件中的 CSS 代码:

@media screen and (min-width: 1169px) and (max-width: 1255px){
  #masteringhtml5_form .txtinput{
    width:45.7%;
  }
  #masteringhtml5_form .dateinput{
    width: 90%;
  }
}

@media screen and (min-width: 957px) and (max-width: 1170px){
  #masteringhtml5_form .txtinput{
    width:44.7%;
  }
  #masteringhtml5_form .dateinput{
    width: 90%;
  }
#masteringhtml5_form .txtinput.textbox{
    width: 94%;
  }
}

@media screen and (min-width: 811px) and (max-width: 958px){
  #masteringhtml5_form .txtinput{
    width:43.7%;
  }
  #masteringhtml5_form .txtinput.textbox{
    width: 93.7%;
  }
  #masteringhtml5_form .dateinput{
    width: 88%;
  }
}

@media screen and (min-width: 707px) and (max-width: 812px){
  #masteringhtml5_form .txtinput{
    width:42.7%;
  }
  #masteringhtml5_form .txtinput.textbox{
    width: 92.7%;
  }
  #masteringhtml5_form .dateinput{
    width: 88%;
  }
}

@media screen and (min-width: 624px) and (max-width: 708px){
  #masteringhtml5_form .txtinput{
    width:41.7%;
  }
  #masteringhtml5_form .txtinput.textbox{
    width: 92%;
  }
  #masteringhtml5_form .dateinput{
    width: 86%;
  }
}

@media screen and (min-width: 567px) and (max-width: 625px){
  #masteringhtml5_form .txtinput{
    width:40.7%;
  }
  #masteringhtml5_form .txtinput.textbox{
    width: 90%;
  }
  #masteringhtml5_form .dateinput{
    width: 84%;
  }
}

@media screen and (min-width: 521px) and (max-width: 568px){
  #masteringhtml5_form .txtinput{
    width:39.7%;
  }
  #masteringhtml5_form .txtinput.select{
    width: 48.7%;
  }
  #masteringhtml5_form .txtinput.textbox{
    width: 90%;
  }
  #masteringhtml5_form .dateinput{
    width: 84%;
  }
}

在前面的代码中,媒体查询应用于具有特定最小屏幕宽度和特定最大屏幕宽度的屏幕类型。我们已经覆盖了txtinputselectdateinput类的宽度,这些类根据屏幕分辨率进行调整。元素会根据特定的屏幕分辨率重新流动和调整。

以下截图是我们制作的响应式表单。这个响应式表单对 Web 浏览器(更改浏览器大小)和各种设备屏幕分辨率都有响应。

对于分辨率 480 x 800,我们的表单如下截图所示:

使我们的表单响应

对于分辨率 768 x 1024,我们的表单如下截图所示:

使我们的表单响应

对于分辨率 1280 x 800,我们的表单如下截图所示:

使我们的表单响应

对于每个特定的分辨率,我们可以注意到我们能够在不滚动任何一侧的情况下查看完整的表单。

在先前的场景中,对于不同的分辨率,一些元素被调整大小,并且动态地从原始位置移动,以获得更好的用户体验。

这样,我们的表单可以动态响应不同的分辨率。

限制

移动网页设计的新方法是响应式设计,但对于网页设计师和他们的客户来说,最大的挑战之一是最终确定网站的布局或线框图。

我们需要克服的其他一些挑战包括:

  • 响应式设计比构建其他网站需要更多的开发时间。

  • 缩放图像会降低图像质量,因为缩放是基于屏幕大小而不是上下文的。

  • 在较小的设备上,使用导航菜单变得具有挑战性。

  • 浏览器兼容性成为一个问题;由于旧版浏览器的支持,媒体查询的支持变得有限。

  • 使用这项技术构建复杂的网站变得乏味。

  • 开发成本更高

  • 网站的响应时间变慢,因为网页的大小大大增加。

  • 在移动设备上,下载甚至没有显示的桌面内容会增加加载时间。

指南

在本节中,我们将看一下响应式设计的指南,以使我们的表单更有效。

一些响应式设计的最佳实践包括:

  • 尽量将网页上的内容保持最少,以获得更好的响应式设计。

  • 在较小的屏幕上,始终优先考虑内容。

  • 尽量少使用导航。

  • 网页必须得到有效的编程和结构。

  • 响应式设计不仅适用于手机。响应式设计的范围不仅限于手机或平板电脑;事实上,我们应该记住人们也使用大尺寸的 27 英寸台式电脑屏幕。

  • 始终专注于浏览器兼容性。

  • 保持表单简短;如果使用长表单,添加一个“保存”按钮,并将用户导航到下一页。

  • 始终保持响应式设计的单独文件,以便轻松维护代码。

摘要

在本章中,我们学习了响应式设计。除此之外,我们还看到了响应式设计的优势和建议。

我们学习了各种技术,可以使我们的表单具有响应性。

然后,借助代码,我们学习了响应式网页表单的实际实现,通过重复使用我们在之前章节中构建的示例。

最后,我们看到了使响应式表单更有效的最佳实践。

posted @ 2024-05-24 11:14  绝不原创的飞龙  阅读(12)  评论(0编辑  收藏  举报