WEb-开发者参考指南-全-
WEb 开发者参考指南(全)
原文:
zh.annas-archive.org/md5/f3da6d62d13eb2ba8f5234075a237c8e译者:飞龙
前言
本书涵盖了任何网络开发者可能需要了解的许多概念。这些概念可能是新的或已知的,但被遗忘的。本书的前两章将涵盖 HTML 的基本元素和属性。接下来的四章将涵盖 CSS 的概念和语法。下一章将专注于 JavaScript。最后,我们将涵盖外部库。这些包括 Bootstrap、jQuery 和 Angular。因为这是一本参考指南,它不是作为阅读教程设置的。每个部分和概念都是独立编写的,这样您可以快速找到所需的信息。
本书涵盖的内容
第一章,HTML 元素,涵盖了构建网页时所需的所有元素。这是针对 HTML5 的。
第二章,HTML 属性,专注于可以与 HTML 元素一起使用的任何属性。
第三章,CSS 概念与应用,专注于选择器。选择器是确定 CSS 属性应用于哪些元素的核心。
第四章,CSS 属性 – 第一部分,涵盖了动画、背景、盒模型、CSS 单位、列和强大的 Flexbox 的属性。
第五章,CSS 属性 – 第二部分,涵盖了字体、变换、过渡、位置、文本、表格、单词和段落以及分页的属性。
第六章,CSS 属性 – 第三部分,涵盖了页面框、列表、计数器、阴影、显示和可见性、裁剪和遮罩、用户界面和 3D 的属性。
第七章,CSS 函数,涵盖了过滤器、变换、颜色、渐变和值的函数。它还涵盖了诸如 at 规则、全局关键字值和杂项等一些额外概念。
第八章,JavaScript 实现、语法基础和变量类型,讨论了 JavaScript 实现和语言基础,包括语法和变量及其类型。这一章将使我们能够理解和开始基本的脚本编写。
第九章,JavaScript 表达式、运算符、语句和数组,使我们能够深化对基本 JavaScript 语言的理解,并介绍了 JavaScript 表达式、基本运算符、语句、循环、条件和数组。这也涵盖了更好的理解所需的示例。
第十章, JavaScript 面向对象编程,解释了面向对象编程的基本概念,即继承、多态、抽象和封装。您还将学习对象、类和相关方法的用法。我们将通过示例来加深理解。
第十一章, 扩展 JavaScript 和 ECMA Script 6,涵盖了 2015 年发布的 ECMAScript 6 的所有新特性,例如新对象、模式、语法更改以及现有对象上的新方法。本章将详细介绍所有这些特性。
第十二章, 服务器端 JavaScript – NodeJS,继续关注 JavaScript。区别在于我们现在将在服务器端而不是客户端编写 JavaScript。我们可以使用其他 JavaScript 章节中介绍的概念,以及学习特定的 NodeJS 对象和范式。
第十三章,Bootstrap – 时尚的 CSS 前端框架,讨论了 Bootstrap,这是一个用于创建响应式网站的直观框架。它使用 JavaScript、HTML 和 CSS。本章将详细介绍 Bootstrap 框架,并使您能够创建响应式布局和网页。本章中的每个主题都有一个相关的示例。
第十四章, jQuery – 流行的 JavaScript 库,专注于 jQuery,这是一个简化处理 HTML 文档各个方面操作的 JavaScript 库。在本章中,您将学习如何遍历 HTML 文档的元素、方法、事件处理、动画和 AJAX 以实现快速开发。
第十五章, AngularJS – 谷歌的热门框架,我们将通过完成外部库部分来结束这本书。Angular 自从谷歌推出以来一直是最受欢迎的框架之一。我们将查看您开始使用 Angular 编写应用程序所需的所有主要概念。
您需要这本书的东西
对于这本书,您可能不需要您尚未使用的东西!您需要一个电脑、一个浏览器和一个文本编辑器。每个章节将涵盖不同的概念和语言,因此每个章节之间可能存在差异。
这里是您在章节中需要总结的各种东西:
-
对于第 1-5 章,您只需要一个文本编辑器和浏览器。
-
对于第六章至第十一章,你需要相同的文本编辑器和浏览器,但由于 JavaScript 是一种编程语言,我建议使用集成开发环境(IDE)。JetBrains 为网络开发制作了一个名为 WebStorm 的出色 IDE。然而,这些章节并不一定需要这个。
-
对于第十二章至第十四章,你将再次需要文本编辑器和浏览器。IDE 对于这一部分也非常有帮助。任何时候你处理复杂框架时,IDE 都会让你的生活变得更轻松。
虽然你可以只用记事本和浏览器来做任何类型的开发,但在任何特定语言中进行开发时,IDE 总是首选和推荐的。我建议初学者使用 Adobe Dreamweaver。IDE 的智能感应功能使得编码变得容易得多,因为它会自动建议各种方法、名称和变量,因此你不必记住所有内容。由于我们将在 jQuery 部分处理元素和文档节点,你应该在你的浏览器中启用扩展。ECMA Script 6 非常新,并不是所有浏览器都完全支持。在某些示例中,你可能需要加载 ES6 编译器来在你的浏览器中启用该功能。然而,我强烈建议你使用最新版本的 Google Chrome 作为客户端,因为它涵盖了 ES6 的大部分内容。
这本书面向谁
这本书旨在面向初学者以及高级网络开发者。对于任何网络开发者来说,这本书都将是一个宝贵的资源。你可以在这本书中查找任何与 HTML、CSS、JavaScript、NodeJS、Bootstrap、jQuery 或 Angular 相关的概念。
习惯用法
在这本书中,你会发现许多文本样式,用于区分不同类型的信息。以下是一些这些样式的示例及其含义的解释。
文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称显示如下:“HTML5 有一个简单的文档类型声明,<!DOCTYPE html>。”
代码块设置如下:
<div class="example">
This is an example HTML element
</div>
当我们希望将你的注意力引到代码块的一个特定部分时,相关的行或项目将以粗体显示:
try{
JSON.parse(jsonObject);
} catch (ex) {
//do something with this error
}
任何命令行输入或输出都如下所示:
# cp /usr/src/asterisk-addons/configs/cdr_mysql.conf.sample
/etc/asterisk/cdr_mysql.conf
新术语和重要词汇以粗体显示。你会在屏幕上看到的单词,例如在菜单或对话框中,在文本中显示如下:“点击下一步按钮将你移动到下一屏幕。”
注意
警告或重要注意事项以如下框的形式出现。
小贴士
小贴士和技巧看起来像这样。
读者反馈
我们欢迎读者的反馈。请告诉我们你对这本书的看法——你喜欢什么或不喜欢什么。读者反馈对我们来说很重要,因为它帮助我们开发出你真正能从中获得最大收益的标题。
要发送给我们一般性的反馈,只需发送电子邮件至<feedback@packtpub.com>,并在邮件的主题中提及书的标题。
如果您在某个领域有专业知识,并且您有兴趣撰写或为书籍做出贡献,请参阅我们的作者指南,网址为www.packtpub.com/authors。
客户支持
现在,您已经成为 Packt 书籍的骄傲拥有者,我们有多种方式可以帮助您从购买中获得最大收益。
下载示例代码
您可以从www.packtpub.com的账户下载此书的示例代码文件。如果您在其他地方购买了此书,您可以访问www.packtpub.com/support,并注册以将文件直接通过电子邮件发送给您。
您可以通过以下步骤下载代码文件:
-
使用您的电子邮件地址和密码登录或注册我们的网站。
-
将鼠标指针悬停在顶部的支持标签上。
-
点击代码下载和错误更正。
-
在搜索框中输入书籍名称。
-
选择您想要下载代码文件的书籍。
-
从下拉菜单中选择您购买此书籍的地方。
-
点击代码下载。
文件下载后,请确保您使用最新版本解压缩或提取文件夹:
-
WinRAR / 7-Zip for Windows
-
Zipeg / iZip / UnRarX for Mac
-
7-Zip / PeaZip for Linux
错误更正
尽管我们已经尽一切努力确保内容的准确性,但错误仍然可能发生。如果您在我们的某本书中找到错误——可能是文本或代码中的错误——如果您能向我们报告,我们将不胜感激。这样做可以节省其他读者的挫败感,并帮助我们改进此书的后续版本。如果您发现任何错误更正,请通过访问www.packtpub.com/submit-errata,选择您的书籍,点击错误更正提交表单链接,并输入您的错误更正详情。一旦您的错误更正得到验证,您的提交将被接受,错误更正将被上传到我们的网站或添加到该标题的错误更正部分下的现有错误更正列表中。
要查看之前提交的错误更正,请访问www.packtpub.com/books/content/support,并在搜索字段中输入书籍名称。所需信息将出现在错误更正部分下。
海盗行为
在互联网上对版权材料的盗版是所有媒体中持续存在的问题。在 Packt,我们非常重视我们版权和许可证的保护。如果您在互联网上发现我们作品的任何非法副本,请立即提供位置地址或网站名称,以便我们可以追究补救措施。
请通过链接mailto:copyright@packtpub.com copyright@packtpub.com 与我们联系,并提供疑似盗版材料的链接。
我们感谢您在保护我们的作者和提供有价值内容的能力方面的帮助。
问题和建议
如果您对本书的任何方面有问题,您可以联系我们的邮箱 <questions@packtpub.com>,我们将尽力解决问题。
第一章:HTML 元素
超文本标记语言(HTML)是一种注释文本的语言。文本的注释是通过元素来完成的。以下面的 p 元素为例,我们将看到如何使用 HTML:
<p>This is an example</p>
HTML 元素也有属性,这些属性将修改它们的渲染或解释方式。属性添加在起始标签内。下面是 div 元素中的 class 属性:
<div class="example">This is an example</div>
到目前为止,HTML 已经有多个规范,但我们将只关注 HTML5 中最常用和最重要的元素。HTML5 是最新的官方规范,因此在撰写本书时,我们将尽可能保证其前瞻性。您将希望尽可能紧密地遵循 HTML 的规范。大多数浏览器都非常宽容,会渲染您的 HTML,但当你超出规范时,你可能会遇到奇怪的渲染问题。
注意
所有 HTML 元素都将具有全局属性。以下各节中列出的每个元素的属性都是超出全局属性的属性。
DOCTYPE
DOCTYPE 元素定义了文件的文档类型,如下所示:
<!DOCTYPE documentType>
属性
前面代码中可以看到的 documentType 属性让浏览器知道您将使用的文档类型。
描述
HTML5 有一个简单的文档类型声明,<!DOCTYPE html>。这会让浏览器知道文档是 HTML5。HTML 的先前版本需要一个正式的版本定义,但 HTML5 为了简化已经去除了这一点。
大多数浏览器将强制执行对声明的文档类型的严格遵循,并试图根据查看文档来推断它是什么。这可能会导致渲染问题,因此建议您遵循标准。
下面是一个 HTML5 声明:
<!DOCTYPE html>
html
html 元素是 HTML 文档的根元素:
<html manifest></html>
属性
manifest 属性链接到一个资源清单,列出了哪些文件应该被缓存。
描述
html 元素必须直接跟在 DOCTYPE 元素之后。这是所有其他元素都必须是其后代的根元素。
html 元素必须有一个 head 元素和一个 body 元素作为其子元素。所有其他元素都将包含在这些标签内。
下面是一个简单的 HTML 页面的样子:
<!DOCTYPE html>
<html manifest="offline.appcache"><head>
</head>
<body>
Hey
</body>
</html>
文档元数据
下一个元素将提供有关文档的元数据。除了这些,您还可以包括对资源(如 CSS 和 JavaScript)的链接。
head
head 元素是元数据父元素。所有其他元数据元素都将是这个元素的子元素:
<head></head>
描述
head 元素通常必须包含一个 title 元素。可以放入 head 的元素有 title、link、meta、style、script、noscript 和 base。这些元素将在下面进行解释。
下面是一个定义了 title 和 stylesheet 元素的 head 元素的示例:
<head>
<title>Title that appears as the tab name</title>
<link href="style.css" rel="stylesheet" type="text/css" media="all" />
</head>
title
title元素显示文档的标题。这是在浏览器标签或浏览器窗口中显示的内容:
<title></title>
描述
title元素是一个恰如其分的元素。这是head中的必需元素,并且对于每个文档,应该只有一个title元素。以下是一个简单的title元素示例:
<head>
<title>Example</title>
</head>
link
link元素将资源链接到当前文档:
<link crossorigin href media rel sizes type></link>
属性
在link元素中使用的属性如下:
-
crossorigin: 这告诉浏览器是否要发起跨源资源共享(CORS)请求 -
href: 这表示资源的 URL -
media: 这选择此资源适用的媒体 -
rel: 这表示此资源与文档的关系 -
sizes: 当rel设置为icons时,此属性被使用 -
type: 这表示资源的内容类型
描述
link元素有很多属性,但大多数情况下,它用于加载 CSS 资源。这意味着您至少需要使用href、rel、type和media属性。
您可以在head元素中拥有多个link元素。以下是一个加载 CSS 的简单示例:
<link href="style.css" rel="stylesheet" type="text/css" media="all" />
<link href="style.css" media="screen" rel="styleshhet" sizes type="text/css"></link>
参见
您还可以通过引用crossorigin、href、media、rel、sizes和type属性来获取更多关于title元素的信息。
meta
meta元素包含关于文档的元数据。其语法如下:
<meta content http-equiv name></meta>
属性
在meta元素中使用的属性如下:
-
content: 这声明了name或http-equiv属性的价值。 -
http-equiv: 在 HTML5 中,此属性可以设置为default-style,以设置默认样式。或者,它可以设置为refresh,可以指定刷新页面的秒数,如果需要,还可以指定新页面的不同 URL,例如,http-equiv="1;url=http://www.google.com"。 -
name: 这声明了元数据的名称。
描述
meta标签有许多非标准应用。标准化应用可以在第二章 HTML 属性中查看。
注意
苹果有许多meta标签,这些标签会将信息传递给 iOS 设备。例如,您可以设置对 App Store 应用的引用,设置图标,或以全屏模式显示页面,这只是其中的一些例子。所有这些标签都是非标准的,但在针对 iOS 设备时很有用。许多其他网站和公司也是如此。
您可以在head元素中使用多个meta标签。以下有两个示例。第一个示例将在每 5 秒刷新页面,而另一个示例将定义author元数据:
<meta http-equiv="refresh" content="5" />
<meta name="author" content="Joshua" />
参见
您还可以通过引用name属性来获取更多关于meta元素的信息。
style
style元素包含样式信息。
CSS:
<style media scoped type></style>
属性
在style元素中使用的属性如下:
-
media: 这是一个媒体查询 -
scoped:此元素包含的样式仅应用于父元素 -
type:这设置了文档的类型;默认值是text/css
描述
style 元素通常位于 head 元素中。这允许你为当前文档定义 CSS 样式。
使用 CSS 的首选方法是创建一个单独的资源并使用 link 元素。这允许样式一次定义并在整个网站上使用,而不是在每一页上定义它们。这是一种最佳实践,因为它允许我们在一个地方定义样式。然后我们可以轻松地找到并更改样式。
这里是一个简单的内联样式表,将字体颜色设置为蓝色:
<style media="screen" scoped type="text/css">
body{
color: #0000FF;
}
</style>
相关内容
你还可以参考全局属性和第 3-7 章,以了解更多有关 style 元素的信息。
base
base 元素是文档的基本 URL。其语法如下:
<base href target>
属性
在 base 元素中使用的属性如下:
-
href:这表示要使用的基 URL -
target:这表示与 URL 一起使用的默认目标
描述
基 URL 在页面上使用相对路径或 URL 时使用。如果没有设置,浏览器将使用当前 URL 作为基 URL。
这里是如何设置基 URL 的一个例子:
<base href="http://www.packtpub.com/">
相关内容
你还可以参考 target 属性以获取有关 base 元素的更多详细信息。
script
script 元素允许你引用或为文档创建脚本:
<script async crossorigin defer src type><script>
属性
在 script 元素中使用的属性如下:
-
async:这是一个布尔属性,告诉浏览器异步处理此脚本。这仅适用于引用的脚本。 -
crossorigin:这告诉浏览器是否进行 CORS 请求。 -
defer:这是一个布尔属性,告诉浏览器在文档解析后执行脚本。 -
src:这区分了脚本的 URL。 -
type:这定义了脚本的类型,如果省略了属性,则默认为 JavaScript。
描述
script 元素是将 JavaScript 引入你的文档并添加增强交互性的方式。这可以通过添加 JavaScript 到元素中的裸 script 标签来完成。此外,你可以使用 src 属性来引用外部脚本。引用脚本文件被认为是一种最佳实践,因为它可以在此处重用。
此元素可以是 head 的子元素,也可以放置在文档的任何位置。根据 script 元素的位置,你可能或可能无法访问 DOM。
这里有两个使用 script 元素的例子。第一个例子将引用外部脚本,第二个将是一个内联 script 元素,最后一个将展示如何使用 crossorigin 属性:
<script src="img/example.js" type="text/javascript"></script>
<script>
var a = 123;
</script>
<script async crossorigin="anonymous" defer src="img/application.js" type="text/javascript"><script>
noscript
如果在浏览器中关闭了脚本,则将解析 noscript 元素。其语法如下:
<noscript></noscript>
描述
如果启用了脚本,则此元素内的内容将不会显示在页面上,并且其中的代码将运行。如果禁用了脚本,它将被解析。
此元素主要用于让用户知道网站可能无法与 JavaScript 一起工作。今天几乎每个网站不仅使用 JavaScript,而且需要它。
这里是 noscript 元素的例子:
<noscript>
Please enable JavaScript.
</noscript>
语义内容部分
下一个元素是在向文档添加内容时使用的主要元素。例如,使用 article 元素而不是任意的 div 元素允许浏览器推断这是页面的主要内容。应使用这些元素来为文档提供结构,而不是用于样式目的。语义元素使我们的 HTML 文档能够通过不断增加的不同设备实现更高的可访问性。
body
body 元素是文档的主要内容部分。必须只有一个主要元素,其语法如下:
<body></body>
属性
body 元素的属性包括内联事件属性。
描述
body 元素是大多数文档的主要内容部分。它必须是 html 的第二个子元素,并且文档中只能有一个 body 元素。
这里是 body 元素的例子:
<body>
<span>Example Body</span>
</body>
section
section 元素描述了文档的内容部分。例如,这可以是书的章节:
<section></section>
描述
section 元素是 HTML5 中引入的一个新元素。section 元素应该将内容分组在一起。虽然不是必需的,但将 heading 元素作为代码中的第一个元素是一种最佳实践。应将部分视为文档大纲的另一个部分。它将相关项目组合成一个易于定位的区域。您可以在文档中多次使用此元素。
这里是 section 元素的例子:
<section>
<h2>Section Heading</h2>
<p>Section content.</p>
</section>
nav
nav 元素是导航元素:
<nav></nav>
描述
nav 元素是 HTML5 中引入的另一个语义元素。这使浏览器知道此元素的内容是父元素,用于导航。nav 元素通过为屏幕阅读器提供导航地标来增强可访问性。此元素应包含任何用于简化导航的网站导航或其他链接。您可以使用此元素多次。
这里是一个使用 nav 元素的例子:
<nav>
<ul>
<li><a href="#">Home</a></li>
</ul>
</nav>
article
article 元素的设计是为了包裹可以独立存在的内联内容:
<article></article>
描述
article 元素是 HTML5 中引入的新元素。article 元素类似于 section 元素;在这一点上,它表示元素中的内容是页面的核心部分。article 元素应该是一个完整的作品,可以独立存在。例如,在博客中,实际的博客文章应该用 article 元素包裹。
可以使用article元素或section元素进一步拆分内容。没有使用哪个元素的标准规则。然而,两者都应该与外部的article元素中的内容相关。
这里是使用article元素的示例:
<article>
<header>
<h1>Blog Post</h1>
</header>
<p>This post covers how to use an article element...</p>
<footer>
<address>
Contact the author, Joshua
</address>
<footer>
</article>
标题
heading元素是用于指定不同标题级别的元素,根据其重要性来划分:
<h1></h1>
<h2></h2>
<h3></h3>
<h4></h4>
<h5></h5>
<h6></h6>
描述
这些应该用于给不同的标题赋予相对的重要性。例如,h1应用于文档的标题。标题的重要性随着标题值的增加而降低,即,在下面的示例中h6是标题级别最低的。
这里是使用所有标题的示例:
<h1>Heading Importance 1</h1>
<h2>Heading Importance 2</h2>
<h3>Heading Importance 3</h3>
<h4>Heading Importance 4</h4>
<h5>Heading Importance 5</h5>
<h6>Heading Importance 6</h6>
参见
你也可以参考全局属性来详细了解heading元素。
header
header元素将一组被认为是特定内容组标题的内容组合在一起,其语法如下:
<header></header>
描述
header元素通常是页面上第一个内容元素之一。它很可能包含导航选项、标志和/或搜索框。页眉通常在网站的多个页面上重复。每个部分或文章也可以包含页眉。这是 HTML5 中引入的新元素。
这里是header元素的示例:
<header>
<img src="img/logo.png" />
</header>
参见
你也可以参考全局属性来详细了解header元素。
footer
footer元素为特定内容组提供页脚,其语法如下:
<footer></footer>
描述
footer元素包含被认为是文档页脚的所有内容。通常,这包括版权、作者和/或社交媒体链接。当然,你决定放入页脚的内容是任意的。每个部分或文章也可以包含页脚。
这里是footer元素的示例:
<footer>
Written by: Joshua Johanan
</footer>
地址
address元素用于作者的联系方式或组织的联系地址,其语法如下:
<address></address>
描述
当你有用户的联系信息时,请使用address元素。address元素将为内容添加语义值,与常规的div元素相反。
通常,这将被放置在页脚中,但也可以用于文章或主体部分。它将应用于最近的article元素或整个文档。不要在address元素中使用任何内容部分元素。
这里是address元素的使用示例:
<footer>
<address>
Please contact me at my <a href="#">website</a>
</address>
</footer>
aside
aside元素用于补充内容:
<aside></aside>
描述
使用aside元素来突出与主要文章相关的内容。在博客的上下文中,一些示例包括作者的简介、作者的其他帖子或甚至相关的广告。
这里是一个aside元素的示例:
<aside>
Peyton Manning is a 5-time MVP (2003, 2004, 2008, 2009, 2013)
</aside>
p
p元素被称为段落元素。这是一个块级元素,其语法如下:
<p></p>
描述
应该使用 p 元素来区分文档中的单独段落。此元素与 text 和 inline 元素相关联。你不会想使用 div 元素,例如。如果你发现自己想要这样做,你可能需要以不同的方式构建你的文档。
这里是几个段落:
<p>This is an intro paragraph.</p>
<p>This paragraph will build upon the opening.</p>
内容部分
content 部分与语义内容部分非常相似。主要区别在于,所有给定元素的使用不是由文档的轮廓或目的驱动的,就像语义部分那样。
水平线
hr 元素是水平线元素,其语法如下:
<hr>
描述
默认情况下,hr 元素将在内容中绘制一条水平线。你可以通过 CSS 改变此元素的外观。
此元素内部不应包含任何内容:
<p>This is a paragraph.</p>
<hr/>
<p>This paragraph goes in another direction.</p>
pre
pre 元素是预格式化文本:
<pre></pre>
描述
HTML 文档中的文本通常在浏览器中不会以与文本文档相同的空白或换行符显示。pre 元素允许你以与文档中相同的方式显示文本。空白和换行符将被保留。
这里是使用换行符的示例。
<pre>This text
has some
line breaks.</pre>
blockquote
blockquote 元素的语法如下:
<blockquote cite></blockquote>
属性
在 blockquote 元素中使用 cite 属性来指向被引用文档的 URL。
描述
当从文档或文本中提取引用时,使用 blockquote 元素。
这里有一个示例:
<blockquote cite="https://www.packtpub.com/">
<p>Contact Us</p>
</blockquote>
有序列表
ol 元素是有序列表元素,其语法如下:
<ol reversed start type></ol>
属性
在 ol 元素中使用的属性如下:
-
reversed:这是一个布尔值。表示列表是倒序的。 -
start:这个属性接受一个数值作为起始值。 -
type:这将改变编号元素的类型。默认情况下,我们可以有一个编号列表(1),但我们可以更改为其他类型,例如小写字母(a)、大写字母(A)、小写罗马数字(i)和大写罗马数字(I)。
描述
ol 元素可以在与 ul 元素相同的情况下使用,除了 ol 元素是编号的而不是带点的。例如,你会使用 ul 元素来创建购物清单,而使用 ol 元素来创建编号指令集。你可以在每个元素内部嵌套多个 ul 或 ol 元素。
列表中的项将是 li 元素。
这里是一个使用罗马数字并从 10 开始的列表示例。
<ol start="10" type="i">
<li>Roman numeral 10</li>
<li>Roman numeral 11</li>
</ol>
相关内容
你也可以参考 ul 和 li 元素来了解更多关于 ol 元素的信息。
无序列表
ul 元素是无序列表元素:
<ul></ul>
描述
ul 元素可以在与 ol 元素相同的情况下使用,但 ul 元素将带点,而 ol 元素将编号。
当你为这个列表设置样式时,你应该使用 CSS 而不是旧的 HTML 4 属性。
你可以多次嵌套 ul 和 ol 元素。
这里是 ul 元素的示例:
<ul>
<li>Items in</li>
<li>no particular</li>
<li>order</li>
</ul>
参考信息
您还可以参考 ol 和 li 元素,以了解更多关于 ul 元素的信息。
li
li 元素是列表项元素:
<li value></li>
属性
value 属性在 li 元素和 ol 元素中使用,它是有序列表中项目的值。
描述
您将使用 li 元素为列表中的每个项目。
这里有一个例子:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
参考信息
您还可以参考 ol 和 ul 元素,以了解更多关于 li 元素的信息。
dl
dl 元素是定义列表元素:
<dl></dl>
描述
dl 元素是一个列表,其中项目有术语和定义;然而,dl 元素不仅可以用于术语和定义。
在构建 dl 元素的列表时,您必须使用 dt 元素后跟 dd 元素。每个 dt 元素后面可以有多个 dd 元素。
这里有一个例子:
<dl>
<dt>PactPub</dt>
<dd>Packt Publishing</dd>
</dl>
参考信息
您还可以参考 dt 和 dd 元素,以了解更多关于 dl 元素的信息。
dt
dt 元素是定义术语元素:
<dt></dt>
描述
dt 元素是定义列表中的第一个项目,另一个项目是 dd 元素。
这里有一个示例:
<dl>
<dt>PactPub</dt>
<dd>Packt Publishing</dd>
</dl>
参考信息
您还可以参考 dl 和 dd 元素,以了解更多关于 dt 元素的信息。
dd
dd 元素是定义描述元素:
<dd></dd>
描述
dd 元素是定义列表中的第二个项目,另一个是 dt 元素。
这里有一个示例:
<dl>
<dt>PactPub</dt>
<dd>Packt Publishing</dd>
</dl>
参考信息
您还可以参考 dl 和 dd 元素,以了解更多关于 dd 元素的信息。
figure
figure 元素的语法如下:
<figure></figure>
描述
figure 元素是 HTML5 中引入的新元素。与文章元素在无意义的地方添加一些意义的方式类似,图元素也添加了意义。图是一个图像或其他与文档相关的信息项。这比仅仅使用 img 元素更有意义。
这里有一个例子:
<figure>
<img src="img/figure1.jpg" title="Figure 1" />
<figcaption>Figure One</figcaption>
</figure>
参考信息
您还可以参考 figcaption 元素,以了解更多关于 figure 元素的信息。
figcaption
figcaption 元素是图注元素:
<figcaption></figcaption>
描述
figcaption 元素是在 HTML5 中与 figure 元素一起引入的。此元素为图提供标题。此元素必须位于 figure 元素内部,并且必须是 figure 元素的第一或最后一个子元素。
这里是 figcaption 元素的简单示例:
<figure>
<img src="img/figure1.jpg" title="Figure 1" />
<figcaption>Figure One</figcaption>
</figure>
参考信息
您还可以参考 figure 元素,以了解更多关于 figcaption 元素的信息。
div
div 元素是分割元素:
<div></div>
描述
div 元素是今天 HTML 中最常用的元素之一。它是用来将您的文档分割成任意部分使用的元素。div 元素没有默认样式。这些分割可以是用于定位、样式或其他任何原因。div 元素不会影响文档的语义意义。它应该只在没有其他元素满足您的要求时使用。
这里是一个示例:
<div>
You can put whatever you want in here!
<div>
More elements.
</div>
</div>
main
main 元素的语法如下:
<main></main>
描述
main 元素应该包含文档的主要内容。您不能将此元素作为 article、aside、footer、header 或 nav 元素的子元素。这与文章不同,因为文章应该是一个自包含的元素。
这里是 main 元素的使用示例:
<main>
This is the main content of the document.
<article>
Here is the article of the document.
</article>
</main>
内联元素
以下元素都可以包裹文本和块级元素,以赋予它们功能、样式和意义。
a
a 元素是锚元素。这是 HTML 获得超文本(HT)的地方,语法如下:
<a download href media ping rel target type></a>
属性
这里列出了在 a 元素中使用的属性:
-
download: 此属性让浏览器知道该项应该被下载。对话框将默认为此属性中的文件名。 -
href: 这是链接目标。 -
media: 这根据媒体查询指定了样式表应该应用到的媒体。 -
ping: 这会创建一个用于 ping 和通知的 URL,如果链接被跟随。 -
rel: 这指定了被链接文档的关系。 -
target: 这指定了目标链接应该显示的位置。 -
type: 这指定了链接资源的 MIME 类型。
描述
a 元素是最重要和最有用的元素之一。它允许您将文档链接在一起,并且您可以轻松地在元素之间跳转。我们可以这样说,如果没有这个非常易于使用的元素,互联网可能不会像现在这样受欢迎。
链接可以是文档中的 anchor 标签、相对 URL 或任何外部资源。当链接到当前文档中的 anchor 标签时,请使用 a 标签和 id 属性。
您在 a 元素内部放置的内容将成为用户可以点击以跟随链接的部分。这包括 text、img 和 div 元素等。
这里是一个带有图像的 img 元素的示例:
<a href="http://www.packtpub.com">
<img src="img/packt_logo.png" />
</a>
这里是一个将要下载的 PDF 文档的示例;这将跟踪每个点击:
<a download="report.pdf" href="assests/report.pdf" media="min-width: 1024px" ping="track/click" rel="alternate" target="_blank" type=" application/pdf"></a>
abbr
abbr 元素是缩写元素:
<abbr></abbr>
描述
abbr 元素用于显示缩写代表的内容。您应该在 title 属性中放置完整的单词。大多数浏览器在您将鼠标悬停在此元素上时将显示此内容作为工具提示。
这里是一个示例:
<abbr title="abbreviation">abbr</abbr>
bdo
bdo 元素是双向覆盖元素:
<bdo dir></bdo>
属性
dir 属性用于 bdo 元素中,它给出了文本的方向。其值可以是 ltr、rtl 和 auto。
描述
bdo 元素将覆盖元素中定义的方向的当前文本方向。
这里是一个示例:
<bdo dir="rtl">Right to Left.</bdo>
br
br 元素是换行元素:
<br>
描述
br 元素添加一个换行。由于在浏览器中渲染文本时忽略行断,因此需要此元素。不应使用它来帮助放置元素,因为这应该是 CSS 的工作。
这里是一个示例:
First Name<br>
LastName
cite
cite 元素是引用元素:
<cite></cite>
描述
cite元素用于引用另一个来源。大多数浏览器将以斜体显示。
这里是一个例子:
This quote is from <cite>Web Developer's Reference</cite>
code
code元素的语法如下:
<code></code>
描述
code元素用于在文档中显示编程代码。浏览器将使用等宽字体显示它。
这里是一个例子:
Here is some JavaScript: <code>var a = 'test'</code>
dfn
dfn元素是定义实例元素:
<dfn></dfn>
描述
dfn元素用于创建定义实例或首次引入并解释特定单词。
这里是dfn元素的例子:
<dfn>HTML</dfn>, or HyperText Markup Language.
em
em元素是强调元素:
<em></em>
描述
em元素用于给特定的单词或短语添加更多强调。默认情况下,浏览器将以斜体字体显示,但不应该仅仅用于斜体。
kbd
kbd元素是键盘输入元素:
<kbd></kbd>
描述
kbd元素用于用户应输入的文本。这并不意味着用户将数据输入到元素中,而是他们将在窗口、控制台或他们电脑上的某些应用程序中输入它。
这里是一个例子:
Press <kbd>Win + R</kbd> to open the Run dialog.
mark
mark元素的语法如下:
<mark></mark>
描述
mark元素用于突出显示文本。
这里是一个例子:
<mark>This</mark> will be highlighted
q
q元素是引用元素:
<q cite></q>
属性
q元素中使用的cite属性声明了引用的来源 URL。
描述
q元素用于短引用。对于较长的引用,请使用blockquote。
这里是一个例子:
<q cite="http://en.wikiquote.org/">Don't quote me on this.</q>
相关内容
您还可以参考blockquote属性来了解更多关于q元素的信息。
s
s元素是删除线元素:
<s></s>
描述
当文档中的某条信息不再准确时,应使用s元素。这与对文档进行的修订不同。
这里是一个例子:
Today is the <s>twenty-fifth<s> twenty-sixth.
samp
samp元素是示例输出元素:
<samp></samp>
描述
samp元素用于显示命令或程序的示例输出。
这里是一个例子:
The command should output <samp>Done!</samp>
small
small元素的语法如下:
<small></small>
描述
small元素用于使文本变小。这通常用于版权或法律文本等文本。
这里是一个例子:
<small>Copyright 2014</small>
span
span元素的语法如下:
<span></span>
描述
span元素与div元素类似;即,它只是一个任意的容器。div元素是一个块级元素,而span元素是一个内联元素。该元素不会向文本或文档添加任何语义意义。通常,它用于向文本添加 CSS 样式:
<span>This text is in the span element.</span>
strong
strong元素的语法如下:
<strong></strong>
描述
当某些文本需要更多重要性时,应使用strong元素。这具有一些语义意义。在大多数浏览器中,strong元素的默认样式是粗体。因此,它不应与b元素互换,因为b元素不携带任何语义意义。
这里是一个例子:
<strong>Warning!</strong> JavaScript must be enabled.
sub
sub元素是下标元素:
<sub></sub>
描述
sub元素会将文本渲染为下标。
这里有一个例子:
H<sub>2</sub>O
sup
sup元素是上标元素:
<sup></sup>
描述
sup元素会将文本渲染为上标。
这里有一个例子:
x<sup>2</sup> is what x squared should look like
time
time元素的语法如下:
<time datetime></time>
属性
在time元素中使用的datetime属性提供了一个日期和时间值的字符串。
描述
datetime元素允许浏览器轻松解析文档中的日期。你可以包裹一个日期或日期的描述(例如明天或 7 月 4 日),浏览器仍然可以读取确切的日期。
这里有一个例子:
The party is on <time datetime="2014-11-27 14:00">Thanksgiving @ 2PM</time>
var
var元素是变量元素:
<var></var>
描述
var元素用于数学表达式中的变量或编程中的变量。
这里有一个例子:
The variable <var>x</var> is equal to the string test in this example.
wbr
wbr元素是单词断行机会元素:
<wbr>
描述
wbr元素是 HTML5 中引入的新元素。我们使用这个元素来让浏览器知道在单词之间一个好的断点。这不会强制断行,但如果需要断行,浏览器将尊重这个元素。
它是一个空标签,这意味着它不应该有结束标签。
这里有一个例子:
If you have a really short width <wbr>then you <wbr>could have breaks.
嵌入内容
以下元素用于将媒体或其他对象嵌入到文档中。
img
img元素是图片元素:
<img alt crossorigin height ismap sizes src srcset width />
属性
在img元素中使用的属性如下:
-
alt:这是图片的替代文本。用于描述图片。这用于提高可访问性。 -
crossorigin:这会让浏览器知道是否应该使用 CORS 请求来获取此图片。如果图片将在画布元素中修改,而不是来自同一域名,则必须使用 CORS 请求。 -
height:这是一个设置图片高度的属性。 -
ismap:这会让浏览器知道图片是否用于服务器端映射。 -
sizes:这是一个将映射到大小的媒体条件列表。这用于帮助浏览器确定使用哪个图片。默认情况下,这将设置为 100 VW,即视口宽度的 100%。 -
src:这是最重要的属性,它是图片的 URL。 -
srcset:这是一个可以用于显示在我们网页上的多个图片列表。这用于针对不同的屏幕尺寸或像素密度。 -
width:这是一个设置图片宽度的属性。
描述
当你希望在文档中插入图片时,会使用img元素。这个元素有许多属性,但src和alt属性是唯一必需的属性。在几乎所有情况下,都应该使用alt属性来描述图片。主要的例外是当图片仅用作装饰性图片时,例如,当图片被用作水平线代替时。如果图片的大小与页面上所需的大小不同,可以使用宽度和高度;否则,它将默认为图片的大小。
crossorigin元素可能会令人困惑。它用于确保在你在画布元素中修改图像之前拥有该图像的所有权。图像必须来自相同的完全限定域名,或者服务器的响应必须让浏览器知道当前域名是否可以使用该图像。
最后,srcset用于向浏览器提供一个它可以使用图像的列表。这是通过逗号分隔的 URL 列表和一个描述符来完成的。描述符可以是宽度描述符,它是一个数字后跟w,或者像素描述符,它是一个数字后跟x。宽度描述符告诉浏览器图像的宽度。像素描述符告诉浏览器应该为图像使用的像素密度。
注意
当像素密度变化时,浏览器也可以使用宽度描述符。例如,如果你有一个分辨率是双倍的图像,像素密度也加倍,浏览器将选择更高的分辨率。
sizes元素与srcset一起使用,以帮助浏览器识别一个断点。这是通过使用媒体条件来完成的,例如,"(min-width: 1600px) 25vw, 100vw"。这表示如果页面宽度至少为1600像素,则图像将是视口宽度的 25%,否则视口宽度是 100%。这有助于浏览器知道你想要在何处设置断点以及你想要图像有多大。
注意
关于srcset的最佳思考方式是,你正在让浏览器知道可以在特定的img元素中使用的所有图像。你包含浏览器最关心的信息——宽度和像素密度——并让浏览器选择。
这里有一些示例。第一个示例是一个简单的img标签,下一个示例使用了crossorigin:
<img src="img/example.png" alt="This is an example image"/>
<img src="img/example.png" crossorigin="anonymous" alt="This is an example image"/>
这里是一个srcset示例,它允许浏览器根据像素密度选择图像:
<img src="img/normal.jpg" srcset="normal.jpg 1x, retina.jpg 2x" alt="Image of Person in article" />
以下是一个使用srcset和宽度的示例:
<img src="img/regular.jpg" srcset="double_size.jpg 1000w, regular.jpg 500w" sizes="100vw" alt="A bird"/>
iframe
iframe元素是内联框架元素:
<iframe height name seamless src width></iframe>
属性
在iframe元素中使用的属性如下:
-
height:这是一个设置高度的属性。 -
name:这表示一个可以在目标属性中使用的名称。 -
seamless:这使得iframe看起来像是文档内容的一部分。这将应用外部上下文 CSS,并允许我们在外部上下文中打开链接。 -
src:这是嵌入文档的 URL。 -
width:这是一个设置宽度的属性。
描述
iframe元素用于在当前文档中嵌入另一个完整的 HTML 文档。
这里有一个加载 Google 主页的示例,另一个加载 Packt Publishing 页面的示例:
<iframe src="img/www.google.com"></iframe>
<iframe height="100px" name="remote-document" seamless src="img/" width="100px"></iframe>
embed
embed元素的语法如下:
<embed height src type width/>
属性
在embed元素中使用的属性如下:
-
height:这是一个设置高度的属性 -
src:这是要嵌入的对象的 URL -
type:这是对象的 MIME 类型。 -
width:这是一个设置宽度的属性
描述
embed元素用于在文档中嵌入其他对象。根据对象类型,还有其他用于嵌入对象的元素。例如,您可以使用视频元素嵌入视频,如下所示:
<embed src="img/example.mp4" type="video/mp4"/>
参见
您还可以参考audio、video和object元素以了解更多关于embed元素的信息。
object
object元素的语法如下:
<object data height type width></object>
属性
这里是object元素使用的属性:
-
data: 这是要嵌入的对象的 URL -
height: 这是设置高度的属性 -
type: 这是对象的 MIME 类型 -
width: 这是设置宽度的属性
描述
object元素可以非常类似于embed元素使用。这历史上被用于Flash对象。
这里是一个示例:
<object data="example.swf" type="application/x-shockwave-flash"></object>
参见
您还可以参考audio、video、embed和param属性以了解更多关于object元素的信息。
param
param元素是参数元素:
<param name="movie" value="video.swf"/>
属性
在param元素中使用的属性如下:
-
name: 这是参数的名称 -
value: 这是参数的值
描述
param元素为object元素定义了一个参数。此元素的父元素应该是object元素。
这里是一个示例。此示例在旧版浏览器中使用对象时很有用:
<object data="example.swf" type="application/x-shockwave-flash">
<param name="movie" value="example.swf" />
</object>
视频
video元素的语法如下:
<video autoplay buffered controls crossorigin height loop muted played poster src width></video>
属性
在video元素中使用的属性如下:
-
autoplay: 这是一个布尔属性,告诉浏览器在加载停止后尽可能快地开始播放视频 -
buffered: 这是一个read对象,用于说明视频缓冲了多少 -
controls: 这是一个布尔属性,用于决定是否显示控件 -
crossorigin: 如果您计划在画布中修改视频且视频不在同一完全限定的域名上托管,则使用此属性进行 CORS 请求 -
height: 这是设置高度的属性 -
loop: 这表示是否循环视频 -
muted: 这表示是否静音音频 -
played: 这是一个read对象,用于读取视频播放了多少 -
poster: 这是将在视频可以播放之前显示的图像的 URL -
src: 这是视频的 URL -
width: 这是设置宽度的属性
描述
video元素是 HTML5 中引入的新元素。您可以使用它直接在浏览器中播放视频。这对于用户来说非常有用,因为用户不需要插件或特殊播放器来查看视频。此外,您还可以将video元素用作canvas元素的源。
如果浏览器只能播放某种类型的文件,您还可以使用source元素包含多个源。如果浏览器不支持video元素或文件类型,您可以将回退内容放入元素中。
这里是使用 video 元素的示例,以及另一个演示所有属性的可能值的示例:
<video src="img/example.mp4" autoplay poster="example-poster.png"></video>
<video autoplay buffered controls crossorigin="anonymous" height="100px" loop muted played poster="cover.jpg" src="img/video.ogg" width="100px"></video>
参见
你也可以参考 source 和 track 属性来了解更多关于 video 元素的信息。
audio
audio 元素的语法如下:
<audio autoplay buffered controls loop muted played src volume></audio>
属性
audio 元素中使用的属性如下:
-
autoplay: 这是浏览器在可能的情况下立即开始播放音频,而不需要加载的属性 -
buffered: 这是缓冲时间范围的属性 -
controls: 这是浏览器显示控制按钮的属性 -
loop: 这是决定是否循环音频的属性 -
muted: 这是决定是否静音音频的属性 -
played: 这是音频播放时间范围的属性 -
src: 这是音频资源的 URL -
volume: 这是范围在 0.0 到 1.0 之间的音量属性
描述
audio 元素是在 HTML5 中引入的。你可以在页面上添加音频,并让浏览器播放它。
你还可以使用 source 元素来包含多个源,以防浏览器可以播放某种类型的文件。如果浏览器不支持音频元素或文件类型,你可以在元素中放入回退内容。
这里是使用 audio 元素的示例:
<audio src="img/test.mp3" autoplay loop>
Your browsers does not support the audio element.
</audio>
参见
你也可以参考 source 和 track 属性来了解更多关于 audio 元素的信息。
source
source 元素的语法如下:
<source src type />
属性
source 元素中使用的属性如下:
-
src: 这是资源的 URL -
type: 这是资源的 MIME 类型
描述
source 元素用于向 audio、picture 和 video 元素添加多个源。它必须是这些元素之一的孩子。你可以使用它来指定同一资源的多个格式。例如,你可以为视频提供两种不同的视频编码。如果浏览器不能播放第一个,它将回退到另一个。
这里是一个使用 audio 元素的示例:
<audio autoplay controls>
<source src="img/test.ogg" type="audio/ogg" />
<source src="img/test.mp3" type="audio/mpeg">
</audio>
参见
你也可以参考 audio 和 video 属性来了解更多关于 audio 元素的信息。
track
track 元素的语法如下:
<track default kind label src />
属性
这里是 track 元素中使用的属性:
-
default: 这表示所选轨道是否为默认轨道。 -
kind: 这表示可以加载的不同类型的轨道。以下是值:subtitles、captions、descriptions、chapters或metadata。 -
label: 这是轨道的标题。 -
src: 这是资源的 URL。
描述
你主要会使用 track 元素来为视频添加字幕或子标题。
这里是一个带有字幕的示例视频:
<video src="img/test.mp4">
<track label="English" kind="captions" src="img/en.vtt" default>
<track label="Spanish" kind="captions" src="img/sp.vtt">
</video>
表格
表格用于展示数据。它们使得定义行和列变得非常容易。在过去,表格用于创建布局,但如今这通过 CSS 来完成。它们应该仅用于显示表格数据。
表格
table元素的语法如下:
<table></table>
描述
table元素是创建表格的根元素。本节中所有其他元素都必须是此元素的子元素。
下面是table元素的简单例子:
<table>
<tr>
<td>Column in Row 1</td>
</tr>
</table>
caption
caption元素的语法如下:
<caption></caption>
描述
caption元素将是表格的标题。此元素必须是table元素的第一个子元素。
下面是一个简单的例子:
<table>
<caption>Caption for the table</caption>
<tr>
<td>Column in Row 1</td>
</tr>
</table>
colgroup
colgroup元素是列分组元素:
<colgroup span></colgroup>
属性
span属性表示该组跨越的列数。
描述
colgroup元素用于定义适用于所有列或列组的样式。由于新的 CSS 选择器可以针对所有列甚至某些特定列,因此此元素不如以前有用。
tbody
tbody属性是表格主体元素:
<tbody></tbody>
描述
tbody属性是表格的主体部分。所有数据行和列都应该放在这个元素中。此元素应有一个或多个tr元素作为其子元素。
下面是一个例子:
<table>
<tbody>
<tr>
<td>Column in Row 1</td>
</tr>
</tbody>
</table>
thead
thead元素是表格表头元素:
<thead></thead>
描述
thead元素是包含所有列标题的行。它必须出现在tbody或tfoot元素之前。
下面是一个例子:
<table>
<thead>
<tr>
<th>Heading 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column in Row 1</td>
</tr>
</tbody>
</table>
tfoot
tfoot元素是表格的页脚元素:
<tfoot></tfoot>
描述
tfoot元素是表格的页脚。它必须在任何thead元素之后使用,但可以在tbody之前或之后。tfoot元素的位置不会影响其渲染位置,它始终位于底部。
下面是一个例子:
<table>
<tbody>
<tr>
<td>Column in Row 1</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer 1</td>
</tr>
</tfoot>
</table>
tr
tr元素是表格行元素:
<tr></tr>
描述
tr元素是行元素。每次需要在表格中添加另一行时,请使用此元素。此元素可以是table、tbody、thead或tfoot元素的子元素。您必须使用td或th作为其子元素。
下面是一个例子:
<table>
<tbody>
<tr>
<td>Column in Row 1</td>
</tr>
</tbody>
</table>
td
td元素是表格单元格元素:
<td colspan headers rowspan></td>
属性
在td元素中使用的属性如下:
-
colspan:这表示它将跨越多少列,以整数形式表示 -
rowspan:这表示rowspan属性将跨越多少行,以整数形式表示 -
headers:这是一个以空格分隔的字符串列表,与任何th元素的 ID 相匹配
描述
td元素是基本的表格列元素。colspan和rowspan属性允许您分别使列更宽和更高。
下面是一个例子:
<table>
<tbody>
<tr>
<td>Column in Row 1</td>
</tr>
</tbody>
</table>
th
th元素是表格表头单元格元素:
<th colspan rowspan></th>
属性
在th元素中使用的属性如下:
-
colspan:这表示colspan属性将跨越多少列,以整数形式表示 -
rowspan: 这表示rowspan属性将跨越的行数,以整数形式表示
描述
当我们在thead元素中添加列时,会使用th元素。
下面是一个示例:
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
</table>
表单
表单非常适合从用户那里获取信息。它们通常包含多个元素,这些元素可以接受用户的输入。从用户输入中获取的数据随后被发送到服务器进行处理。
表单
form元素的语法如下:
<form accept-charset action autocomplete enctype method name novalidate target></form>
属性
在form元素中使用的属性如下:
-
accept-charset: 这是服务器接受的字符编码列表。这可以是一个空格或逗号分隔的列表。 -
action: 这是处理表单的 URL。 -
autocomplete: 这让浏览器知道是否可以使用之前输入的值自动完成此表单。 -
enctype: 这设置了发送到服务器的内容的 MIME 类型。 -
method: 这是指提交表单时将使用的 HTTP 方法。可以是Post或Get。 -
name: 这是表单的名称。 -
novalidate: 这告诉浏览器不要验证表单。 -
target: 这表示响应将在何处显示。可以是:_self,_blank,_parent, 或_top。
描述
form元素是文档中表单的根元素。当提交时,表单将包含所有输入到表单内部不同元素中的数据。
这里是语法的一个简单示例:
<form action="processForm" method="post">
<input type="text" name="text-input"/>
<button type="submit">Submit!</button>
</form>
字段集
fieldset元素的语法如下:
<fieldset disabled form name></fieldset>
属性
在fieldset元素中使用的属性如下:
-
disabled: 这将禁用字段集中的所有元素 -
form: 这是form属性所属的表单的 ID -
name: 这是字段集的名称
描述
fieldset元素允许我们将相关的输入项组合在一起。大多数浏览器的默认样式是在字段集周围添加边框。
如果第一个元素是legend元素,则字段集将使用该元素作为其标签。
下面是使用fieldset元素的示例:
<form action="processForm" method="post">
<fieldset>
<legend>This is a fieldset</legend>
<input type="text" name="text-input" />
</fieldset>
</form>
相关内容
您还可以参考legend属性以了解更多关于fieldset元素的信息。
图例
legend元素的语法如下:
<legend></legend>
描述
legend元素将成为其子元素的fieldset元素的标签。
相关内容
您还可以参考fieldset元素以了解更多关于legend元素的信息。
标签
label元素的语法如下:
<label accesskey for form></label>
属性
在label元素中使用的属性如下:
-
accesskey: 这是accesskey元素的快捷键 -
for: 这是表单元素的 ID,也是其标签的 ID -
form: 这是与form属性关联的表单的 ID
描述
label元素用于标记输入。您可以将元素放入标签中或使用for属性。当标签正确链接到输入时,您可以点击标签,光标将定位到输入框。
下面是一个示例,涵盖了标记元素的不同方式:
<form action="processForm" method="post">
<label>First name: <input type="text" name="firstName" /></label>
<label for="lastNameInput">Last name: </label><input id="lastNameInput" type="text" name="lastName" />
</form>
输入
input元素的语法如下所示:
<input accept autocomplete autofocus checked disabled form formaction formenctype formmethod formnovalidate formtarget height inputmode max maxlength min minlength multiple name placeholder readonly required size spellcheck src step tabindex type value width></input>
属性
在input元素中使用的属性如下:
-
accept: 这用于指定网页接受的文件类型。 -
autocomplete: 这表示浏览器是否可以根据先前值自动完成此输入。 -
autofocus: 这允许浏览器自动将焦点放在元素上。这应该只用于一个元素。 -
checked: 这与单选按钮或复选框一起使用。这将选择页面加载时的值。 -
disabled: 这表示是否禁用元素。 -
form: 这表示表单的 ID。 -
formaction,formenctype,formmethod,formnovalidate, 和formtarget: 如果这些属性与按钮或图像相关联,将覆盖表单的值。 -
height: 这用于设置图像的高度。 -
inputmode: 这为浏览器提供了显示哪个键盘的提示。例如,您可以使用数字来指定仅键盘。 -
max: 这是系统的最大数字或日期时间。 -
maxlength: 这是可以在网页中接受的字符的最大数量。 -
min: 这是系统的最小数字或日期时间。 -
minlength: 这是字符的最小数量。 -
multiple: 这表示是否可以有多个值。这与email或file一起使用。 -
placeholder: 这是当没有为该属性分配值时在元素中显示的文本。 -
readonly: 这使元素为只读格式。 -
required: 这是必须分配值且不能为空的元素。 -
size: 这是元素的大小。 -
src: 如果它是img类型,这将图像的 URL。 -
step: 这与min和max属性一起使用,以确定增量步骤。 -
tabindex: 这是使用 tab 键时元素的顺序。 -
type: 请参阅下一节以获取描述。 -
value: 这是元素的初始值。 -
width: 这是设置宽度的属性。
描述
input元素是获取用户数据的主要方式。根据使用的类型,该元素可能会有很大的变化。HTML5 增加了一些输入,同时也提供了验证。例如,email类型将验证电子邮件是否为有效的email。此外,类型还可以向浏览器提供有关要显示哪个键盘的提示。这对于拥有许多不同虚拟键盘的移动设备来说很重要。例如,tel类型将显示数字键盘而不是常规键盘。以下是不同类型键盘及其描述的概述:
-
button: 这是一个按钮。 -
checkbox: 这是一个复选框。 -
color: 对于大多数浏览器,这将创建一个颜色选择器;然而,HTML5 并不要求必须使用。 -
date: 这创建了一个日期选择器。 -
datetime: 这使用时区创建日期和时间选择器。 -
datetime-local: 这创建了一个没有时区的日期和时间选择器。 -
email: 这是一个用于电子邮件地址的文本输入。此类型会验证电子邮件。 -
file: 这选择一个文件。 -
hidden: 此属性不会显示,但值仍然是表单的一部分。 -
image: 这实际上创建了一个图像按钮。 -
month: 这可以输入月份和年份。 -
number: 这用于浮点数。 -
password: 这是一个文本输入,其中文本不会显示。 -
radio: 这是一个使用相同名称属性对多个元素进行分组控制的控件。只能从提供的列表中选择一个。 -
range: 这是一种选择数字范围的方式。 -
reset: 这将重置表单。 -
search: 这是一个文本输入。 -
submit: 这是一个提交表单的按钮。 -
tel: 这是一个输入电话号码的字段。 -
text: 这是你基本的文本输入。 -
time: 这是没有时区的时间。 -
url: 这是一个输入 URL 的字段。这将进行验证。 -
week: 这是输入周数的字段。
下面是 text、e-mail 和 tel 输入的示例:
<input type="text" name="name" placeholder="enter email"/>
<input type="email" />
<input type="tel" />
button
button 元素的语法如下:
<button autofocus disabled form formaction formenctype formmethod formnovalidate formtarget name type value></button>
属性
在 button 元素中使用的属性如下:
-
autofocus: 这允许浏览器自动聚焦于具有此属性的元素。这应仅用于一个元素。 -
disabled: 这表示是否禁用元素。 -
form: 这是表单的 ID。 -
formaction、formenctype、formmethod、formnovalidate和formtarget:如果这是一个按钮或图像,这些将覆盖表单的值。 -
name: 这是表单按钮的名称。 -
type: 这会改变按钮的功能。值包括submit——提交表单,reset——重置表单,button——默认不执行任何操作。 -
value: 这是元素的初始值。
描述
button 元素创建一个可点击的按钮。更改 type 属性将改变其行为。
下面是 reset 和 submit 按钮的示例:
<button type="reset">Reset</button>
<button type="submit">Submit</button>
select
select 元素的语法如下:
<select autofocus disabled form multiple name required size ></select>
属性
在 button 元素中使用的属性如下:
-
autofocus: 这允许浏览器自动聚焦于此元素。这应仅用于一个元素。 -
disabled: 这表示是否禁用元素。 -
form: 这是表单的 ID。 -
multiple: 这表示是否可以选择多个项目。 -
name: 这是元素的名称。 -
required: 这用于检查选项是否需要值。 -
size: 这确定元素的行数。
描述
button 元素与 option 元素一起使用。可以将多个 option 元素添加到列表中,以选择或选择。当表单提交时,将使用所选选项的值。
下面是一个示例:
<select name="select">
<option value="1">One</option>
<option value="2">Two</option>
</select>
参见
你也可以参考optgroup和option属性来了解更多关于button元素的信息。
optgroup
optgroup元素是选项组元素:
<optgroup disabled label></optgroup>
属性
在optgroup元素中使用的属性如下:
-
disabled: 这将禁用该组 -
label: 这是下拉菜单中的标题
描述
optgroup元素允许你将选项分组在一起。此元素的子元素需要是option元素。它们不可选择,也没有值。
这里是outgroup元素的一个例子,包含汽车品牌和型号:
<select name="cars">
<optgroup label="Ford">
<option value="Fiesta">Fiesta</option>
<option value="Taurus">Taurus</option>
</optgroup>
<optgroup label="Honda">
<option value="Accord">Accord</option>
<option value="Fit">Fit</option>
</optgroup>
</select>
参见
你也可以参考option和select元素来了解更多关于optgroup元素的信息。
option
option元素的语法如下:
<option disabled selected value></option>
属性
在option元素中使用的属性如下:
-
disabled: 这表示元素是否禁用。 -
selected: 这表示选项是否被选中。每个选中的元素只能设置一个选项。 -
value: 这表示option的值。
描述
option元素是select元素中的实际项目。它们可以是select或optgroup元素的子元素。
这里有一个例子:
<select name="select">
<option value="1">One</option>
<option value="2">Two</option>
</select>
参见
你也可以参考select和optgroup元素来了解更多关于option元素的信息。
textarea
textarea元素的语法如下:
<textarea autocomplete autofocus cols disabled form maxlength minlength name placeholder readonly required rows spellcheck wrap></textarea>
属性
在textarea元素中使用的属性如下:
-
autocomplete: 这表示浏览器是否可以根据先前值自动完成此输入。 -
autofocus: 这允许浏览器自动聚焦到该元素。这应该只用于一个元素。 -
cols: 这表示textarea元素的字数宽度。 -
disabled: 这表示是否禁用元素。 -
form: 这是表单的 ID。 -
maxlength: 这是最大字符数。 -
minlength: 这是最小字符数。 -
name: 这是元素的名称。 -
placeholder: 这是元素中没有值时显示的文本。 -
readonly: 这使元素只读。 -
required: 这表示元素是必需的,不能为空。 -
rows: 这表示textarea的行数。 -
spellcheck: 这表示元素是否应该进行拼写检查。 -
wrap: 这表示行如何换行。
描述
当你需要比单行更多的文本时,你会使用这个。
这里有一个例子:
<textarea cols="20" rows="10" placeholder="Input text here"></textarea>
绘图元素
在 HTML 的早期版本中,如果你想要一个图形或图像,你必须在其他应用程序中创建它,并使用img元素将其拉入你的文档。HTML5 引入了一些新的元素和功能,以替换旧元素,允许你在浏览器中绘制自己的图像。
canvas
canvas元素的语法如下:
<canvas height width></canvas>
属性
在canvas元素中使用的属性如下:
-
height:这是一个设置高度的属性 -
width:这是一个设置宽度的属性
描述
canvas 元素用于绘图。你可以使用 JavaScript 来绘制线条、形状和图像;从视频中提取帧;以及使用 WebGL 等功能。HTML 元素只是你用来进行绘图的画布(恰如其名!)。所有的交互都在 JavaScript 中进行。
下面是一个小 canvas 元素的示例:
<canvas height="400" width="400">
Your browser does not support the canvas element.
</canvas>
svg
svg 元素是 可缩放矢量图形(SVG)元素:
<svg height viewbox width ></svg>
属性
在 svg 元素中使用到的属性如下:
-
height:这是设置高度的属性。 -
viewbox:这个属性设置了元素的范围。它接受四个数字,分别对应min-x、min-y、width和height。 -
width:这是设置宽度的属性。
描述
SVG 并不是一个真正的 HTML 元素。它是一个拥有许多元素和属性的独立规范。有关于 SVG 的书籍完全就是写的这个。这个元素之所以存在,是因为你现在可以在 HTML 文档中创建内联 SVG。这为你提供了在二维绘图方面的很多灵活性,这是图像所不具备的。
下面是一个示例,展示了高度、宽度和视口之间的区别。视口占据了元素的范围,而高度和宽度则决定了元素的大小:
<svg preserveAspectRatio=""
width="200" height="100" viewBox="0 0 400 200">
<rect x="0" y="0" width="400" height="200" fill="yellow" stroke="black" stroke-width="3" />
</svg>
第二章。HTML 属性
HTML 是使用元素构建的。这些元素中的每一个都将具有属性。这些属性可以改变浏览器渲染元素的方式、配置它以及涉及该元素的行为。
本章的重点将完全集中在属性上。如果你不确定哪些属性适用于哪些元素,上一章几乎涵盖了几乎所有元素及其属性。
全局属性
这些是适用于每个 HTML 元素的属性。然而,你应该注意,尽管属性是可用的,但这并不意味着它实际上会做任何事情。
accesskey
accesskey 属性创建一个键盘快捷键以激活或聚焦到元素:
<element accesskey></element>
描述
accesskey 属性允许您创建键盘快捷键。这可以是一个由空格分隔的字符列表。大多数 Windows 上的浏览器将使用 Alt + accesskey,而大多数 Mac 上的浏览器将使用 Ctrl + Option + accesskey。
这里是一个使用可以聚焦于字符 q 的文本框的示例:
<input type="search" name="q" accesskey="q"/>
class
class 属性通常用于帮助对相似元素进行分组以供 CSS 选择器使用:
<element class></element>
描述
class 属性是最常用的属性之一。class 属性允许 CSS 定位多个元素并将样式应用于它们。除此之外,许多人还使用 class 属性来帮助在 JavaScript 中定位元素。
类名使用空格分隔的列表。
这里是一个将 search-box 类应用于元素的示例:
<input type="search" name="q" class="search-box"/>
contenteditable
contenteditable 属性将元素的内容设置为可编辑:
<element contenteditable></element>
描述
contenteditable 属性告诉浏览器用户可以编辑元素中的内容。contenteditable 属性的值应该是 true 或 false,其中 true 表示元素是可编辑的。
这里是一个使用 div 元素的示例:
<div contenteditable="true">Click here and edit this sentence!</div>
data-*
data-* 属性是元素的定制属性:
<element data-*></-></element>
描述
你可以给数据属性起任何名字,只要名字不以 XML 开头,不使用任何分号,并且没有大写字母。值可以是任何内容。
这里是一个具有 data-id 属性的项目列表。请注意,属性名 data-id 是任意的。你在这里可以使用任何有效的名称:
<li data-id="1">First Row</li>
<li data-id="2">Second Row</li>
<li data-id="3">Third Row</li>
dir
dir 属性定义文本方向:
<element dir></element>
描述
dir 属性是方向属性。它指定文本方向。以下是其可能的值:
-
auto:这允许浏览器自动选择方向 -
ltr:这允许浏览器选择从左到右的方向 -
rtl:浏览器选择从右到左的方向
这里是 ltr 和 rtl 属性的示例。
<div dir="ltr">Left to Right</div>
<div dir="rtl">Right to Left</div>
draggable
draggable 属性定义元素是否可拖动:
<element draggable-></element>
描述
draggable 属性允许元素被拖动。请注意,大多数元素还需要 JavaScript 才能完全工作:
这里是一个示例:
<div draggable="true">You can drag me.</div>
hidden
hidden属性阻止元素的渲染:
<element hidden></element>
描述
hidden属性用于隐藏元素。但是,隐藏的元素可以通过 CSS 或 JavaScript 覆盖并显示。这是一个布尔属性,因此包含此属性将值设置为true,排除它将值设置为false。
这里是一个示例:
<div hidden>This should not show</div>
id
id属性是元素的唯一标识符:
<element id></element>
描述
id属性是元素的唯一标识符。这用于片段链接以及在 JavaScript 和 CSS 中轻松访问元素。
这里是一个使用div元素的示例:
<div id="the-first-div">This is the first div.</div>
lang
lang属性定义元素中使用的语言:
<element lang></element>
描述
lang属性设置元素的语言。可接受的值应该是 BCP47 语言。这里不一一列举,但您可以在www.ietf.org/rfc/bcp/bcp47.txt上阅读标准。语言对于屏幕阅读器使用正确的发音等重要事项很重要。
这里是一个简单的英文示例:
<div lang="en">The language of this element is English.</div>
spellcheck
spellcheck属性指定是否可以使用拼写检查:
<element spellcheck></element>
描述
spellcheck属性是在 HTML5 中引入的。它将告诉浏览器是否对该元素进行拼写检查。值应该是true或false。
这里是一个使用textarea的示例:
<textarea spellcheck="false">Moste fo teh worsd r mispeld.</textarea>
style
style属性用于设置内联样式:
<element style></element>
描述
您可以直接使用style属性将 CSS 样式添加到元素中。您在这里可以使用任何在 CSS 中可以使用的样式规则。请记住,这将覆盖 CSS 中定义的任何其他样式。
这里是一个示例,将背景设置为红色,文本设置为白色:
<div style="background: #ff0000; color: #ffffff">This has inline styles.</div>
tabindex
tabindex属性设置 Tab 顺序:
<element tabindex></element>
描述
tabindex属性元素定义了当使用Tab键时元素将聚焦的顺序。您可以使用三种不同类型的值。第一个是负数。这表示它不在元素列表中。zero值表示浏览器应确定此元素的顺序。这通常是元素在文档中出现的顺序。这是一个正数,它将设置 Tab 顺序。
以下示例演示了您可以设置与文档中元素顺序不同的tabindex:
<input type="text" tabindex="1" />
<input type="text" tabindex="3" />
<input type="text" tabindex="2" />
title
title属性是提示文本:
<element title></element>
描述
title属性提供了关于元素的额外信息。通常,标题会作为元素的提示显示。例如,当使用图像时,这可能是图像的名称或照片的版权信息:
<p title="Some extra information.">This is a paragraph of text.</p>
杂项
属性的杂项分组将没有层次结构,因为它们可以用于许多不同的元素。
accept
accept属性为服务器提供类型列表:
<element accept></element>
元素
在accept属性中使用的元素是form和input。
描述
accept 属性允许你建议此表单或输入应接受的文件类型。你可以使用 audio/*、video/*、image/*、MIME 类型或扩展名。
这里有一个寻找 PNG 文件的例子:
<input type="file" accept=".png, image/png"/>
accept-charset
accept-charset 属性提供了支持的字符集列表:
<element accept-charset></element>
元素
form 元素用于 accept-charset 属性。
描述
accept-charset 属性设置了表单将接受的字符集。UTF-8 最常用,因为它接受许多语言中的许多字符。
这里是使用 charset 属性的一个例子:
<form accept-charset="UTF-8"></form>
action
action 属性是表单被处理的地方,其语法如下:
<element action ></element>
元素
form 元素用于 action 元素。
描述
action 属性包含将处理表单数据的 URL。
这里有一个例子:
<form action="form-process.php"></form>
alt
alt 属性是元素的替代文本:
<element alt ></element>
元素
在 alt 属性中使用的元素有 applet、area、img 和 input。
描述
alt 属性是当元素无法渲染代码时的替代文本。文本应向用户传达与图像相同的信息。
一些浏览器(Chrome 是最常用的)不会显示文本,你可能需要使用 title 属性。这不是标准化的行为。
这里使用了一个图像的例子:
<img alt="Login button." src="img/non-loading-image.png"/>
async
async 属性用于脚本的异步执行:
<element async ></element>
元素
script 元素用于 async 属性。
描述
async 属性告诉浏览器异步加载和执行脚本。默认情况下,浏览器将同步加载脚本。异步加载将立即下载并解析脚本,而不会阻塞页面渲染。
这里有一个例子:
<script src="img/application.js" async></script>
autocomplete
autocomplete 属性定义了元素是否可以被自动完成:
<element autocomplete ></element>
元素
form 和 input 元素用于 autocomplete 属性。
描述
autocomplete 属性让浏览器知道是否可以从之前的值自动完成表单或输入。这可以有 on 和 off 作为值。
这里有一个例子:
<input type="text" autocomplete="off" placeholder="Will not autocomplete"/>
autofocus
autofocus 属性定义了元素是否会在元素上自动聚焦:
<element autofocus ></element>
元素
button、input、select 和 textarea 元素用于 autofocus 属性。
描述
autofocus 属性将焦点设置到元素上。这应该只用于一个元素。
这里是 autofocus 属性与文本输入的例子:
<input type="text" autofocus/>
autoplay
autoplay 属性定义了音频或视频轨道是否应该尽可能快地播放:
<element autoplay ></element>
元素
audio 和 video 元素用于 autoplay 属性。
描述
autoplay 属性将使元素一有机会就播放,而无需停止加载。
这里有一个包含音频文件的例子:
<audio autoplay src="img/audio.mps"></audio>
autosave
autosave 属性定义是否应保存先前值:
<element autosave ></element>
元素
input 元素用于 autosave 属性。
描述
autosave 属性指示浏览器保存输入到此输入框中的值。这意味着在下次页面加载时,这些值将被保留。它应该有一个浏览器可以关联保存值的唯一名称。此属性在某些浏览器中可能不起作用,因为它尚未完全标准化。
这里是一个示例:
<input type="text" autosave="textautosave" />
cite
cite 属性包含引用的来源:
<element cite ></element>
元素
blockquote、del、ins 和 q 元素用于 cite 属性。
描述
cite 属性通过提供 URL 来指向引用的来源。
这里是一个示例:
<blockquote cite="http://en.wikiquote.org/wiki/The_Good,_the_Bad_and_the_Ugly">
After a meal there's nothing like a good cigar.
</blockquote>
cols
cols 属性指定列数:
<element cols ></element>
元素
textarea 元素与 cols 属性一起使用。
描述
cols 属性指定 textarea 元素中的列数。
这里是它在使用中的示例:
<textarea cols="30"></textarea>
colspan
colspan 属性指定单元格应跨越的列数:
<element colspan ></element>
元素
td 和 th 元素用于 colspan 属性。
描述
colspan 属性指定表格单元格应跨越的列数。
这里是一个使用表格元素的示例:
<table>
<tr><td colspan="2">1 and 2</td></tr>
<tr><td>1</td><td>2</td></tr>
</table>
datetime
datetime 属性提供与此元素关联的日期和时间:
<element datetime ></element>
元素
del、ins 和 time 元素与 datetime 属性一起使用。
描述
datetime 属性应该是执行元素所暗示动作的时间。此属性主要用于 del 和 ins 元素,以显示删除或插入发生的时间。
这里是一个使用 del 的示例:
My name is <del datetime="2014-12-16T23:59:60Z">John</del>Josh.
disabled
disabled 属性定义元素是否可使用:
<element disabled ></element>
元素
button、fieldset、input、optgroup、option、select 和 textarea 元素用于 disabled 属性。
描述
disabled 属性使元素不可用。如果元素被禁用,则无法使用。这意味着按钮无法点击,文本区域和文本输入无法输入文本,下拉列表无法更改,等等。
这里是一个使用 button 元素的示例:
<button disabled>This is a disabled button</button>
download
download 属性设置链接以下载资源:
<element download ></element>
元素
a 元素用于 download 属性。
描述
download 属性指示当点击时浏览器下载资源。这意味着当点击 a 元素时,将出现一个保存对话框,并将属性值作为默认名称。
这里是一个示例:
<a href="example.pdf" download="example.pdf">Save the PDF</a>
content
content 属性为 name 属性提供值:
<element content ></element>
元素
meta 元素用于 content 属性。
描述
content 属性是 meta 标签的属性。它用作 name 属性的值。
这里是一个示例:
<meta name="example" content="value for example" />
controls
controls 属性定义是否应显示控件:
<element controls ></element>
Elements
audio和video元素用于controls属性。
描述
controls属性告诉浏览器显示媒体文件的控件。这是一个布尔属性。
下面是一个音频示例:
<audio controls src="img/example.mp3"></audio>
for
for属性设置与该属性关联的元素:
<element for ></element>
元素
label元素与for属性一起使用。
描述
for属性指定与标签关联的表单输入。这使用输入元素的 ID 指定。标签还将允许用户点击它并聚焦到输入。
下面是一个带有文本输入的示例:
<label for="username">Username</label>
<input type="text" id="username" name="username" />
表单
form属性设置与该输入关联的表单:
<element form ></element>
元素
button、fieldset、input、labellable、object、output、select和textarea元素用于form属性。
描述
form属性引用这些控件所在的表单:
<form method="get" id="example-form">
</form>
<input type="text" form="example-form" />
formaction
formaction属性设置元素的形式操作:
<element formaction ></element>
元素
button和input元素用于formaction属性中。
描述
formaction属性将覆盖此元素的表单操作。这应该是一个 URL。如果用于表单元素本身,此属性指定表单数据的目标。如果用于表单内的元素(例如,按钮),则覆盖表单本身声明的值。
下面是一个带有按钮的示例:
<form method="get" action="formaction.php">
<button formaction="buttonaction.php">Press me</button>
</form>
高度
height属性设置元素的高度:
<element height ></element>
元素
canvas、embed、iframe、img、input、object和video元素用于height属性。
描述
height属性设置元素的高度。只有上一节中列出的元素应该使用此属性,所有其他元素应使用 CSS 设置其高度。
注意
您可能会看到许多使用height的 HTML 文档。这不再有效,应使用 CSS 设置任何其他元素的高度。
下面是一个带有 canvas 元素的示例:
<canvas height="400" width="400"></canvas>
href
href属性给出资源的 URL:
<element href ></element>
元素
a、base和link元素用于href属性。
描述
元素的 URL 由href属性给出。
下面是一个带有锚点元素的示例:
<a href="http://www.google.com">Google</a>
hreflang
hreflang属性声明资源的语言:
<element hreflang ></element>
元素
a和link元素用于hreflang属性。
描述
hreflang属性是链接文档的语言。可接受的值应遵循 BCP47 语言标准。这里不一一列出,但您可以在www.ietf.org/rfc/bcp/bcp47.txt上阅读标准。
下面是一个示例:
<a href="http://www.google.com" hreflang="en">Google</a>
标签
label属性声明轨道的标题:
<element label ></element>
元素
track元素用于label属性。
描述
label属性与track元素一起使用,为轨道提供标题。
下面是一个带有视频副标题的示例:
<video src="img/sample.mp4">
<track kind="subtitles" label="English Subtitles" src="img/en.vtt" />
</video>
列表
list 属性给出选项列表:
<element list ></element>
元素
input 元素用于 list 属性。
描述
list 属性与 datalist 属性相关联,为 input 提供选项列表。
这个示例有一个用于文本输入的水果列表:
<input type="text" list="fruit" />
<datalist id="fruit">
<option>Apple</option>
<option>Banana</option>
</datalist>
loop
loop 属性定义元素是否应该循环媒体:
<element loop ></element>
元素
audio 和 video 元素用于 loop 属性。
描述
loop 属性是一个布尔属性,它将循环播放媒体。
这里是一个带有 audio 元素的示例:
<audio src="img/example.mp3" loop></audio>
max
max 属性定义最大值:
<element max ></element>
元素
input 和 progress 元素用于 max 属性。
描述
max 属性设置允许的最大数值或日期时间值。
这里是一个带有输入的示例:
<input type="number" min="0" max="5" >
maxlength
maxlength 属性定义最大字符数:
<element maxlength ></element>
元素
input 和 textarea 元素用于 maxlength 属性。
描述
maxlength 属性设置最大字符数。
这里是一个带有输入的示例:
<input type="text" maxlength="5">
media
media 属性设置链接资源的媒体:
<element media ></element>
元素
a、area、link、source 和 style 元素用于 media 属性。
描述
media 属性指定此资源针对的媒体。通常,此属性与链接和 CSS 一起使用。标准值是 screen、print 和 all。screen 值用于在显示器上显示,print 值用于打印,all 值是两者都适用。不同的浏览器确实有几个其他值,但没有一个可以在所有浏览器上工作。
这里是一个使用 CSS 创建打印样式的示例:
<link rel="stylesheet" href="print.css" media="print"/>
method
method 属性定义表单的 HTTP 方法:
<element method ></element>
元素
form 元素用于 method 属性。
描述
method 属性设置表单的 HTTP 方法。两个值是 GET,这是默认值,和 POST。
这里是一个使用 POST HTTP 方法提交的表单示例:
<form method="post" action="formaction.php"></form>
min
min 属性定义最小值:
<element min ></element>
元素
input 元素用于 min 属性。
描述
min 属性是 max 的反义词。它为输入设置最小值。
这里是一个示例:
<input type="number" min="2">
multiple
multiple 属性定义是否可以选择多个值:
<element multiple ></element>
元素
select 元素用于 multiple 属性。
描述
multiple 属性允许你选择多个值。这是一个布尔属性。
这里是一个示例:
<select multiple>
<option>First</option>
<option>Second</option>
</select>
name
name 属性是元素的名字:
<element name ></element>
元素
button、form、fieldset、iframe、input、object、select、textarea 和 meta 元素用于 name 属性。
描述
name 属性命名一个元素。这允许你在提交的表单中获取元素的值。
这里是一个带有输入的示例:
<input type="text" id="username" name="username" />
novalidate
novalidate 属性定义是否跳过验证:
<element novalidate ></element>
元素
form 元素用于 novalidate 属性。
描述
novalidate 属性设置表单在提交时不进行验证。浏览器将在不添加任何客户端代码的情况下验证输入。这是一个布尔属性。
这里是一个示例:
<form method="post" action="formaction.php" novalidate></form>
pattern
pattern 属性定义一个正则表达式:
<element pattern ></element>
元素
input 元素用于 pattern 属性。
描述
您可以使用正则表达式在此属性中验证输入。
这里是一个只有数字才有效的示例:
<input pattern="[0-9].+" type="text" />
placeholder
placeholder 属性为元素中的用户提供提示:
<element placeholder ></element>
元素
input 和 textarea 元素用于 placeholder 属性。
描述
当元素未被交互(没有值且不在焦点中)时,它将显示此属性中的文本。一旦元素被交互,值将消失。
这里是一个使用 input 的示例:
<input type="text" name="username" placeholder="Please enter username"/>
poster
poster 属性为视频提供图像:
<element poster ></element>
元素
video 元素用于 poster 属性。
描述
poster 属性应指向一个图像,该图像将成为视频元素的封面(或占位符),直到视频加载。
这里是一个示例:
<video src="img/video-about-dogs.mp4" poster="images/image-of-dog.png"></video>
readonly
readonly 属性定义元素是否可编辑:
<element readonly ></element>
元素
input 和 textarea 元素用于 readonly 属性。
描述
readonly 属性使元素只读或不可编辑。这是一个布尔属性。
这里是一个使用文本输入的示例:
<input type="text" readonly />
rel
rel 属性定义元素的关系:
<element rel ></element>
元素
a 和 link 元素用于 rel 属性。
描述
rel 属性是链接资源与文档之间的关系。通常,您会看到它与 link 元素和 CSS 或与 a 元素和 nofollow 的值一起使用。
这里是一个 CSS 示例:
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
required
required 属性定义在提交表单时元素是否为必填项:
<element required ></element>
元素
input、select 和 textarea 元素用于 required 属性。
描述
required 属性使元素在表单中成为必填项。表单在元素填写完毕之前不会提交。这是一个布尔属性。
这里是一个使用文本输入的示例:
<input required type="text" />
reversed
reversed 属性改变列表的显示顺序:
<element reversed ></element>
元素
ol 元素用于 reversed 属性。
描述
reversed 属性仅是有序列表的属性,它将以反向顺序渲染列表。项目本身不是反向的,而是编号列表的指示器是。这是一个布尔属性。
这里是一个示例:
<ol reversed>
<li>1</li>
<li>2</li>
<li>3</li>
</ol>
行
rows 属性设置文本区域的行数:
<element rows ></element>
元素
textarea 元素用于 rows 属性。
描述
rows 属性设置 textarea 中的行数。
这里是一个示例:
<textarea rows="30"></textarea>
rowspan
rowspan 属性设置单元格跨越的行数:
<element rowspan ></element>
元素
td 和 th 元素用于 rowspan 属性。
描述
rowspan 属性用于表格单元格元素。它将使单元格跨越指定行数的行。
这里是一个示例:
<table>
<tr><td rowspan="2">Pets</td><td>Dogs</td></tr>
<tr><td>Cats</td></tr>
</table>
scope
scope 属性定义了与元素关联的单元格:
<element scope ></element>
元素
td 和 th 元素用于 scope 属性。
描述
scope 属性指示单元格关联的内容。例如,这可以是 row 或 col。这是一个很大的好处,因为它有助于提高可访问性。当使用屏幕阅读器时,它有助于传达表格中行和列之间的关系。
这里是一个带有表格单元格的示例:
<table>
<tr><th>Name</th><th>Age</th></tr>
<tr><td scope="row">Gizmo</td><td>4</td></tr>
</table>
selected
selected 属性设置默认选择:
<element selected ></element>
元素
option 元素用于 selected 属性。
描述
selected 属性将在页面加载时设置选项为选中状态。每个 select 元素中应只设置一个 option 元素的 selected 属性。这是一个布尔属性。
这里是一个示例:
<select>
<option>Cats</option>
<option selected>Dogs</option>
</select>
size
size 属性设置元素的宽度:
<element size ></element>
元素
input 和 select 元素用于 size 属性。
描述
size 属性确定元素的宽度,除非元素是 input 和文本或密码。在这种情况下,它将确定元素可以显示的字符数。这以整数形式指定字符数。默认值是 20。
这里是一个带有文本输入的示例:
<input type="text" size="100" />
src
src 属性给出了元素的 URL:
<element src ></element>
元素
audio、embed、iframe、img、input、script、source、track 和 video 元素用于 src 属性。
描述
src 属性给出了元素的资源 URL。
这里是一个带有 image 元素的示例:
<img src="img/dogs.png" />
start
start 属性设置有序列表的起始数字:
<element start ></element>
元素
ol 元素用于 start 属性。
描述
start 属性将改变有序列表的起始数字。
这里是一个示例:
<ol start="10">
<li>1</li>
<li>2</li>
</ol>
step
step 属性确定每个数字之间的跳跃:
<element step ></element>
元素
input 元素用于 step 属性。
描述
step 属性与 input 元素和 type 属性为数字或日期时间的 input 元素一起使用。它确定每次增加的跳跃距离。
这里是一个带有数字输入的示例。在达到最大值之前,您只能增加 5 四次:
<input type="number" min="0" max="20" step="5" />
type
type 属性定义了元素的类型:
<element type ></element>
元素
button、input、embed、object、script、source 和 style 元素用于 type 属性。
描述
type 属性是最复杂的属性之一。它可以完全改变元素的外观和行为。例如,input。
这里是每个元素的列表:
-
button:以下为button属性的值:-
button:这是默认值 -
reset:这会重置表单 -
submit:这会提交表单
-
-
input:请参阅上一章中的输入元素部分。 -
embed:这将是指定嵌入资源的 MIME 类型。 -
object:这将是指定对象的 MIME 类型。 -
script:这将是指定的 MIME 类型。通常使用text/javascript。 -
source:这将是指定的 MIME 类型。 -
style:这将是指定的 MIME 类型。通常使用text/css。
这里有一个使用输入元素的例子:
<input type="password" />
value
value 属性设置元素的值:
<element value ></element>
元素
button、input、li、option、progress 和 param 元素用于 value 属性。
描述
value 属性将在页面加载时设置元素的值。
这里有一个使用文本输入元素的例子:
<input type="text" value="Hey!"/>
width
width 属性设置元素的宽度:
<element width ></element>
元素
canvas、embed、iframe、img、input、object 和 video 元素用于 width 属性。
描述
width 属性设置元素的宽度。
注意
你可能会看到许多使用宽度属性的 HTML 文档。这已经不再有效;应该使用 CSS 来设置其他元素的宽度。
这里有一个使用 canvas 元素的例子:
<canvas width="200" height="200"></canvas>
wrap
wrap 属性设置文本的换行方式:
<element wrap ></element>
元素
textarea 元素用于 wrap 属性。
描述
wrap 属性决定文本是否可以在 textarea 中换行。其值可以是硬值或软值。硬值会在文本中插入换行符。它还必须与 cols 属性一起使用,以便知道行尾的位置。软值不会插入任何换行符。
这里有一个例子:
<textarea cols="10" wrap="hard"></textarea>
第三章。CSS 概念和应用
层叠样式表(CSS)是设置 HTML 样式的首选方式。HTML 有一个样式元素和一个全局样式属性。这些使得编写难以维护的 HTML 变得非常容易。例如,让我们假设我们在一个 HTML 页面上有 10 个元素,我们希望这些元素的字体颜色为红色。我们创建一个span元素来包裹具有红色字体颜色的文本,如下所示:
<span style="color: #ff0000;"></span>
如果我们决定将颜色更改为蓝色,我们不得不更改该元素 10 次实例,然后乘以我们在页面上使用span元素的数量。这是完全不可维护的。
这就是 CSS 发挥作用的地方。我们可以针对我们希望应用特定样式的特定元素或元素组进行定位。CSS 允许我们定义这些样式,轻松更新它们,并从一处更改到另一处。
本书将重点介绍最常用的 CSS 选择器、单位、规则、函数和属性,这些来自 CSS1、CSS2.1 和 CSS3。在大多数情况下,这些都应该在任何浏览器中工作,但也有一些例外。一个很好的经验法则是新浏览器将出现更少的问题。
我们将快速概述不同类型的基本选择器。
基本选择器
选择器代表一个结构。这种表示随后用于 CSS 规则中,以确定哪些元素被选中并应用此规则中的样式。CSS 样式规则以瀑布效应的形式应用。每个匹配的规则也会传递给其每个子规则,根据选择器的权重进行匹配和应用。本节将仅关注最基本的选择器。
基本选择器包括类型选择器、通用选择器、属性选择器、类选择器、ID 选择器和伪类。
注意
所有 CSS 选择器都是不区分大小写的。选择器也可以分组在一起以共享规则。要分组选择器,只需用逗号分隔它们。考虑以下示例:
p { color: #ffffff; }
article { color: #ffffff }
这里,以下声明与前面的声明相同
p, article { color: #ffffff }
简单选择器
以下选择器都是 CSS 的简单选择器。
类型选择器
type选择器根据元素名称进行选择:
E
ns|E
在这里,E是元素名称,ns是命名空间。
描述
这是选择元素的最简单方式——使用它们的名称。在大多数情况下,当仅使用 HTML 时,你不需要担心命名空间,因为所有 HTML 元素都在默认命名空间中。可以使用星号来指定所有命名空间,例如,*|Element。
当使用此选择器时,它将匹配文档中的所有元素。例如,如果你有十五个h2元素,并使用单个h2元素,那么这个规则将匹配所有十五个。
这里有一些type选择器的示例。第一段代码将所有h1元素的字体颜色设置为红色。接下来的代码将红色作为所有p元素的背景颜色:
h1 { color: #ff0000; }
p { background: #ff0000; }
通用选择器
星号(*)代表任何和所有合格元素:
*
ns|*
*|*
在这里,ns 是一个命名空间。
描述
这实际上是一个通配符选择器。它将匹配每个元素。即使与其他选择器一起使用,这也是 true。例如,*.my-class 和 .my-class 是相同的。
虽然你可以将其用作单个选择器来匹配每个元素,但它在与其他选择器一起使用时最有用。按照我们前面的例子,我们可能想要选择任何是 article 元素后代的元素。这个选择器非常明确且易于阅读,请看以下语法:
article *
这里有一个例子。第一个例子使用属性选择器选择任何具有 hreflang 的元素,并且是英文的,第二个例子将选择文档中的所有元素:
*[hreflang="en"] { display: block; background:url(flag_of_the_UK); }
* { padding: 0; }
属性选择器
这些选择器将匹配元素的属性。有七种不同的属性选择器类型,如下所示:
[attribute]
[attribute=value]
[attribute~=value]
[attribute|=value]
[attribute^=value]
[attribute$=value]
[attribute*=value]
这些选择器通常由类型选择器或通用选择器 precede。
描述
这个选择器是一种在选择器规则中使用正则表达式语法的方法。每个选择器根据其使用方式会有不同的行为,因此它们会根据差异在此列出:
-
[attribute]: 这匹配具有[attribute]属性的元素,无论属性的值如何。 -
[=]: 值必须与精确匹配。 -
[~=]: 当属性接受值列表时使用。列表中的某个值必须匹配。 -
[|=]: 这个属性必须要么是精确匹配,要么值必须以紧跟其后的值开始,后面跟着一个-。 -
[^=]: 这个属性匹配具有此前缀的值。 -
[$=]: 这个属性匹配具有此后缀的值。 -
[*=]: 这个属性匹配值的任何子串。
真正展示这些选择器之间差异的最好方法是使用一些例子。我们将查看 lang 和 href 属性。例子将按照它们被引入的顺序排列。
这里是选择器将要选择的 HTML 文件。
<span lang="en-us en-gb">Attribute Selector</span>
<span lang="es">selector de atributo</span>
<span lang="de-at de">German (Austria)</span>
<a href="https://example.com">HTTPS</a>
<a href="http://google.com">Google</a>
<a href="http://example.com/example.pdf">Example PDF</a>
使用以下方法,我们应该有所有具有 lang 属性的 span 元素具有黑色背景,西班牙语将是灰色,德语将是红色,英语将是蓝色,具有 https 属性的锚点元素将是黄色,任何 PDF 将是红色,任何指向 Google 的锚点将是绿色。以下是前面描述的样式:
span[lang] { background-color: #000000; color: #ffffff; }
span[lang="es"] { color: #808080; }
span[lang~="de-at"] { color: #ff0000; }
span[lang|="en"] { color: #0000ff; }
a[href^="https"] { color: #ffff00; }
a[href$="pdf"] { color: #ff0000; }
a[href*="google"] { color: #00ff00; }
类选择器
这个选择器将根据元素的类属性匹配 HTML 元素。
element.class
.class or *.class
element.class.another-class
描述
这是最常用的选择器。基于 class 属性的选择允许你以正交的方式对元素进行样式化。类可以应用于许多不同的元素,并且我们可以以相同的方式为每个元素设置样式。
class 选择器可以堆叠,以便两个类都必须存在。
这里有一些包含不同元素的 HTML 代码,这些元素具有类属性:
<h1 class="red">Red Text</h1>
<span class="red">Red Text</span>
<span class="green black">Green text, black background</span>
<span class="green">Normal text</span>
这里是用于样式化 HTML 的 CSS:
.red { color: #ff0000; }
.green.black { color: #00ff00; background-color: #000000; }
当将red类应用于一个元素时,它将改变文本颜色为红色。复合的绿色和黑色将只选择定义了这两个类的元素。
ID 选择器
这个选择器将基于元素的ID属性进行匹配:
#id
element#id or *#id
描述
ID属性应该对文档是唯一的,所以ID选择器应该只针对一个元素。这与class选择器形成对比,class选择器可以用来选择多个元素。例如,你可以使用class选择器来使页面上的每个图像都有一定量的边距,并有一个专门针对你的标志的规则,使其有不同的边距。
这里是一个针对标志 ID 的 CSS 规则示例:
#logo { margin: 10px; }
组合器
组合器用于选择更复杂的结构。它们可以帮助选择其他方式难以选择的具体元素或元素组。
后代组合器
这个选择器指定一个元素必须被另一个元素包含。
组合器是空白字符。我们在这里明确定义它,以便清晰:
selector-a selector-b
描述
在这个选择器中使用的两个或多个语句可以是任何有效的选择器语句。例如,第一个可以是class选择器后面跟着type选择器。选择器之间的距离无关紧要。每个中间元素不需要列出,选择器就可以工作。
组合器可以堆叠。每个语句周围都有一个空白字符。这个选择器列表不需要包含所有内容,但为了选择器匹配层次结构,它确实需要存在。
这个选择器最好用于你只想在特定情况下样式化元素的情况。以下示例说明了这一点。
在这个第一个例子中,我们将针对具有“presidents”ID 的有序列表中的图像,并给它们添加一个红色边框。这是它的 HTML 代码:
<ol id="presidents">
<li><img src="img/pres01.png" alt="PortraitProtrait of George Washington" />George Washington</li>
<li><img src="img/pres02.png" alt="PortraitProtrait of John Adams" />John Adams</li>
</ol>
<img src="img/not_pres.png" alt="not a President - no border" />
这里是 CSS 规则:
ol#presidents img { border: 1px solid #ff0000; }
这里是一个例子,演示了选择器之间可以存在许多元素。这是非常随意的 HTML。
<div class="example">
I am normal.
<div>
<div class="select-me">
I am red.
<span class="select-me">I am red as well.</span>
</div>
</div>
</div>
这里是 CSS 规则:
.example .select-me { color: #ff0000; }
最后,这里是一个多重选择器层次结构的例子,其 HTML 如下:
<div class="first">Not the target
<div class="second">Not the target
<div class="third">I am the target.</div>
</div>
</div>
CSS 规则:
.first .second .third { color: #ff0000; }
子组合器
这个选择器针对特定的子元素:
element-a > element-b
描述
这与后代组合器非常相似,只是这个只针对子关系。第二个选择器必须是第一个直接包含在父元素中的直接后代。
这里是一个例子,它将只针对这个 HTML 中的第一个span:
<div>Here is an <span>arbitrary</span> <p><span>structure.</span></p></div>
这里是只设置第一个span颜色的 CSS 规则:
div > span { color: #ff0000; }
邻接兄弟组合器
这个选择器针对在层次结构中相邻的元素:
element-a + element-b
描述
这两个元素必须具有相同的父元素,第一个元素必须紧接第二个元素之后。
这里有一个示例,突出显示了选择器的工作方式。只有第二个 span 将应用此规则。最后一个 span 的前一个兄弟不是 span,因此它不会被选择器匹配。以下是 HTML 代码。
<p>Here are a few spans in a row: <span>1</span> <span>2</span> <em>3</em> <span>4</span></p>
CSS:
span + span { color: #ff0000; }
一般兄弟组合器
这个选择器针对任何与第一个元素有相同父元素并跟随它的元素。
element-a ~ element-b
描述
这与相邻兄弟组合器类似;不同之处在于,两个元素可以由其他元素分隔。
这里有一个示例,说明尽管第二个和第三个 span 之间有一个 em 元素,但第二个和第三个 span 都将被目标化。以下是 HTML 代码。
<p>Here are a few spans in a row: <span>1</span> <span>2</span> <em>3</em> <span>4</span></p>
这里是 CSS 规则。
span ~ span { color: #ff0000; }
选择器特定性
这不是本节中其他选择器规则之一。一个元素可以被多个规则目标化,那么如何知道哪个规则具有优先级?这就是特定性发挥作用的地方。你可以计算出哪个规则将被应用。以下是计算方法。请注意,内联样式将覆盖任何选择器特定性:
-
选择器中的
ID选择器数量用a表示 -
选择器中的类选择器、属性选择器和伪类的数量用
b表示 -
选择器中的
类型选择器和伪元素的数量用c表示 -
任何
通用选择器都被忽略
这些数字然后被连接起来。数值越大,规则优先级越高。让我们看看一些选择器示例。示例将由选择器和计算值组成:
-
h1:a=0b=0c=1,001或1 -
h1 span:a=0b=0c=2,002或2 -
h1 p > span:a=0b=0c=3,003或3 -
h1 *[lang="en"]:a=0b=1c=1,011或11 -
h1 p span.green:a=0b=1c=3,013或13 -
h1 p.example span.green:a=0b=2c=3,023或23 -
#title:a=1b=0c=0,100 -
h1#title:a=1b=0c=1,101
考虑这个问题的最简单方法是认为每个分组(a、b 或 c)应该是一个更小的元素组,从中选择。这意味着每一步都有更多的权重。例如,一个页面上可以有多个 h1 实例。所以,仅仅选择 h1 就有点模糊。接下来,我们可以添加一个 class、attribute 或伪类选择器。这应该是 h1 实例的子集。然后,我们可以通过 ID 搜索。这具有最高的权重,因为整个文档中应该只有一个。
这里是一个包含三个标题的示例 HTML。
<h1>First Heading</h1>
<h1 class="headings"><span>Second Heading</span></h1>
<h1 class="headings" id="third">Third Heading</h1>
这里是针对每个标题不同目标的 CSS 规则。第一个规则针对所有元素,但它的特定性最低,下一个规则位于中间,最后一个规则只针对一个元素。在下面的示例中,/* */ 表示注释文本:
h1 { color: #ff0000; } /* 001 */
h1.headings span { color: #00ff00; } /* 012 */
h1#third { color: #0000ff; } /* 101 */
伪类
伪类是使用文档树之外的信息的选择器。这些信息不在元素的属性中。这些信息可能在访问之间或甚至在访问期间改变。伪类总是有一个冒号后跟伪类的名称。
链接伪类
有两个互斥的链接伪类,即 :link 和 :visited。
:link
这选择未访问的链接。语法如下:
:link
描述
这个伪类存在于任何未访问的锚点元素上。浏览器可能会在一段时间后决定将链接切换回来。
这里有一个与 :visited 伪类一起的例子。这是它的 HTML:
<a href="#test">Probably not visited</a>
<a href="https://www.google.com">Probably visited</a>
这里是 CSS。我们可以假设你已经访问过 Google,所以链接可能呈绿色:
a:link { color: #ff0000; }
a:visited { color: #00ff00; }
:visited
这选择已访问的链接。语法如下:
:visited
描述
这个伪类存在于任何已访问的锚点元素上。
这里有一个与 :link 伪类一起的例子。这是它的 HTML:
<a href="#test">Probably not visited</a>
<a href="https://www.google.com">Probably visited</a>
这里是 CSS。我们可以假设你已经访问过 Google,因此第一个链接应该是红色,第二个链接将是绿色:
a:link { color: #ff0000; }
a:visited { color: #00ff00; }
用户操作伪类
这些类基于用户的操作生效。这些选择器不是互斥的,一个元素可以同时匹配多个。
:active
这用于元素被激活时:
:active
描述
:active 选择器在鼠标按钮按下但未释放时最常使用。这种样式可以被其他用户操作或链接伪类所取代。
这里有一个例子:
<a href="https://www.google.com">Google</a>
当你点击链接时,链接会变成绿色。这是它的 CSS:
a:active { color: #00ff00; }
:focus
这个选择器针对需要聚焦的元素。语法如下:
:focus
描述
当元素接受键盘输入时,它被认为是具有焦点。例如,一个文本输入元素,你可能已经通过制表符切换到它或点击在其中。
这里是一个文本输入示例:
<input type="text" value="Red when focused">
这里是 CSS。这也强调了你可以使用伪类,这允许使用更复杂的选择器:
input[type="text"]:focus { color: #ff0000; }
:hover
这个选择器在用户将鼠标悬停在元素上时针对元素:
:hover
描述
这用于用户将光标悬停在元素上时。一些浏览器(一个很好的例子是移动触摸设备,如手机)可能不会实现这个伪类,因为没有方法可以确定用户是否悬停在元素上。
这里有一个例子:
<span>Hover over me!</span>
当鼠标悬停在 span 中的文本上时,文本颜色会变成红色。这是它的 CSS:
span:hover { color: #ff0000; }
结构选择器
这些选择器允许你根据文档树选择元素;这使用其他选择器很难或不可能做到。这仅选择节点是元素,不包括不在元素内的文本。编号是 1- 基础索引。
:first-child
这针对另一个元素的第一个子元素:
:first-child
描述
这与 :nth-child(1) 相同。这个选择器很简单,将选择应用到的元素类型的第一个子元素。
这里有一个例子,它只会选择第一个段落元素。以下是 HTML 代码:
<p>First paragraph.</p>
<p>Second paragraph.</p>
这里是 CSS 代码。这将改变第一段文本的颜色为红色:
p:first-child { color: #ff0000; }
:first-of-type
这针对的是另一个元素的子元素中的第一个元素类型:
:first-of-type
描述
:first-of-type 属性与 :first-child 不同,因为它只有在它是第一个子元素时才会选择该元素。这等同于 :nth-of-type(1)。
这里有一个例子,即使它不是第一个子元素,也会选择第一个段落元素。以下是 HTML 代码:
<article>
<h1>Title of Article</h1>
<p>First paragraph.</p>
<p>Second paragraph.</p>
</article>
这里是 CSS 代码:
p:first-of-type { color: #ff0000; }
:last-child
这针对的是另一个元素的最后一个子元素:
:last-child
描述
这与 :nth-last-child(1) 相同。这个选择器很简单,将选择应用到的元素类型的最后一个子元素。
这里有一个例子,它只会选择最后一个段落元素。以下是 HTML 代码:
<p>First paragraph.</p>
<p>Second paragraph.</p>
这里是 CSS 代码。这将改变第二段和第一段的颜色为红色。这个选择器之所以有效,是因为即使在最基础的页面上,p 元素也是 body 元素的子元素:
p:last-child { color: #ff0000; }
:last-of-type
这针对的是另一个元素的子元素中的最后一个元素类型:
:last-of-type
描述
:last-of-type 属性与 :last-child 不同,因为它只有在它是第一个 last-child 属性时才会选择该元素。这等同于 :nth-last-of-type(1)。
这里有一个例子,它将选择最后一个段落元素。以下是它的 HTML 代码:
<article>
<p>First paragraph.</p>
<p>Second paragraph.</p>
<a href="#">A link</a>
</article>
这里是 CSS 代码:
p:last-of-type { color: #ff0000; }
:nth-child()
这将把所有子元素分割开,并根据它们存在的位置来选择它们:
:nth-child(an+b)
描述
这个选择器有一个参数,它在选择方面非常表达。这也意味着它比大多数其他 CSS 规则更复杂。以下是该参数的技术规范。这个选择器基于其前面的元素来选择元素。
参数可以分为两部分:部分 a 和部分 b。部分 a 是一个整数,后面跟着字符 n。部分 b 有一个可选的加号或减号,后面跟着一个整数。参数还接受两个关键字:even 和 odd。以 2n+1 为例。
以这种方式查看时,更容易理解。第一部分,an,是子元素被分割的部分。2n 值将使元素成对分组,3n 值将使元素成三组,依此类推。下一部分 +1 将选择分组中的该元素。2n+1 将选择每个奇数行项,因为它针对的是每个两个元素分组中的第一个元素。2n+0 或 2n+2 将选择每个偶数行项。第一部分,部分 a,可以省略,然后它将只选择整个组中的第 n 个子元素。例如,:nth-child(5) 将只选择第五个子元素,而不选择其他元素。
表行是使用此选择器的绝佳示例,因此我们将针对每个奇数行。以下是 HTML:
<table>
<tr><td>First (will be red)</td></tr>
<tr><td>Second</td></tr>
<tr><td>Third (will be red)</td></tr>
</table>
这里是 CSS:
tr:nth-child(2n+1) { color: #ff0000; }
:nth-last-child
这将针对从末尾开始的第 n 个元素:
:nth-last-child(an+b)
描述
此选择器计算后续元素的数量。计数逻辑与 :nth-child 相同。
这里有一个使用表格的示例。以下是 HTML:
<table>
<tr><td>First</td></tr>
<tr><td>Second</td></tr>
<tr><td>Third</td></tr>
<tr><td>Fourth</td></tr>
</table>
第一条 CSS 规则将改变每行中每隔一行的颜色,但由于它从末尾开始计数,第一行和第三行将被选中。第二条 CSS 规则将仅针对最后一行:
tr:nth-last-child(even) { color: #ff0000; }
tr:nth-last-child(-n+1) { color: #ff0000; }
参见
上一节 :nth-child。
:nth-last-of-type 和 :nth-of-type
这根据元素的类型和它们在文档中的位置选择元素:
:nth-last-of-type(an+b)
:nth-of-type(an+b)
描述
像所有其他 nth 选择器一样,这个选择器使用与 :nth-child 相同的逻辑。不同之处在于 nth-of-type 是 :nth-last-of-type 只按相同类型的元素分组。
这里有一个使用段落和跨度示例:
<p>First</p>
<span>First Span</span>
<span>Second Span</span>
<p>Second</p>
<p>Third</p>
这里是 CSS。此规则将仅针对段落,并将奇数行变为红色:
p:nth-of-type(2n+1) { color: #ff0000; }
参见
上一节 :nth-child。
:only-child
这针对没有兄弟元素的元素:
:only-child
描述
当 :only-child 属性是元素的唯一子元素时,这将匹配。
这里有两个表格的示例,其中一个有多个行,另一个只有一个:
<table>
<tr><td>First</td></tr>
<tr><td>Second</td></tr>
<tr><td>Third</td></tr>
</table>
<table>
<tr><td>Only</td></tr>
</table>
这里是针对第二个表格中唯一行的 CSS:
tr:only-child { color: #ff0000; }
:only-of-type
这针对只有一个此类元素的情况:
:only-of-type
描述
这将仅在父元素下没有其他相同类型的兄弟元素时匹配。
这里有一个使用任意分隔来创建一个结构的示例,其中一个段落元素是其类型的唯一元素。以下是 HTML:
<div>
<p>Only p.</p>
<div>
<p>Not the </p>
<p>only one.</p>
</div>
</div>
这里是仅针对第一段元素的 CSS 规则:
p:only-of-type { color: #ff0000; }
验证
这些是伪类,可以用来针对输入元素的状态等。
:checked
此属性针对已选中的单选按钮或复选框:
:checked
描述
任何可以打开或关闭的元素都可以使用此选择器。到目前为止,这些是单选按钮、复选框和选择列表中的选项。
这里有一个包含 checkbox 和 label 值的示例:
<input type="checkbox" checked value="check-value" name="test" />
<label for="test">Check me out</label>
这里是一个 CSS 规则,它将仅在复选框被选中时针对标签:
input:checked + label { color: #ff0000; }
:default
这针对多个类似元素中的默认元素:
:default
描述
使用此选择器帮助定义一组元素中的默认元素。在表单中,这将默认按钮或从 select 元素中最初选中的选项。
这里有一个使用表单的示例:
<form method="post">
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>
这里是 CSS。这将仅针对提交输入,因为它默认:
:default { color: #ff0000; }
:disabled 和 :enabled
这些将根据它们的启用状态选择元素:
:disabled
:enabled
描述
在交互式元素上有一个可用的禁用属性。使用 :disabled 将针对具有 :disabled 属性的元素,而 :enabled 将执行相反的操作。
这里有一些包含两个输入的 HTML,其中一个被禁用:
<input type="submit" value="Submit" disabled/>
<input type="reset" value="Reset" />
这里是 CSS。禁用的输入项将文本颜色设置为红色,而其他输入项为绿色:
input:disabled { color: #ff0000; }
input:enabled { color: #00ff00; }
:empty
这针对没有子节点的元素:
:empty
描述
这针对没有子节点的节点。子节点可以是任何其他元素,包括文本节点。这意味着即使是一个空格也会算作一个子节点。然而,注释不会算作子节点。
这里是一个有三个div标签的示例。第一个是空的,下一个有文本,最后一个有一个空格。这是 HTML:
<div></div>
<div>Not Empty</div>
<div> </div>
这里是 CSS。只有第一个div将具有红色背景:
div { height: 100px; width: 100px; background-color: #00ff00; }
div:empty { background-color: #ff0000; }
:in-range 和 :out-of-range
这些选择器定位具有范围限制的元素:
:in-range
:out-of-range
描述
一些元素现在有可以应用的范围限制。当值超出这个范围时,:out-of-range选择器将定位它,而当值在这个范围内时,:in-range将定位它。
这里是一个使用数字类型输入的示例:
<input type="number" min="1" max="10" value="11" />
<input type="number" min="1" max="10" value="5" />
这里是 CSS。第一个输入项将具有红色文本,因为它超出了最大范围,而第二个输入项将具有绿色文本:
:in-range {color: #00ff00; }
:out-of-range { color: #ff0000; }
:invalid 和 :valid
:invalid 和 :valid 属性根据数据的有效性来定位元素:
:invalid
:valid
描述
某些输入元素具有数据有效性,一个很好的例子是电子邮件元素。选择器根据数据是否有效来选择。你应该注意,一些元素始终是有效的,例如文本输入,而一些元素永远不会被这些选择器定位,例如div标签。
这里是一个电子邮件输入的示例:
<input type="email" value="test@test.com" />
<input type="email" value="not a valid email" />
这里是 CSS。第一个输入项将是绿色,因为它有效,而其他输入项将是红色:
:valid {color: #00ff00; }
:invalid { color: #ff0000; }
:not 或否定
:not 属性否定一个选择器:
:not(selector)
描述
:not 参数必须是一个简单选择器,并将定位到:not参数不是true的元素。这个选择器不会增加规则的特定性。
这里是一个使用段落的示例:
<p>Targeted Element</p>
<p class="not-me">Non targeted element</p>
这里是 CSS。只有第一个段落将被定位:
p:not(.not-me) {color: #ff0000; }
:optional 和 :required
:optional 和 :required 属性分别定位可选或必需的元素。
:optional
:required
描述
这用于任何必需或可选的输入元素。
这里是一个有两个输入的示例——一个是必需的,另一个不是:
<input type="text" value="Required" required />
<input type="text" value="Optional" />
这里是 CSS。必需的输入项将具有红色文本,而可选的输入项将具有绿色文本:
:required { color: #ff0000; }
:optional { color: #00ff00; }
:lang()
:lang() 属性根据语言来定位:
:lang(language)
描述
这个选择器与属性选择器的工作方式不同;即,这将定位所有在特定语言中的元素,即使它们没有明确定义。属性选择器只会定位具有lang属性的元素。
这里是一个span元素的示例,它没有lang属性,但它是具有lang属性的 body 元素的子元素:
<body lang="en-us">
<span>This is English.</span>
</body>
这里是 CSS。第一个规则将匹配元素,但第二个规则不会匹配任何内容:
:lang(en) { color: #ff0000; }
span[lang|=en] { color: #00ff00; }
伪元素
这些是超出文档中指定内容的选择器。选择器选择的东西可能是文档中不存在的元素。伪元素不被视为简单选择器的一部分。这意味着您不能将伪元素用作:not()选择器的一部分。最后,每个选择器只能有一个伪元素。
注意
注意,所有伪元素都以双冒号(::)开头。这是在 CSS3 中引入的,以帮助区分具有单个冒号(:)的伪类。这很重要,因为在 CSS2 中,伪元素只有单个冒号。在大多数情况下,您应该使用双冒号。
::before 和 ::after
这些用于在所选元素之前或之后插入生成内容:
::before
::after e
描述
这将根据选择器将内容插入文档。内容是放置在目标元素之前还是之后取决于所使用的伪元素。请参阅生成内容部分,了解您可以插入的内容。
这里是一个使用::before和::after的例子。这将创建一个火鸡三明治。以下是 HTML 代码。
<p class="sandwich">Turkey</p>
这里是 CSS,它将在火鸡前后放置一片面包:
p.sandwich::before, p.sandwich::after
{ content: ":Slice of Bread:"; }
相关内容
生成内容
::first-letter
这针对元素的第一个字母:
::first-letter
描述
这将选择元素中的第一个字母,前提是它前面没有任何其他内容,例如一个img元素在字符之前会使::first-letter不选择第一个字符。任何在第一个字母之前或之后出现的标点符号都将包含在第一个字母中。这将选择任何字符,包括不仅仅是字母,还包括数字。
这仅适用于类似块容器,如块、list-item、table-cell、table-caption和inline-block元素。
注意
::first-letter伪元素只有在第一个字母位于第一格式行上时才会匹配。如果第一个字母出现之前有换行符,则不会选择它。
这里是一个例子,它不会选择第一个字母:
<p><br />First letter</p>
这里是 CSS:
p::first-letter { font-size: 2em; }
这里是一个例子:
<p>This is a long line of text that may or may not be broken up across lines.</p>
这里是 CSS。在"This"中的 T 将是所有其他字符字体大小的两倍:
p::first-letter { font-size: 2em; }
::first-line
::first-line属性针对元素的第一行:
::first-line
描述
这将针对类似块容器(如block box、inline-block、table-caption或table-cell)的第一格式行。
这里是一个例子,以下面的 HTML 为例:
<p>This is a long line of text that may or may not be broken up across lines based on the width of the page and the width of the element it is in.</p>
<p>This is the entire first line.</p>
这里是 CSS。这将使第一行(无论是什么)显示为红色:
p::first-line { color: #ff0000; }
::selection
这针对用户突出显示的文本:
::selection
描述
这个伪元素允许您对用户突出显示的任何文本进行样式设置。这个伪元素在 CSS3 中不存在,但它将是下一个版本的一部分。大多数浏览器仍然会尊重这个伪元素。
这里是一个例子:
<p>Highlight this to text.</p>
这里是 CSS。当文本被选中时,文本将在红色背景上显示为白色:
::selection { color: #ffffff; background: #ff0000; }
生成内容
这不是一个选择器,但与伪元素 ::before 和 ::after 一起使用。你可以生成的内容类型有限。以下是概述。
内容
这是将被放置在元素前后的内容:
content(none, <string>, <uri>, <counter>, open-quote, close-quote, no-open-quote, no-close-quote, attr(x))
参数
以下是参数及其描述:
-
none: 此参数不会生成任何内容 -
normal: 这是默认参数,等同于无 -
<string>: 这是指任何字符串文本内容 -
<uri>: 这将映射到一个资源,例如,一个图像 -
<counter>: 这可以用来作为counter()或counters()函数,在元素前后放置计数器 -
open-quote和close-quote: 这与生成的引用内容属性一起使用 -
no-open-quote和no-close-quote: 这不会添加内容,但会递增或递减引用的嵌套层级 -
attr(x): 这将返回目标元素的属性值
描述
此属性用于向文档添加内容。输出由使用的值控制。这些值可以组合起来创建更复杂的内容。
可以使用字符 \A 插入新行。只需记住,HTML 默认会忽略换行符。
这里有一些示例。这些示例将展示如何使用许多内容值:
<h1>First</h1>
<h1>Second</h1>
<h1 class="test">Attribute</h1>
<h2>Line Break</h2>
<blockquote>Don't quote me on this.</blockquote>
这里是 CSS 代码。h1 元素将带有“章节”这个词,并在每个前面加上一个数字。h2 元素的内容将有一个换行符。最后,blockquote 将有一个开引号和一个闭引号:
h1 { counter-increment: chapter; }
h1::before { content: "Chapter" counter(chapter) ": " attr(class) ; }
h2::before { content: "New\A Line"; white-space: pre; }
blockquote::before { content: open-quote; }
blockquote::after { content: close-quote; }
引号
引号指定了哪些字符用作开引号和闭引号:
quotes: [<string> <string>]+
参数
<string> <string>: 这些是表示开引号和闭引号的字符对。你可以多次使用它来创建引用的层级。
描述
我们可以使用此属性来设置使用的引号类型。
这里有一个包含嵌套引用的示例:
<blockquote>Don't quote me <blockquote>on</blockquote> this.</blockquote>
引号是完全任意的。以下是 CSS 代码:
blockquote { quotes: ":" "!" "&" "*"; }
第四章:CSS 属性 - 第一部分
CSS 属性是标记语言(HTML、SVG、XML 等)中元素的特性,它们控制其样式和/或表现。这些特性是 W3C 不断发展的标准的一部分。
一个 CSS 属性的简单例子是border-radius:
input {
border-radius: 100px;
}
CSS 属性的数量多得令人难以置信,学习它们所有几乎是不可能的。更不用说,还有一些 CSS 属性需要供应商前缀(-webkit-、-moz-、-ms-等等),这使得这个方程式变得更加复杂。
供应商前缀是添加到 CSS 属性(有时也是 CSS 值)开头的简短 CSS 片段。这些代码片段直接与浏览器制造商的公司(“供应商”)或浏览器的 CSS 引擎相关。
有四个主要的 CSS 前缀:-webkit-、-moz-、-ms-和-o-。它们在这里解释:
-
-webkit-:这指的是 Safari 的引擎,Webkit(Google Chrome 和 Opera 过去也使用这个引擎) -
-moz-:这代表 Mozilla,它是 Firefox 的创造者 -
-ms-:这代表 Microsoft,它是 Internet Explorer 的创造者 -
-o-:这代表 Opera,但仅针对旧版本的浏览器
Google Chrome 和 Opera 都支持-webkit-前缀。然而,这两个浏览器已经不再使用 Webkit 引擎了。它们的引擎被称为 Blink,由 Google 开发。
一个带有前缀的 CSS 属性的简单例子是column-gap:
.column {
-webkit-column-gap: 5px;
-moz-column-gap: 5px;
column-gap: 5px;
}
知道哪些 CSS 属性需要前缀是徒劳的。这就是为什么保持对CanIUse.com的持续关注很重要。然而,使用Autoprefixer或-prefix-free等工具自动化前缀过程,或者在预处理器中使用 mixin 等,也同样重要。
然而,供应商前缀不在本书的范围内,所以我们讨论的属性不包含任何供应商前缀。如果您想了解更多关于供应商前缀的信息,您可以访问Mozilla 开发者网络(MDN)tiny.cc/mdn-vendor-prefixes。
让我们开始滚动 CSS 属性的参考。
动画
与需要第三方应用程序和插件的 Flash 旧时代不同,今天我们可以仅通过 CSS 实现几乎相同的事情,具有更少的开销,更好的性能,以及更大的可扩展性。
忘记插件和第三方软件!我们需要的只是一个文本编辑器,一些想象力,以及一点耐心来理解 CSS 带来的动画概念。
基础标记和 CSS
在我们深入所有动画属性之前,我们将使用以下标记和动画结构作为我们的基础:
HTML:
<div class="element"></div>
CSS:
.element {
width: 300px;
height: 300px;
}
@keyframes fadingColors {
0% {
background: red;
}
100% {
background: black;
}
}
在示例中,我们只会看到.element规则,因为 HTML 和@keyframes fadingColors将保持不变。
小贴士
@keyframes 声明块是一个可以应用于任何元素的定制动画。当应用时,元素的背景将从红色变为黑色。
好的,让我们来做这个。
animation-name
animation-name CSS 属性是我们想要执行的 @keyframes at 规则的名称,它看起来是这样的:
animation-name: fadingColors;
描述
在 HTML 和 CSS 基础示例中,我们的 @keyframes at 规则有一个动画,背景颜色从红色变为黑色。那个动画的名字是 fadingColors。
因此,我们可以这样调用动画:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
}
这是一个使用长语的合法规则。显然,它没有任何问题。问题是,除非我们添加 animation-duration,否则动画不会运行。
animation-duration
animation-duration CSS 属性定义了动画完成一个周期所需的时间,它看起来是这样的:
animation-duration: 2s;
描述
我们可以指定单位,使用 s 表示秒或使用 ms 表示毫秒。指定一个单位是必需的。指定 0s 的值意味着动画实际上永远不会运行。
然而,由于我们确实想让动画运行,我们这样做:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
}
如前所述,这将使一个盒子在 2 秒内从其红色背景变为黑色,然后停止。
animation-iteration-count
animation-iteration-count CSS 属性定义了动画应该播放的次数,它看起来是这样的:
animation-iteration-count: infinite;
描述
这里有两个值:infinite 和一个 数字,例如 1、3 或 0.5。不允许使用负数。
将以下代码添加到前面的示例中:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
}
这将使一个盒子从其红色背景变为黑色,然后再次从红色背景开始,并再次变为黑色,无限循环。
animation-direction
animation-direction CSS 属性定义了动画在周期之后应该播放的方向,它看起来是这样的:
animation-direction: alternate;
描述
有四个值:normal、reverse、alternate 和 alternate-reverse。
-
normal:这使得动画向前播放。这是默认值。 -
reverse:这使得动画向后播放。 -
alternate:这使得动画在第一个周期中向前播放,然后在下一个周期中向后播放,然后再向前播放,以此类推。此外,时间函数也会受到影响,所以如果我们有ease-out,当反向播放时,它会被ease-in替换。我们将在一分钟内查看这些时间函数。
-
alternate-reverse:这与alternate相同,但动画从结束处开始向后播放。
在我们当前的例子中,我们有一个连续的动画。然而,当从黑色(动画的结束)变为红色(动画的开始)时,背景颜色有一个“硬停止”。
让我们创建一个更“流畅”的动画,通过让黑色背景淡入红色,然后红色再淡入黑色,没有任何硬停止。基本上,我们正在尝试创建一个“脉冲”效果:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
animation-delay
animation-delay CSS 属性允许我们定义动画应该何时开始。这意味着一旦动画被应用到元素上,它将在开始运行之前遵守延迟。
它看起来像这样:
animation-delay: 3s;
描述
我们可以使用 s 表示秒或使用 ms 表示毫秒来指定单位。指定单位是必需的。
允许使用负值。请考虑使用负值意味着动画应该立即开始,但它将在动画中开始时处于中间位置,持续时间为负值的相反时间。
谨慎使用负值。
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
}
这将使动画在 3 秒后开始。
animation-fill-mode
animation-fill-mode CSS 属性定义了在动画执行时间之外应用于元素的哪些值。基本上,是在动画执行时间之外。
它看起来像这样:
animation-fill-mode: none;
描述
有四个值:none、forwards、backwards 和 both。
-
none:在动画前后不应用任何样式。 -
forwards:动画元素将保留最后一个关键帧的样式。这是最常用的值。 -
backwards:动画元素将保留第一个关键帧的样式,并且在animation-delay期间这些样式将保持不变。这可能是最不常用的值。 -
both:动画元素在开始动画之前将保留第一个关键帧的样式,在动画完成后将保留最后一个关键帧的样式。在许多情况下,这几乎与使用forwards相同。
之前的属性更适合用于有结束和停止的动画。在我们的例子中,我们使用的是淡入/脉冲动画,所以最好的属性是 none。
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
}
animation-play-state
animation-play-state CSS 属性定义了动画是正在运行还是暂停,看起来像这样:
animation-play-state: running;
描述
有两个值:running 和 paused。这些值是自我解释的。
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
}
在这种情况下,将 animation-play-state 定义为 running 是多余的,但我列出它是为了举例。
animation-timing-function
animation-timing-function CSS 属性定义了动画在其周期中速度应该如何进展,看起来像这样:
animation-timing-function: ease-out;
对于 Bézier 曲线(我们将在下一分钟看到 Bézier 曲线是什么),有五个预定义的值,也称为缓动函数:ease、ease-in、ease-out、ease-in-out 和 linear。
ease
ease 函数在开始时急剧加速,并在周期中间开始减速,看起来像这样:
animation-timing-function: ease;
ease-in
ease-in 函数开始缓慢加速,直到动画突然结束,看起来像这样:
animation-timing-function: ease-in;
ease-out
ease-out 函数开始迅速,并逐渐减速到结束,看起来像这样:
animation-timing-function: ease-out;
ease-in-out
ease-in-out 函数开始时速度较慢,在周期中间变得很快。然后它开始减速,直到周期结束。它看起来是这样的:
animation-timing-function:ease-in-out;
线性
linear 函数具有恒定的速度。不会发生任何类型的加速度。它看起来是这样的:
animation-timing-function: linear;
现在,缓动函数建立在名为贝塞尔曲线的曲线上,可以使用 cubic-bezier() 函数或 steps() 函数调用。
cubic-bezier()
cubic-bezier() 函数允许我们创建自定义的加速度曲线。大多数用例都可以从我们刚才提到的已定义的缓动函数(ease, ease-in, ease-out, ease-in-out 和 linear)中受益,但如果你愿意尝试新事物,cubic-bezier() 是你的最佳选择。
这就是贝塞尔曲线的样子:

参数
cubic-bezier() 函数接受四个参数,如下所示:
animation-timing-function: cubic-bezier(x1, y1, x2, y2);
X 和 Y 代表 x 和 y 轴。每个轴后面的数字 1 和 2 代表控制点。1 代表从左下角开始的控制点,而 2 代表右上角的控制点。
描述
让我们用 cubic-bezier() 函数来表示所有五个预定义的缓动函数:
-
ease:animation-timing-function: cubic-bezier(.25, .1, .25, 1); -
ease-in:animation-timing-function: cubic-bezier(.42, 0, 1, 1); -
ease-out:animation-timing-function: cubic-bezier(0, 0, .58, 1); -
ease-in-out:animation-timing-function: cubic-bezier(.42, 0, .58, 1); -
线性:
animation-timing-function: cubic-bezier(0, 0, 1, 1);
我不确定你是否和我一样,但我更喜欢使用预定义的值。
现在,我们可以开始调整和测试每个值到小数点后,保存它,并等待实时刷新完成其工作。然而,如果你问我,这太浪费时间了去测试。
小贴士
惊人的 Lea Verou 创建了最好的用于处理贝塞尔曲线的 Web 应用程序。你可以在 cubic-bezier.com 找到它。这是处理贝塞尔曲线最简单的方法。我强烈推荐这个工具。
之前展示的贝塞尔曲线图像来自 cubic-bezier.com 网站。
让我们在我们的例子中添加 animation-timing-function:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: ease-out;
}
steps()
steps() 时间函数并不非常常用,但如果你对 CSS 动画感兴趣,了解它是如何工作的则是必须的。
它看起来是这样的:
animation-timing-function: steps(6);
当我们想要动画执行一个定义的步骤数时,这个函数非常有用。
在我们的当前例子中添加 steps() 函数后,它看起来是这样的:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: steps(6);
}
这使得盒子从红色淡出到黑色,反之亦然,需要六个步骤。
参数
我们可以使用 steps() 函数的两个可选参数:start 和 end。
-
start: 这将使动画在每个步骤的开始运行。这将使动画立即开始。 -
end: 这将使动画在每个步骤的末尾运行。如果没有声明任何内容,这是默认值。这将在动画开始前给予一个短暂的延迟。
描述
在我们的当前示例中添加 steps() 函数后,它看起来是这样的:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: steps(6, start);
}
承认,当我们添加 steps() 函数时,示例中的脉冲效果并不太明显。然而,你可以在 Louis Lazarus 的这个笔上更清楚地看到它,当鼠标悬停在盒子上时,在 tiny.cc/steps-timing-function
这是一张来自 Stephen Greig 在 Smashing Magazine 文章中的图片,解释了 steps() 函数中的 start 和 end:

此外,steps() 函数有两个预定义值:step-start 和 step-end。
-
step-start:这与steps(1, start)相同。这意味着每次变化都发生在每个间隔的开始。 -
step-end:这与steps(1, end)相同。这意味着每次变化都发生在每个间隔的末尾。
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: step-end;
}
animation
animation CSS 属性是 animation-name、animation-duration、animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode 和 animation-play-state 的简写。
它看起来是这样的:
animation: fadingColors 2s;
描述
要使简单的动画工作,我们需要至少两个属性:animation-name 和 animation-duration。
如果你觉得所有这些属性让你感到不知所措,放松一下。让我帮你简单分解它们。
使用 animation 长格式,代码将如下所示:
CSS:
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
}
使用 animation 简写,这是推荐的语法,代码将如下所示:
CSS:
.element {
width: 300px;
height: 300px;
animation: fadingColors 2s;
}
这将使一个盒子在 2 秒内从红色背景变为黑色,然后停止。
最终 CSS 代码
让我们看看所有动画属性在一个最终的示例中是如何表现的,这个示例展示了长格式和简写样式。
长格式
.element {
width: 300px;
height: 300px;
animation-name: fadingColors;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 3s;
animation-fill-mode: none;
animation-play-state: running;
animation-timing-function: ease-out;
}
简写样式
.element {
width: 300px;
height: 300px;
animation: fadingColors 2s infinite alternate 3s none running ease-out;
}
小贴士
animation-duration 属性将始终首先考虑,而不是 animation-delay。所有其他属性可以在声明中按任何顺序出现。
这里是一个在 CodePen 上的演示:tiny.cc/animation
背景
CSS 背景属性处理 HTML 元素上的背景效果显示。
background-attachment
background-attachment CSS 属性定义了元素的背景相对于其包含父元素如何滚动,它看起来是这样的:
background-attachment: fixed;
描述
有三个值:scroll、fixed 和 local。
-
scroll:背景在其容器内不移动 -
fixed:背景始终固定在视口中,不受任何影响 -
local:背景在其容器和视口中滚动
CSS:
.scroll {
background-attachment: scroll;
}
.fixed {
background-attachment: fixed;
}
.local {
background-attachment: local;
}
这里是一个在 CodePen 上的演示:tiny.cc/css-background
background-blend-mode
background-blend-mode CSS 属性指定了元素的背景图像应该如何与其背景颜色混合,它看起来是这样的:
background-blend-mode: multiply;
描述
有 18 种可能的混合模式值:
-
color: 顶部颜色的色调和饱和度占主导地位,但底部颜色的亮度被添加。灰度级别被保留。 -
color-burn: 最终颜色是通过取底部颜色并取反,将值除以顶部颜色,然后取反该值得到的。 -
color-dodge: 最终颜色是除以顶部颜色的倒数得到的底部颜色。 -
darken: 最终颜色是每个通道中每个颜色最暗值的组合。 -
difference: 最终颜色是通过从背景图像和背景颜色的较亮颜色中减去较暗颜色得到的。 -
exclusion: 结果类似于difference,但对比度较低。 -
hard-light: 如果底部颜色较暗,则结果是multiply。然而,如果底部颜色较亮,则结果是screen。 -
hue: 取顶部颜色的色调,以及底部颜色的饱和度和亮度。 -
inherit: 最终颜色继承其父容器的混合模式。 -
initial: 这是默认值,没有任何混合。 -
lighten: 结果是每个通道中每个颜色的最亮值。 -
luminosity: 结果是顶部颜色的亮度,以及底部颜色的色调和饱和度。 -
multiply: 乘以顶部和底部颜色。这与在半透明胶片上打印颜色并将它们一层层叠放的效果相同。 -
normal: 最终颜色是顶部的颜色,无论其下是什么颜色。 -
overlay: 如果底部颜色较暗,则最终颜色为multiply。如果底部颜色较亮,则为screen。 -
saturation: 最终颜色是顶部颜色的饱和度加上底部颜色的色调和亮度。 -
screen: 对顶部和底部颜色取反,相乘,然后取反最终颜色。 -
soft-light: 与hard-light属性相同,但更柔和,就像将散射光指向最终颜色。
在以下示例中,我们将声明两个背景,一个图像和一个颜色,然后对它们应用混合模式:
CSS 长格式:
.element {
width: 500px;
height: 500px;
background-image: url('../images/image.jpg');
background-color: red;
background-blend-mode: multiply;
}
CSS 短格式:
.element {
width: 500px;
height: 500px;
background-image: url(../images/image.jpg) red;
background-blend-mode: multiply;
}
小贴士
注意,在第二个示例中,图像的路径不在引号内。单引号 '' 或双引号 "" 是可选的。
CSS-Tricks 有一个很好的 Pen 展示了所有这些混合模式。然而,我对其进行了改进。
所以,查看所有混合模式的 CodePen 示例 tiny.cc/background-blend-mode
background-clip
background-clip CSS 属性有助于定义元素背景是否延伸到其边框下方,其外观如下:
background-clip: border-box;
描述
有四个值:inherit、border-box、padding-box 和 content-box。
继承
这取自其父元素的值。
border-box
这使得背景覆盖整个容器,包括边框。
padding-box
这使得背景只延伸到边框开始的地方。
content-box
它的工作方式类似于 border-box,但它将考虑任何填充,从而在边框和背景之间创建一个间隙。
CSS:
.element {
background-clip: border-box;
}
这里是一个在 CodePen 上的演示:tiny.cc/background-clip
background-color
background-color CSS 属性定义了元素的实心背景颜色,其外观如下:
background-color: red;
描述
此外,transparent 在 CSS 中实际上是一种颜色。
提示
如果我们想要设置渐变背景颜色,我们必须使用 background-image 属性。这是因为渐变实际上是图像。
颜色值可以使用以下任何一种方法定义:
-
命名颜色
-
十六进制
-
RGB 和 RGBa
-
HSL 和 HSLa
CSS:
/*Named Color*/
.element {
background-color: red;
}
/*HEX*/
.element {
background-color: #f00;
}
/*RGB*/
.element {
background-color: rgb(255,0,0);
}
/*RGBa*/
.element {
/*Background has 50% opacity*/
background-color: rgba(255, 0, 0, .5);
}
/*HSL*/
.element {
background-color: hsl(0, 100%, 50%);
}
/*HSLa*/
.element {
/*Background has 50% opacity*/
background-color: hsla(0, 100%, 50%, .5);
}
background-image
background-image CSS 属性在元素的背景中设置图像或渐变,其外观如下:
background-image: url(../images/background.jpg);
或者,它也可以是这样的:
background-image: linear-gradient(red, orange);
描述
此属性支持 JPG、PNG、GIF、SVG 和 WebP 图像格式。
我们也可以使用 none 值来声明图像的缺失。
一个元素也可以在单个声明中使用多个背景图像。
当涉及到渐变时,有两种样式:线性和径向。
线性
它的语法是 linear-gradient。这些渐变可以垂直、水平或对角延伸。
径向
它的语法是 radial-gradient。这些渐变本质上是圆形的,默认情况下,它们将适应元素的尺寸。例如,如果元素是一个完美的正方形,它将创建一个完美的圆形径向渐变。然而,如果元素是一个矩形,那么径向渐变将看起来像一个椭圆形。
我们可以在渐变中添加我们想要的或需要的任意多的颜色。除非这是绝对必要的,否则我建议您避免这样做,因为它可能会对浏览器性能产生负面影响。
此外,为了让我们对渐变有更多的控制,我们可以定义渐变颜色的停止位置,以便下一个颜色可以开始。这被称为颜色停止。颜色停止可以用像素或百分比定义。百分比更常用,因为它的相对性质有助于保持渐变的完整性和比例。
CSS:
/*Graphic file*/
.element {
background-image: url(../images/bg-texture.jpg);
}
/*Multiple images*/
.element {
background-image:
url(../images/bg-icon.svg),
url(../images/bg-texture.jpg);
}
/*Linear gradient*/
.element {
background-image: linear-gradient(red, orange);
}
/*Linear Gradient with color stops*/
.element {
background-image: linear-gradient(red 40px, orange 25%, green);
}
/*Radial gradient*/
.element {
background-image: radial-gradient(red, orange);
}
/*Radial gradient with color stops*/
.element {
background-image: radial-gradient(red 40px, orange 25%, green);
}
background-origin
background-origin CSS 属性定义了背景如何在元素内部渲染,其外观如下:
background-origin: border-box;
描述
此属性的工作方式与 background-clip CSS 属性类似,但与 background-origin 不同的是,背景是缩放而不是裁剪。
有四个值:border-box、padding-box、content-box 和 inherit。
-
border-box:背景延伸到容器的边缘,但在边框下方 -
padding-box:背景延伸到与边框边缘对齐 -
content-box:背景在内容框内渲染 -
inherit:这是默认值
CSS:
.element {
background-origin: border-box;
}
这里是一个在 CodePen 上的演示:tiny.cc/background-origin
background-position
background-position CSS 属性允许我们在其父容器内放置背景(图像或渐变),其外观如下:
background-position: 10px 50%;
描述
我们可以使用三种不同类型的价值:预定义的 关键词,百分比,和 长度。
预定义关键词
值如 left, right, top, 和 bottom 是预定义的关键词。
百分比
值如 5% 和 80%.
长度
值如 15px 130px.
此属性需要您声明两个值:第一个值与 x 轴(水平)相关,第二个值与 y 轴(垂直)相关。
默认值是 0 0;这与 left top 完全相同。
CSS:
/*Default values*/
.element {
background-position: 0 0;
}
/*Keyword values*/
.element {
background-position: right bottom;
}
/*Percentages values*/
.element {
background-position: 5% 80%;
}
/*Length values*/
.element {
background-position: 15px 130px;
}
这里是一个在 CodePen 上的演示:tiny.cc/background-position
background-repeat
background-repeat CSS 属性有两个功能:
-
定义背景图像是否重复
-
确定背景图像的重复方式
它看起来像这样:
background-repeat: no-repeat;
或者,它也可能看起来像这样:
background-repeat-x: repeat;
描述
此属性仅在 background-image 已声明时才有效。
有四个值:repeat, repeat-x, repeat-y, 和 no-repeat.
-
repeat: 背景图像将在 x 和 y 轴上重复。这将完全填充容器。这是默认值。 -
repeat-x: 背景图像将在 x 轴上重复,因此,水平方向上。 -
repeat-y: 背景图像将在 y 轴上重复,因此,垂直方向上。 -
no-repeat: 背景图像不会重复,并且只会显示一个实例。
CSS:
/*Default value*/
.repeat { background-repeat: repeat; }
/*Repeat horizontally*/
.repeat-x { background-repeat: repeat-x; }
/*Repeat vertically*/
.repeat-y { background-repeat: repeat-y; }
/*No repeat*/
.no-repeat { background-repeat: no-repeat; }
这里是一个在 CodePen 上的演示:tiny.cc/background-repeat
background-size
background-size CSS 属性定义了背景图像的大小,其外观如下:
background-size: contain;
描述
有五个值:一个 长度 值,一个 百分比 值,auto,contain,和 cover。
长度值
这是我们使用以下单位之一时:px, em, in, mm, cm, vw, 等等。
百分比值
这是我们使用百分比如 50%, 85%, 等等情况。
auto
此值在相应的方向(水平或垂直)上缩放图像,以保持其宽高比,不变形。
contain
此值确保图像可以完全在其父容器内看到。图像的边缘不会溢出;它是“包含”的。
cover
此值缩放图像并取最长的维度(水平或垂直)。它确保图像完全覆盖该维度。如果容器和图像有不同的宽高比,则可能会发生溢出。
当声明背景的大小,我们可以使用一个或两个值。第一个值是 宽度,第二个值是背景图像的 高度。
使用一个值意味着第二个值设置为 auto。当使用两个值时,我们定义背景图像的 width 和 height 值。
我们可以使用我们想要的任何度量单位。像素、百分比和auto值是最常用的。
我们甚至可以在同一个容器中组合多个图像。背景缩写属性是处理这种情况的最佳方式。
CSS:
.contain {
background-size: contain;
}
.cover {
background-size: cover;
}
.auto {
background-size: auto;
}
.multiple {
background-image:
url(../images/image-1.jpg),
url(../images/image-2.jpg);
background-size: 150px 100px, cover;
}
这里是一个在 CodePen 上的演示:tiny.cc/background-size
背景
background CSS 属性是一个缩写,我们可以列出所有背景值。
我经常看到许多开发者编写长格式来声明单个值,例如颜色。以下是一个例子:
background-color: red;
虽然这完全没问题,但我更喜欢为几乎所有事情使用缩写版本:
background: red;
这更易于扩展,因为如果我们需要添加任何其他值,我们只需要将新值添加到这个声明中,而不是单独编写一个。然而,最终,这还是取决于个人风格。
CSS:
/*BG color*/
.element { background: red; }
/*BG color and image*/
.element { background: url(../images/bg.png) red; }
/*BG color, image and position*/
.element { background: url(../images/bg.png) 50% 50% red; }
/*BG color, image, position and do not repeat*/
.element { background: url(../images/bg.png) 50% 50% red no-repeat; }
/*BG color, image, position, do not repeat and size*/
.element { background: url(../images/bg.png) 50% 50% / contain red no-repeat; }
/*BG color, image, position, do not repeat, size and clip*/
.element { background: url(../images/bg.png) 50% 50% / contain red no-repeat content-box; }
/*BG color, image, position, do not repeat, size, clip and attachment*/
.element { background: url(../images/bg.png) 50% 50% / contain red no-repeat content-box fixed; }
盒模型
在网络中,每个元素都是一个正方形,因此它具有固有的特性:宽度、高度、填充、边框和边距。所有这些特性加在一起,构成了盒模型。
不可一世的盒模型是 CSS 行业中最常讨论的主题之一,因为 IE6 和 IE7 在当年是最受欢迎的浏览器。然而,它们在解释这个简单的 CSS 概念上存在重大问题。这意味着网页设计师和开发者不得不想出各种技巧来解决这个问题。至少在大多数情况下,那些日子已经过去了。
让我们继续讨论盒模型属性。
宽度
width CSS 属性指定了元素内容区域的宽度,其形式如下:
width: 10px;
或者,它也可能看起来像这样:
width: 10px 50px;
描述
内容区域位于元素的填充、边框和边距内部。
让我们讨论最常用的值和关键字:长度值、百分比值、auto、max-content、min-content和fit-content。
长度值
这基本上是我们使用以下单位之一时的情况:px、em、in、mm、cm、vw等等。
百分比值
这是我们使用百分比的时候,比如50%、85%等等。
auto
这是一个关键字值,允许浏览器选择元素的宽度。
max-content
这是一个关键字值,使容器宽度与其内容相匹配。
min-content
这是一个关键字值,根据其内容使容器尽可能小。
fit-content
这是一个关键字值,使容器宽度与其内容相匹配。这对于具有未知或可变宽度的容器效果很好。
你可以在 MDN 上找到更多信息:tiny.cc/mdn-width
CSS:
/*max-content*/
.element {
width: max-content;
}
/*min-content*/
.element {
width: min-content;
}
/*fit-content*/
.element {
width: fit-content;
}
这里是一个在 CodePen 上的演示:tiny.cc/width
高度
height CSS 属性指定了元素内容区域的高度,其形式如下:
height: 200px;
描述
内容区域位于元素的填充、边框和边距内部。
最常用的值是长度值、百分比值和 inherit。
长度值
这基本上是我们使用以下单位之一时的情况:px、em、in、mm、cm、vw 等等。
百分比值
这是我们使用百分比的情况,例如 50%、85% 等等。
inherit
使用这个关键字,元素将继承其父容器的高度。
你可以在 MDN 上找到更多信息:tiny.cc/mdn-height
CSS:
/*Length value*/
.element {
height: 200px;
}
/*Percentage value*/
.element {
height: 50%;
}
/*Inherit value*/
.element {
height: inherit;
}
padding
padding CSS 属性在元素的内部四侧创建空间,在其内容与边缘之间,其外观如下:
padding: 10px;
或者,它也可以是这样的:
padding: 10px 15px;
描述
边框和边距在内容区域之外,并且不受填充的影响。
padding 属性是 padding-top、padding-right、padding-bottom 和 padding-left 的简写。我们可以使用一个、两个、三个或所有四个值。
-
一个值:这意味着所有四侧都有相同的值。
-
两个值:第一个值用于顶部和底部。第二个值用于左侧和右侧。
-
三个值:第一个值用于顶部。第二个值用于左侧和右侧。第三个值用于底部。
-
四个值:第一个值用于顶部。第二个是用于右侧。第三个是用于底部。第四个是用于左侧。
不允许使用负值。
CSS:
/*Shorthand, ONE value: all four sides have the same padding*/
.element { padding: 10px; }
/*Shorthand, TWO values: Top & Bottom - Left & Right*/
.element { padding: 10px 15px; }
/*Shorthand, THREE values: Top - Left & Right - Bottom*/
.element { padding: 10px 15px 20px; }
/*Shorthand, FOUR values: Top - Right - Bottom - Left*/
.element { padding: 10px 15px 20px 25px; }
/*Longhand, all values. They can go in any order*/
.element {
padding-top: 10px;
padding-right: 15px;
padding-bottom: 20px;
padding-left: 25px;
}
margin
margin CSS 属性定义了一个元素的一侧、两侧、三侧或所有四侧的外部空间,其外观如下:
margin: 10px;
或者,它也可以是这样的:
margin: 10px 15px;
描述
margin 属性是 margin-top、margin-right、margin-bottom 和 margin-left 的简写。就像 padding 一样,我们可以使用一个、两个、三个或所有四个值。
-
一个值:这意味着所有四侧都有相同的填充。
-
两个值:第一个值用于顶部和底部。第二个值用于左侧和右侧。
-
三个值:第一个值用于顶部。第二个值用于左侧和右侧。第三个值用于底部。
-
四个值:第一个值用于顶部。第二个值用于右侧。第三个值用于底部。第四个值用于左侧。
允许使用负值。
CSS:
/*Shorthand, ONE value: all four sides have the same padding*/
.element { margin: 10px; }
/*Shorthand, TWO values: Top & Bottom - Left & Right*/
.element { margin: 10px 15px; }
/*Shorthand, THREE values: Top - Left & Right - Bottom*/
.element { margin: 10px 15px 20px; }
/*Shorthand, FOUR values: Top - Right - Bottom - Left*/
.element { margin: 10px 15px 20px 25px; }
/*Longhand, all values. They 1can go in any order*/
.element {
margin-top: 10px;
margin-right: 15px;
margin-bottom: 20px;
margin-left: 25px;
}
边距合并
边距有一个特定的行为。如果有两个堆叠的元素具有顶部和底部边距,则边距不会相加。相反,只考虑较大的值。
例如,我们有一个 <h1> 标题和一个 <p> 段落。标题的底部边距为 20px,而段落的顶部边距为 10px。
我们的感觉立即告诉我们总边距是 30px,但实际上,因为垂直边距会合并,只有最大的值会被考虑,在这种情况下,是 20px。
原因在于,许多元素,如我们示例中的标题和段落,都有顶部和底部边距。因此,合并边距允许内容和布局保持一致性,避免在堆叠元素之间创建不希望的多余空间。
这也很好,因为它节省了我们为每个具有顶部和底部边距的堆叠元素“抵消”边距的精力,再次避免创建那些额外空间。
我认为,合并边距是 CSS 边距属性的一个编辑功能。我希望前面的解释有助于理解这种行为。
这里是一个 CodePen 上的演示:tiny.cc/collapsing-margins
边框
border CSS 属性是一个简写属性,用于定义元素的边框厚度、样式和颜色。
border属性及其所有姐妹属性(border-width、border-style和border-color)及其变体都是不言自明的,因此不需要像先前属性那样有“描述”部分。
前面的 CSS 示例将有助于阐明这些属性的使用。
边框宽度
这是边框的厚度。可以使用px或em声明,但px会产生更可控的结果。
边框样式
这定义了线的类型或根本不显示线。它支持以下值:dashed、dotted、double、groove、hidden、inset、none、outset、ridge和solid。
边框颜色
这定义了线的颜色。它支持所有颜色模式:十六进制、RGB、RGBa、HSL、HSLs 和颜色名称。
请记住,所有 HTML 元素都是正方形,因此我们可以使用border-top-color、border-right-color、border-bottom-color或border-left-color来定位元素的任何一边。
简写值中的值的顺序不影响输出。
在以下示例中,简写语法中的顶部规则与长写语法中的底部规则达到完全相同的效果:
CSS:
/*Shorthand*/
.element-shorthand {
border: 10px solid green;
}
/*Longhand*/
.element-longhand {
/*Width*/
border-top-width: 10px;
border-right-width: 10px;
border-bottom-width: 10px;
border-left-width: 10px;
/*Style*/
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
/*Color*/
border-top-color: green;
border-right-color: green;
border-bottom-color: green;
border-left-color: green;
}
盒子模型
box-sizing CSS 属性允许我们通过默认方式更改浏览器理解盒子模型的方式,其语法如下:
box-sizing: border-box;
描述
有两个值:content-box和border-box。
content-box
这是默认值。填充、边框和边距值添加到元素的最终宽度和高度。这个值很少使用,正是因为我刚才描述的行为。
border-box
另一方面,由于这个值改变了盒子模型,填充和边框不会添加到元素的最终宽度和高度,而只会添加到边距。
CSS:
/*Padding, border and margin are added to the element's dimensions*/
.element {
box-sizing: content-box;
}
/*Padding and border are not added to the element's dimensions, only margin*/
.element {
box-sizing: border-box;
}
/*Always start your CSS with this rule*/
*, *:before, *:after {
box-sizing: border-box;
}
这里是一个 CodePen 上的演示:tiny.cc/box-sizing
最大高度
max-height CSS 属性定义了元素的最大的高度,其语法如下:
max-height: 150px;
描述
max-height属性覆盖了height属性。不允许使用负值。
最常用的值是长度值和百分比值。
长度值
这是我们使用以下单位之一的情况:px、em、in、mm、cm、vw等。
百分比值
这是我们使用百分比的情况,例如50%、85%等。
您可以在 MDN 上找到更多关于 MDN 的信息,链接为tiny.cc/mdn-max-height。
CSS:
/*Length value*/
.element {
height: 75px;
/*This property overrides height*/
max-height: 150px;
}
/*Percentage value*/
.element {
max-height: 65%;
}
max-width
max-width CSS 属性定义了元素的宽度最大值,它看起来是这样的:
max-width: 75px;
描述
max-width属性覆盖了width属性。不允许使用负值。
最常用的值是长度值和百分比值。
长度值
这是我们使用以下单位之一的情况:px、em、in、mm、cm、vw等。
百分比值
这是我们使用百分比的情况,例如50%、85%等。
您可以在 MDN 上找到更多关于 MDN 的信息,链接为tiny.cc/mdn-max-width。
CSS:
/*Length value*/
.element {
width: 150px;
/*This property overrides width*/
max-width: 75px;
}
/*Percentage value*/
.element {
max-width: 65%;
}
min-height
min-height CSS 属性定义了元素的最小高度,它看起来是这样的:
min-height: 300px;
描述
min-height属性覆盖了height和max-height属性。不允许使用负值。
最常用的值是长度值和百分比值。
长度值
这是我们使用以下单位之一的情况:px、em、in、mm、cm、vw等。
百分比值
这是我们使用百分比的情况,例如50%、85%等。
您可以在 MDN 上找到更多关于 MDN 的信息,链接为tiny.cc/mdn-min-height。
CSS:
/*Length value*/
.element {
height: 75px;
max-height: 150px;
/*This property overrides height and max-height*/
min-height: 300px;
}
/*Percentage value*/
.element {
min-height: 65%;
}
min-width
min-width CSS 属性定义了元素的宽度最小值,它看起来是这样的:
min-widht: 300px;
描述
min-width属性覆盖了width和max-width属性。
不允许使用负值。
最常用的值是长度值和百分比值。
长度值
这是我们使用以下单位之一的情况:px、em、in、mm、cm、vw等。
百分比值
这是我们使用百分比的情况,例如50%、85%等。
您可以在 MDN 上找到更多关于 MDN 的信息,链接为tiny.cc/mdn-min-width。
CSS:
/*Length value*/
.element {
width: 150px;
max-width: 75px;
/*This property overrides width and max-width*/
min-width: 300px;
}
/*Percentage value*/
.element {
min-width: 65%;
}
object-fit
object-fit CSS 属性定义了替换元素如何适应其内容框,它看起来是这样的:
object-fit: cover;
描述
替换元素是一个 HTML 元素,其内容和尺寸是内在的(由元素本身定义),而不是由 CSS 或其上下文或周围环境定义。
替换元素的例子有<img>、<video>、<audio>、<canvas>、<iframe>、<textarea>、<object>、<input>、<button>、<br>和<hr>。
现在,替换元素最重要的特性之一是我们不能通过 CSS 使用:before或:after伪元素选择器向它们应用生成内容。
当我们想要一组缩略图具有相同的宽度和高度,但又不扭曲图像时,这个属性会很有用。然而,缩略图的图像是由用户上传的,这意味着上传的图像可以是各种尺寸和不同的宽高比。object-fit CSS 属性可以帮助我们在这种情况下控制缩略图。
提示
替换元素内部的内容默认在水平和垂直方向上居中。然而,可以使用object-position属性重新定位内容。
有四个关键字值:contain、cover、fill、none和scale-down。
contain
替换元素内部内容的宽高比被保留。此内容尽可能放大,直到达到其宽度和高度定义的最大尺寸。由于宽高比的保护,可能会看到一些“未填充”的元素区域。
覆盖
替换元素内部内容的宽高比被保留。此内容尽可能放大,直到它完全填充或“覆盖”整个内容框。
填充
替换元素内部内容的宽高比不一定被保留。这意味着当填充整个内容框时,替换元素的内容在放大或缩小过程中可能会被拉伸或缩小。
无
不进行缩放。
缩小
这相当于声明了none或contain。这里的想法是,浏览器将尝试确定替换元素内部内容的最大具体尺寸,以便使其适合其内容框,同时保留替换元素内部内容的宽高比。
CSS:
img {
width: 15em;
height: 25em;
object-fit: contain;
}
这里是一个 CodePen 上的演示:tiny.cc/object-fit-position
object-position
object-position CSS 属性定义了替换元素内容的定位,其外观如下:
object-position: right bottom;
描述
如对象-fit CSS 属性的提示所述,默认情况下,替换元素的 内容放置在内容框的中心,即 50% 50%。
现在,此属性的行为类似于background-position CSS 属性。这意味着我们可以声明一个或两个值。
值可以是top、right、bottom或left等关键字值的长度或百分比。允许使用负值。
CSS:
img {
width: 15em;
height: 25em;
object-fit: contain;
object-position: right bottom;
}
这里是一个 CodePen 上的演示:tiny.cc/object-fit-position
边框半径
使用此属性,我们不仅可以制作圆角,还可以制作圆形、椭圆形和其他有趣的形状。
我承认“圆角”这个术语比“边框半径”要少一些晦涩。
border-radius
border-radius CSS 属性允许我们在几乎任何 HTML 元素上制作圆角,其外观如下:
border-radius: 20px;
描述
border-radius属性也是border-top-left-radius、border-top-right-radius、border-bottom-right-radius和border-bottom-left-radius属性的简写语法。
使用圆形或椭圆形,我们可以创建圆角:

有两个值:一个长度值和一个百分比值。
长度值
这时我们会使用以下单位之一:px、em、in、mm、cm、vw等等。
百分比值
这时我们会使用百分比,如50%、85%等等。
我们可以在同一个声明中使用一个、两个、三个或四个值。我们还可以使用斜杠符号"/"来分隔值组。
小贴士
有时,某些浏览器的背景颜色或纹理会“溢出”到圆角上。使用background-clip来解决这个问题。
CSS:
/*Longhand*/
.element {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
border-bottom-left-radius: 20px;
}
/*Shorthand*/
.element { border-radius: 20px; }
/*Two values: top-left-and-bottom-right - top-right-and-bottom-left*/
.element-1 { border-radius: 70px 7px; }
/*Three values: top-left - top-right-and-bottom-left - bottom-right*/
.element-2 { border-radius: 70px 7px 20px; }
/*Four values: top-left - top-right - bottom-right - bottom-left*/
.element-3 { border-radius: 70px 7px 20px 150px; }
/*Values divided with a slash "/" symbol */
.element-4 { border-radius: 70px 7px/20px 30px; }
/*Circle*/
.element-5 { border-radius: 200px; }
/*Ellipse*/
.element-6 { height: 100px; border-radius: 100%; }
/*Pill*/
.element-7 { height: 100px; border-radius: 100px; }
/*Half Pill: top-left - top-right - bottom-right - bottom-left*/
.element-8 { height: 100px; border-radius: 100px 0 0 100px; }
这里是一个 CodePen 中的演示:tiny.cc/css-border-radius
单位
CSS 单位是一种数据类型,我们可以用它来定义测量值,它看起来像这样:
max-height: 150px;
或者,它也可以这样:
transform: rotate(45deg);
数字和单位之间没有空格。
在大多数情况下,数字0(零)后面不需要单位。
如下所述,有几种长度单位类型。
相对长度单位
它们依赖于另一个元素的长度(通常是一个 DOM 中的父元素)与所讨论的元素直接相关。当其他元素的长度发生变化时,所讨论的元素的长度保持定义的比例。换句话说,没有必要再次声明子元素的长度。
描述
如果我们想要构建可伸缩的系统,相对单位总是最好的选择。在单个元素中设置值,然后修改该单个元素以影响整个系统可以节省大量时间和许多麻烦。
ex
ex后缀代表一个元素的 x-height。ex CSS 单位指的是小写字母x的高度。这个高度取决于字体。换句话说,如果我们使用 Arial 而不是使用 Verdana,即使值相同,高度也可能不同。
CSS:
.element {
padding: 2ex;
}
ch
ch后缀代表字符。ch CSS 单位指的是字符0(零)的宽度。这个宽度取决于字体。换句话说,如果我们使用 Arial 而不是使用 Verdana,即使值相同,宽度也可能不同。
CSS:
.element {
padding: 2ch;
}
em
em后缀代表字母m的发音,它代表了印刷和排版行业中小写m的宽度。在 CSS 中,em单位代表一个元素的font-size属性的计算。
这个单位可以与许多 CSS 属性一起使用,但最常见的使用是定义font-size元素。
然而,许多网页设计师和开发者更喜欢使用rem单位来避免em单位在嵌套元素(3-4 或更多级别)中存在的继承问题。
CSS:
.element {
font: 1.5em Arial, Helvetica, san-serif;
}
rem
rem 后缀表示术语 根元素 的缩写。rem CSS 单位表示标记文档中根元素的字体大小。标记文档不仅是一个 HTML 文档;它还可以是 XML、SVG 或其他基于标记的文档。
在本指南中,我们指的是 HTML 文档,既然如此,根元素就是 <html> 元素。
一种非常常见的做法是将 <html> 元素的字体大小设置为 62.5%。这样,当我们为其他元素设置字体大小时,我们仍然可以以像素为单位思考,但用 rem 单位来保持相对字体大小,以便在响应式项目中放大或缩小文档。
CSS:
html {
font-size: 62.5%;
}
h1 {
/*It's the same as 22px*/
font-size: 2.2rem;
}
百分比符号
% 符号就是它所暗示的,百分比。在 CSS 中,em 单位和百分比单位会产生相同的结果。百分比值,如其他相对单位一样,依赖于另一个值,通常是父元素的值。
与所有其他相对单位一样,百分比和响应式网页设计是相辅相成的。
CSS:
.element {
margin: 0 1%;
}
视口相对长度单位
这些单位与视口相关。如果视口的尺寸发生变化,使用视口相对长度值的属性将适应视窗的新尺寸。
描述
这些单位对我来说是救星。它们在响应式世界中实现了我们对字体所期望的功能:根据视口的宽度或高度放大或缩小。
让我们来了解一下。
vh
vh 后缀表示 视口高度。vh CSS 单位与视口的高度相关。vh 的值是视口高度的 1/100。
例如,如果我们将一个元素的 font-size 声明为 1vh,而浏览器窗口大小为 500px,那么字体大小就是 5px。
CSS:
.element {
font-size: 1vh;
}
vw
vw 后缀表示 视口宽度。vw CSS 单位与视口的宽度相关。vw 的值是视口宽度的 1/100。
例如,如果我们将一个元素的 font-size 声明为 1vh,而浏览器窗口大小为 1400px,那么字体大小就是 14px。
CSS:
.element {
font-size: 1vw;
}
vmin
vmin 后缀表示 视口最小值。vmin CSS 单位与视口的最小值相关,无论是其高度还是宽度。vmin 的值是视口最短边的 1/100。
例如,如果我们将一个元素的 font-size 声明为 1vmin,而浏览器的视口大小为 600 × 800,那么字体大小就是 6px。
CSS:
.element {
font-size: 1vmin;
}
vmax
vmax 后缀表示视口最大值。vmax CSS 单位与视口的最大值相关,无论是其高度还是宽度。vmax 的值是视口最长边的 1/100。
例如,如果我们将一个元素的 font-size 声明为 1vmax,而浏览器的视口大小为 600 × 800,那么字体大小就是 8px。
CSS:
.element {
font-size: 1vmax;
}
绝对长度单位
这些单位代表元素的物理尺寸。CSS 中的一些单位来自印刷世界,尽管它们不常用,但了解它们是很重要的。
描述
这些类型的单位直接与物理测量相关。当输出环境已知时,例如在打印中,它们工作得最好。
最常用的绝对单位是像素(px)。像素被熟知为屏幕上的单个点。问题是,那个点的尺寸没有行业标准。
换句话说,标准 LED/LCD 显示器(例如,显示器或电视)上的像素大小与高密度屏幕上的像素大小不同。即使是高密度屏幕之间的像素大小也不同。
让我们看看每个缩写的含义,并在本节末尾,我们将能够看到一个包含所有单位的单一示例。
cm
cm后缀代表厘米。
mm
mm后缀代表毫米。
in
in后缀代表英寸。
pc
pc后缀代表派卡。
pt
pt后缀代表点。
px
px后缀代表像素。
CSS:
所有以下值代表类似于16px字体大小的单位,但使用不同的长度单位。
/*Centimeter*/
.element { font-size: .43cm; }
/*Millimeter*/
.element { font-size: 4.3mm; }
/*Inch*/
.element { font-size: .17in; }
/*Pica*/
.element { font-size: 1pc; }
/*Point*/
.element { font-size: 12pt; }
/*Pixel*/
.element { font-size: 16px; }
角度数据类型
这些单位代表角度值。
描述
这些单位在需要通过transform属性旋转元素时使用。
除了deg数据类型外,其他角度数据类型的单位并不常见。
让我们来看看它们。
deg
deg后缀代表度。
grad
grad后缀代表梯度。
rad
rad后缀代表弧度。
turn
turn后缀不是一个缩写;它是实际单词转。一个完整圆周有一个转,所以如果我们想要将一个水平矩形旋转 90 度使其垂直,我们将定义它为.25turn,因为它是一个完整转的四分之一。
CSS:
所有以下值代表类似于元素 90 度转动的单位,但使用不同的角度数据类型:
/*Degrees*/
.element { transform: rotate(90deg); }
/*Gradians*/
.element { transform: rotate(100grad); }
/*Radians*/
.element { transform: rotate(89.535rad); }
/*Turn*/
.element { transform: rotate(.25turn); }
分辨率单位
这些单位代表任何给定输出或设备上像素的屏幕密度。与相对和绝对单位不同,必须在值0(零)后添加单位。
描述
当我们需要考虑密度屏幕时,分辨率单位将为我们做大量工作。它们用于媒体查询。
让我们看看它们是如何工作的。
dpi
dpi后缀代表每英寸点数。屏幕通常包含 72 或 96 dpi,而打印文档的 dpi 则大得多。1 英寸=2.54 厘米,因此1dpi≈ 0.39dpcm。
dpcm
dpcm后缀代表每厘米点数。1 英寸=2.54 厘米,因此1dpcm≈ 2.54dpi。
dppx
dppx后缀代表每像素点数。1dppx = 96dpi,由于 CSS 像素的 1:96 固定比率。
CSS:
/**@2x pixel ratio**/
/*Dots per inch*/
@media (min-resolution: 192dpi) { ... }
/*Dots per centimeter*/
@media (min-resolution: 75.5906dpcm) { ... }
/*Dots per pixel*/
@media (min-resolution: 2dppx) { ... }
持续时间单位
这些单位代表动画的持续时间,无论是秒还是毫秒。
描述
这些单位相当直接,仅在 CSS 动画中使用。
小贴士
你可能会认为,因为所有其他单位都使用两个、三个或四个字母的缩写(如px、dip、dpcm等)。始终记住:在声明秒单位时,只使用一个s。使用sec或secs是不正确的。
ms
ms后缀代表毫秒。1000ms = 1 秒。
s
s后缀代表秒。1s = 1000 毫秒。
CSS:
/*Milliseconds*/
.element { animation-duration: 3ms; }
.element { transition: .003s; }
/*Seconds*/
.element { animation-duration: 3s; }
.element { transition: 3000ms; }
列
CSS 列是流畅地分配长字符串内容并保持可伸缩性的最灵活方式。如果内容增长或减少,它将自动在声明的列的可用空间中重新流动。
虽然不一定是最理想的选择,但实际元素,如 DIV,也可以通过 CSS 的columns属性分布在列中。
让我们深入探讨。
column-count
column-count CSS 属性定义了元素列的数量,其外观如下:
column-count:3;
描述
我们可以使用一个数字值或关键字auto。
当我们使用auto关键字时,我们让浏览器决定在可用空间内可以容纳多少列。这是一个非常强大且稳健的响应式布局解决方案。但是,为了使此功能正常工作,我们需要声明column-width。
CSS:
/*Let the browser decide*/
.element {
column-count: auto;
column-width: 200px;
}
/*Specific number of columns*/
.element {
column-count: 3;
}
column-fill
column-fill CSS 属性控制内容如何在列之间分配,其外观如下:
column-fill: balance;
描述
有两个关键字:auto和balance。
-
auto:这意味着内容将按顺序填充。基本上,当空间变得可用时,内容将开始填充它。这使得父容器垂直增长,使列变高以适应内容。 -
balance:这意味着内容将在可用列中均匀分布。为了使此功能正常工作,我们需要在父容器上声明一个高度。这将确保列具有特定的高度。问题是,如果父容器变得太小,内容将不断流向父容器外部。
CSS:
/*Balance*/
.element {
column-fill: balance;
column-count: 4;
height: 400px;
}
/*Auto*/
.element {
column-fill: auto;
column-count: 4;
}
column-gap
column-gap CSS 属性定义了列之间的空间。在编辑术语中,这个空间是“边距”,其外观如下:
column-gap: 50px;
描述
有两个值:auto关键字和一个长度值。
-
auto:这是规范中定义的默认值,即1em。 -
长度值:我们使用px或em来定义这个值。
CSS:
/*Auto = 1em*/
.element {
column-gap: auto;
column-count: 4;
}
/*Length value: px or em*/
.element {
column-gap: 50px;
column-count: 4;
}
column-rule
column-rule CSS 属性创建或绘制一条垂直线,这条线“分隔”了列,其外观如下:
column-rule: 2px solid black;
描述
我们可以定义column-rule CSS 属性的三个方面:厚度或width;style,这是与border-style属性相同的样式;和color。
column-rule CSS 属性是以下属性的简写:
-
column-rule-width:这可以是一个长度值(一个数字),或者我们可以使用以下任何关键字:thin、medium或thick。 -
column-rule-style:这可以是任何border-style值,例如dotted、dashed、inset等。 -
column-rule-color:这是一个以任何格式定义的颜色:HEX、RGB或HSL。它还支持 alpha 通道,因此允许RGBa和HSLa。
CSS:
/*Length, solid line and RGBa*/
.element {
column-gap: auto;
column-count: 4;
column-rule: 2px solid rgba(0, 0, 0, .3);
}
/*Keyword, dotted and color name*/
.element {
column-gap: 50px;
column-count: 4;
column-rule: thick dotted black;
}
column-rule-color
column-rule-color CSS 属性定义了列之间的分隔线的颜色。
颜色可以用任何格式定义:HEX、RGB 或 HSL。它还支持 alpha 通道,因此允许 RGBa 和 HSLa。
CSS:
.element {
column-rule-color: red;
}
column-rule-style
column-rule-style CSS 属性定义了列之间的分隔线的样式。
它可以是任何 border-style 值,例如,dotted、dashed、inset 等。
CSS:
.element {
column-rule-style: dotted;
}
column-rule-width
column-rule-width CSS 属性定义了列之间分隔线的厚度(宽度)。
它可以是长度值(一个数字),或者我们可以使用以下任何关键字:thin、medium 或 thick。
CSS:
.element {
column-rule-width: 5px;
}
column-span
column-span CSS 属性将一个本应像列一样行为的元素变成一个跨越所有列的元素。该元素仍然是“列”,但现在它扩展了列的全宽,就像一个块元素。
有两个值,none 和 all,它们是自我解释的。
CSS:
.element {
column-span: all;
}
这里是一个在 CodePen 上的演示:tiny.cc/column-span
column-width
column-width CSS 属性定义了列的宽度。
当我们定义列的宽度时,浏览器会根据可用空间自动添加或删除列。
例如,如果我们说我们的列宽度是 200px,而父容器是 800px,那么浏览器将包括三列(考虑到默认的 column-gap 为 1em)。然而,如果容器至少 450px 宽,浏览器将适应两列。
CSS:
/*em value*/
.element {
column-width: 10em;
}
/*px value*/
.element {
column-width: 200px;
}
columns
columns CSS 属性是我们可以用来自定义 column-width 和 column-count 的缩写。
它可以在同一个声明中接受一个或两个值。值的顺序无关紧要,但声明 column-width 首先然后 column-count 第二是个好习惯。
CSS:
/*column-width and then column-count*/
.element {
columns: 300px 2;
}
弹性框(flexbox)
当涉及到在容器中排列元素时,Flexbox 是最有用的 CSS 模块之一。Flexbox 允许元素根据可用空间增长或缩小,以保持布局的完整性。
使用 Flexbox 是在基于浮动布局之后下一步,不仅因为它更容易操作,更容易理解其概念,而且还可能减少标记和 CSS。
小贴士
Flexbox 的一个强大伙伴是网格布局(Grid Layout),它仍处于早期开发阶段,浏览器支持有限。由于网格布局超出了本节范围,你可以在 Rachel Andrew 的项目网站 Grid By Example 上了解更多信息,网址为 gridbyexample.com/
在我们深入研究 Flexbox 属性之前,以下图表将帮助我们理解术语和方向:

让我们深入了解 Flexbox 属性。
flex-grow
这个属性定义了 flex 项目相对于其他 flex 项目通过 flex 增长因子应该增长多少,其表现形式如下:
flex--grow: 2;
描述
flex 增长因子是一个没有单位的数字。负值无效。
只要还有空间,flex 项目就会根据定义的增长因子增长。它可以在主轴或交叉轴上增长,具体取决于由flex-direction属性定义的方向,我们稍后会讨论这个属性。
CSS:
/*First flex item will take 1 unit of the available space*/
.element-1 { flex-grow: 1; }
/*Second and third flex items will take 2 units of the available space*/
.element-2 { flex-grow: 2; }
.element-3 { flex-grow: 2; }
/*Fourth flex item will take 1 unit of the available space*/
.element-4 { flex-grow: 1; }
flex-shrink
这个属性定义了 flex 项目相对于其他 flex 项目通过 flex 收缩因子应该收缩多少,其表现形式如下:
flex-shrink: 1;
描述
flex 收缩因子是一个没有单位的数字。负值无效。
这在所有 flex 项目的总和超过 flex 容器大小时使用。这可以是水平方向或垂直方向(主轴或交叉轴)。通过将 flex 收缩因子分配给一个或多个 flex 项目,我们可以使它们适应 flex 容器的大小。
CSS:
/*First flex item will take 1 unit of the available space*/
.element-1 { flex-shrink: 1; }
/*Second and third flex items will take 2 units of the available space*/
.element-2 { flex-shrink: 2; }
.element-3 { flex-shrink: 2; }
/*Fourth flex item will take 1 unit of the available space*/
.element-4 { flex-shrink: 1; }
flex-basis
这个属性定义了 flex 项目的初始宽度,其表现形式如下:
flex-basis: 200px;
描述
flex-basis 接受一个带有绝对或相对长度单位(px、em、%等)或content关键字的长度值。
当使用content时,容器将适应其内部的内容。负值无效。
CSS:
/*Both elements will be 50% wide*/
/*Both elements will be 50% wide*/
.a { flex-grow: 1; }
.b { flex-grow: 1; }
/*First element WILL NOT grow and has a fixed width of 200px if there's enough space*/
.a {
flex-grow: 0;
flex-basis: 200px;
}
/*Second element WILL grow and has a minimum width of 200px if there's enough space*/
.b {
flex-grow: 1;
flex-basis: 200px;
}
/*First element WILL grow and has a minimum width of 200px if there's enough space*/
.a {
flex-grow: 1;
flex-basis: 200px;
}
/*Second element:
- WILL NOT grow
- WILL shrink if the container is smaller than 400px
- It has a minimum width of 200px if there's enough space*/
.b {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 200px;
}
flex-direction
flex-direction CSS 属性定义了 flex 容器内 flex 项目的方向,其表现形式如下:
flex-direction: column;
描述
这个属性设置 flex 项目可以布局的方向,要么是水平方向的row,要么是垂直方向的column。
有四个值:两个用于水平,两个用于垂直:
row
这在水平轴上布局 flex 项目。这是默认值。
当 flex 项目使用row进行布局时,它们从左到右堆叠在一起。
row-reverse
这与row相同,但方向相反。当 flex 项目使用row-reverse进行布局时,它们从右到左堆叠在一起。
column
这在垂直轴上布局 flex 项目。
当 flex 项目使用column进行布局时,它们从上到下堆叠在一起。
column-reverse
这与column相同,但方向相反。
当 flex 项目使用column-reverse进行布局时,它们从下到上堆叠在一起。
提示
flex-direction属性应用于 flex 容器,而不是 flex 项目。
CSS:
/*Horizontal axis: row*/
.flex-container { flex-direction: row; }
/*Horizontal axis: row-reverse*/
.flex-container { flex-direction: row-reverse; }
/*Vertical axis: column*/
.flex-container { flex-direction: column; }
/*Vertical axis: column*/
.flex-container { flex-direction: column-reverse; }
flex-wrap
flex-wrap CSS 属性定义了当容器变得太小时,flex 项目是否应该换行,其表现形式如下:
flex-wrap: wrap;
描述
这个属性接受三个关键字值之一:nowrap、wrap和wrap-reverse。
nowrap
这是默认值。它告诉 flex 项目不要换行。
wrap
这告诉 flex 元素进行换行。
wrap-reverse
这告诉 flex 元素进行换行,但方向相反。
提示
flex-wrap 属性应用于弹性容器,而不是弹性项。
CSS:
.flex-container {
flex-wrap: wrap;
}
flex-flow
flex-flow CSS 属性是 flex-direction 和 flex-wrap 属性的简写,其形式如下:
flex-flow: row wrap-reverse;
描述
我们现在知道 flex-direction 属性定义了弹性项的方向,是列还是行。
相反,flex-wrap 属性定义了当容器变得太小时,弹性项是否应该换行。
我们可以指定一个或两个值。顺序不会影响结果。
flex-direction 属性可以取其任何可用值:row(默认值)、row-reverse、column 或 column-reverse。
flex-wrap 属性可以取其任何可用值:nowrap(默认值)、wrap 或 wrap-reverse。
小贴士
flex-flow 属性应用于弹性容器,而不是弹性项。
CSS:
/*Main axis and elements will wrap from bottom to top*/
.flex-container {
flex-direction: row;
flex-wrap: wrap-reverse;
}
/*Above rule is the same as this rule*/
.flex-container { flex-flow: row wrap-reverse; }
/*Main axis and flex items will wrap from top to bottom*/
.flex-container { flex-flow: row-reverse wrap; }
/*Cross axis, wrapping doesn't happen on column layout*/
.flex-container { flex-flow: column; }
align-content
align-content CSS 属性在交叉轴上有额外空间时,将弹性容器内的行对齐,其形式如下:
align-content: center;
描述
有六个值:flex-start、flex-end、center、space-around、space-between 和 stretch。
flex-start
这将行组合到容器的开始位置。
flex-end
这将行组合到容器的末尾位置。
center
这将行组合到容器的中心。
space-around
这将在容器中均匀分布行,但第一行放置在容器的开始处,最后一行放置在容器的末尾。
space-between
这将在容器中均匀分布行,并且每行之间有相等的空间。
stretch
这是默认值。行将均匀拉伸以填充整个容器。
小贴士
align-content 属性应用于弹性容器,而不是弹性项。
CSS:
/*All lines at the top*/
.flex-container { align-content: flex-start; }
/*All lines at the bottom*/
.flex-container { align-content: flex-end; }
/*All lines at the center*/
.flex-container { align-content: center; }
/*Evenly spaced lines. The top one touches the top edge; the bottom one touches the bottom edge*/
.flex-container { align-content: space-around; }
/*Evenly spaced lines, even the top and bottom ones*/
.flex-container { align-content: space-between; }
/*Lines will stretch to fill all the available space*/
.flex-container { align-content: stretch; }
align-items
align-items CSS 属性设置弹性容器内弹性元素的默认对齐方式,其形式如下:
align-items: center;
描述
此属性接受五个值:flex-start、flex-end、center、baseline 和 stretch。
flex-start
这将弹性元素对齐到容器的开始位置。
flex-end
这将弹性元素对齐到容器的末尾。
center
这将弹性元素对齐到容器的中心,并且同时将它们对齐到它们的中心。
baseline
这将弹性元素对齐到每个弹性元素内的文本基线。
stretch
这将弹性元素拉伸以填充整个父容器。
小贴士
align-items 属性应用于弹性容器,而不是弹性项。
CSS:
/*Align items to the beginning*/
.flex-container { align-items: flex-start; }
/*Align items to the end*/
.flex-container { align-items: flex-end; }
/*Align items to the center*/
.flex-container { align-items: center; }
/*Align items to their text baseline*/
.flex-container { align-items: baseline; }
/*Make items stretch and fill the parent container*/
.flex-container { align-items: stretch; }
align-self
align-self CSS 属性将特定弹性项在其父容器内对齐,其形式如下:
align-self: flex-start;
描述
此属性接受与 align-items 相同的精确值,结果也相同:flex-start、flex-end、center、baseline 和 stretch。
flex-start
这将弹性元素对齐到容器的开始位置。
flex-end
这将 flex 元素对齐到容器的末尾。
center
这将 flex 元素对齐到容器的中心。
baseline
这将 flex 元素对齐到每个 flex 元素内的文本基线。
stretch
这将 flex 元素拉伸以填充整个父容器。
CSS:
/*Align the flex item to the top*/
.element { align-self: flex-start; }
/*Align the flex item to the bottom*/
.element { align-self: flex-end; }
/*Align the flex item to the center*/
.element { align-self: center; }
/*Align the flex items to their text baseline*/
.element { align-self: baseline; }
/*Make the flex item stretch*/
.element { align-self: stretch; }
order
order CSS 属性用于改变同一父容器内 flex 元素的默认顺序,其表现形式如下:
order: 3;
Description
默认情况下,flex 元素按照它们在源(HTML)中出现的顺序显示。order 属性允许我们改变显示顺序,同时保持它们的源顺序。该属性接受一个不带单位的 数字 值。
顺序以逻辑方式定义:数字越低,顺序越靠前。具有相同数字的项目将根据源文档进行布局。
起始数字是 0(零),不是 1。允许负值。
CSS:
/*The default order of all elements has been altered,
however, their source order remains the same.*/
.element-1 { order: 3; }
.element-2 { order: 0; }
.element-3 { order: -1; }
.element-4 { order: 2; }
justify-content
justify-content CSS 属性仅在 flex 元素上起作用。它允许浏览器根据它们的主轴在 flex 元素之间和周围分配空间。
Description
该属性支持五个关键字值:flex-start、flex-end、center、space-between 和 space-around。
flex-start
这是默认值。它将元素分组并定位到容器的开头。
flex-end
这将元素分组并定位到容器的末尾。
center
这会将元素分组并定位到容器的中心。
space-between
这沿着容器分布和定位元素,并均匀地分配空间。
第一个和最后一个 flex 元素分别紧贴容器的左侧和右侧。换句话说,第一个和最后一个 flex 元素接触容器的左右边缘。
space-around
与 space-between 属性类似,这沿着容器分布和定位元素,并均匀地分配空间。
然而,第一个和最后一个 flex 元素不接触左右边缘。
CSS:
.flex-container {
display: flex;
justify-content: space-between;
}
flex
flex CSS 属性是声明 flex-grow、flex-shrink 和 flex-basis 值的简写。建议您按照以下顺序声明值。
CSS:
/*Apply flexbox to the parent container*/
.flex-container { display: flex; }
/*Flex items create 4 containers, each of different size.
Each container grows/shrinks proportional to the
flex growth/shrink factorsand the browser automatically
calculates the flex-basis*/
.element-1 { flex: 1 4 auto; }
.element-2 { flex: 2 3 auto; }
.element-3 { flex: 3 2 auto; }
.element-4 { flex: 4 1 auto; }
Summary
这就是您开始关于 CSS 属性的第一章的方式!我们学习了 CSS 属性和供应商前缀是什么。
现在,随着动画属性变得清晰,我们可以开始为我们的网站和应用制作出色的交互。我们还可以处理所有背景功能,无论是定位还是混合模式,以创建无需依赖任何图像编辑器的精美视觉效果。
Box Model 概念是我们更容易解决的问题,特别是知道传统 IE 浏览器的影响越来越小。这很大程度上取决于我们如何处理 CSS 单位,因为我们需要了解哪些单位在不同用例和需求中工作得最好。
我们了解到 CSS 列是一个很好的工具,可以分配长字符串文本。而且强大的 Flexbox 是在容器中排列元素的必备特性。
改善我们的排版和转换是下一章节中众多有趣特性的一部分。
准备好!
第五章。CSS 属性 – Part 2
好的,我们已经完成了 CSS 属性的 Part 1 部分。确实,还有很多很多属性需要讨论。
现在我们继续到 Part 2。
字体
在设计的世界里,字体是我们拥有的最有力的资产之一,同时,它们也是被低估最多的资产之一。
排版功能如此强大,当我们正确使用它时,我们甚至可能在我们的项目中不用使用任何一张图片。
让我们来看看 CSS 字体属性,怎么样?
font-family
font-family CSS 属性定义了元素想要使用的字体,其格式如下:
font-family: "Times New Roman", Times, Baskerville, Georgia, serif;
描述
这个属性可以在其声明中包含一个或多个字体名称。它没有限制可以包含多少个字体名称;然而,实际上列出超过四到五个字体是非常不可能的,而且也是不必要的。
字体家族名称由逗号分隔。我们称之为字体堆栈。浏览器将读取字体堆栈,并使用堆栈中的第一个字体,如果找不到或下载不了,它将移动到下一个字体家族名称,依此类推,直到它能够使用堆栈中的一个字体。
字体家族名称有两种类型:字体名称和通用字体名称。
字体名称
姓氏实际上是代表真实字体的名称,例如Times、Arial、Verdana、Monaco等等。它们应该始终在字体堆栈中列在通用字体名称之前。
通用字体名称
这些是唯一代表系统字体的关键词。它们被称为后备字体。它们应该始终在字体堆栈中列在字体名称之后。通用字体名称可以是monospace、san-serif、serif、cursive和fantasy。
小贴士
当字体家族名称包含多个单词时,使用引号(单引号或双引号)不是强制的。例如,写作font-family: "Times New Roman", serif;与写作font-family: Times New Roman, serif;是相同的。注意在第二个例子中Times New Roman没有使用引号。
CSS:
.element {
font-family: "Times New Roman", Times, Baskerville, Georgia, serif;
}
font-feature-settings
font-feature-settings CSS 属性提供了对 OpenType 字体中排版属性的控制的权限,其格式如下:
font-feature-settings: "smcp";
描述
font-feature-settings CSS 属性允许我们控制和使用某些字体文件中包含的其他交替符号。
一个交替符号的例子是当我们输入分数 1/2 或 1/4 时,字体实际上包含了“小上标”版本,如½和¼。或者如果我们输入 H[2]O,它就会变成 H[2]O。
记住,并非所有字体都包含特殊符号(字体特征)。
要找出字体文件具有哪些字体特征,你可以使用以下两种工具中的任何一种:
-
Fontdeck.com (
fontdeck.com/) - 找到你想要的字体,在“关于这个字体”部分,查找 OPENTYPE 行,那里将列出该特定字体的所有字体特征。 -
测试 OpenType 功能(文本有链接
www.impallari.com/testing/index.php)- 只需拖放您的字体文件并点击左上角的 OpenType Features 链接,一个大型面板将滑动出来,您可以选择查看哪些功能。
这里有一些最常见的特征标签:
-
dlig: 可选连字符 -
kern: 字距调整 -
liga: 标准连字符 -
lnum: 基线数字 -
onum: 旧式数字 -
tnum: 表格数字 -
smcp: 小写字母大写 -
ss01, ss02, ss03, ss04… ss20: 风格集(字体相关) -
swsh: 波浪形
更多信息,请查看 MDN 网站:tiny.cc/mdn-font-feature-settings
要查看所有字体特征的完整列表,请访问微软网站 tiny.cc/msn-font-features-list
CSS:
/*Small capitals*/
.element {
font-feature-settings: "smcp";
}
font-size
font-size CSS 属性定义了元素的文本大小,其看起来如下:
font-size-settings: "smcp";
描述
此属性也可以用来改变其他元素的大小,因为我们还可以计算em、rem和ex长度单位的价值。
我们可以使用几种不同的值类型与font-size CSS 属性一起使用:绝对关键词/大小、相对大小、长度和百分比。
绝对关键词/大小
定义的大小直接关联到特定的字体大小。它们也可以用来根据父元素的字体大小设置元素的字体大小。值如下:
-
xx-small -
x-small -
small -
medium(默认值) -
large -
x-large -
xx-large
相对大小关键词
这些大小根据其父容器字体大小增加或减少元素的字体大小。值如下:
-
smaller -
larger
长度
负值无效。当使用px时,字体大小是绝对的;它不相对于父容器字体大小。当使用em、ex和ch时,字体大小相对于元素的父容器字体大小。当使用rem时,字体大小相对于根元素,即<html>元素。当使用vw、vh、vmax和vmin时,字体大小相对于视口。
要查看此属性的可用值,请参阅绝对长度单位部分。
最流行的单位有:
-
px -
em -
rem
百分比
percentage属性指的是父元素字体大小的百分比。其单位是%。
CSS:
/*Absolute keywords/size*/
.element { font-size: x-small; }
/*Relative size*/
.element { font-size: smaller; }
/*Length value*/
.element { font-size: 18px; }
/*Percentage value*/
.element { font-size: 62.5%; }
font-size-adjust
font-size-adjust CSS 属性帮助我们根据小写字母x和上标字母X的大小差异来定义字体宽高比,其看起来如下:
font-size-adjust: .5";
描述
在字体堆栈中,字体大小可以不同,因此文本的样式可能会与预期设计有相当大的差异。使用font-size-adjust CSS 属性,我们可以确保当浏览器使用字体堆栈中的任何字体时,字体大小是一致的。
此属性接受一个不带单位的数字值。它也可以接受十进制值。
一个可以为我们完成这项工作的优秀在线工具是 Fontdeck 的字体大小调整 web 应用:fontdeck.com/support/fontsizeadjust。
提示
尽管在撰写本节时 Firefox 是唯一支持font-size-adjust属性的浏览器,但我决定仍然包括它,因为一旦其他浏览器开始支持它,它将非常有价值。
CSS:
.element {
font-size-adjust: .5;
}
font-stretch
font-stretch CSS 属性允许我们从相关的字体族中选择condensed、normal或expanded面,其外观如下:
font-stretch: condensed;
描述
font-stretch属性不仅将字体拉伸到我们告诉它的任何地方。它会在字体文件中寻找与声明的样式相匹配的实际面;或者尽可能接近。
此属性支持以下值:
-
ultra-condensed -
extra-condensed -
condensed -
semi-condensed -
normal -
semi-expanded -
expanded -
extra-expanded -
ultra-expanded
CSS:
.element {
font-stretch: condensed;
}
font-style
font-style CSS 属性指定了元素的字体样式,其外观如下:
font-style: italic;
描述
font-style属性接受以下值:normal、italic和oblique。
让我们澄清italic和oblique之间的区别。
根据规范:
"斜体形式通常是草书的,而斜体面通常是常规面的倾斜版本。"
这意味着当我们声明字体样式为italic时,浏览器将寻找字体的斜体面并使用该面。一个很好的例子是字体族Georgia;当我们使用italic属性时,我们可以清楚地看到它是一个真正的斜体面,而不是使正常面倾斜。
斜体使正常面倾斜或倾斜,以模拟斜体。
CSS:
.element {
font-style: italic;
}
font-variant
font-variant CSS 属性将目标文本转换为小写字母,其外观如下:
font-variant: small-caps;
描述
font-variant属性在 CSS3 中被视为缩写,并已通过新值进行了扩展,但开发者很少使用。
需要注意的一点是,如果文本已经是全大写,并且我们对其应用了small-caps属性,文本将不会改变;它将继续保持全大写。
最常用的值是:normal和small-caps。CSS3 中的一些附加值包括small-caps、all-small-caps、petite-caps、all-petite-caps、unicase和titling-caps。
想要了解更多信息,请访问 MDN 网站:tiny.cc/mdn-font-variant
CSS:
.element {
font-variant: small-caps;
}
font-variant-ligatures
font-variant-ligatures CSS 属性在文本中定义连字符,指定了如何组合符号以产生更和谐的文本,其外观如下:
font-variantligatures: discretionary-ligatures;
描述
font-variant-ligatures在 OpenType 字体中很常见。
font-variant-ligatures属性使用以下值:common-ligatures、no-common-ligatures、discretionary-ligatures、no-discretionary-ligatures、historical-ligatures、no-historical-ligatures、contextual、no-contextual和contextual。
更多信息,请查看 MDN 网站:tiny.cc/mdnfont-variant-ligatures
CSS:
.element {
font-variant-ligatures: discretionary-ligatures;
}
font-weight
font-weight CSS 属性定义了字体的厚度(重量),其语法如下:
font-weight: bold;
描述
这个属性接受两种类型的值:一个数字值和一个关键字值。
数字值
这个属性接受100、200、300、400、500、600、700、800和900这样的数字值。
关键字值
这个属性也接受关键字值,如normal、bold、bolder和lighter。
小贴士
normal关键字等同于400数字值,而bold关键字等同于700。
有一点需要注意,关键字bolder和lighter取决于父元素的字体粗细。
CSS:
/*Numeric value*/
.element { font-weight: 200; }
/*Keyword value*/
.element { font-weight: bold; }
font
font CSS 属性是font-style、font-variant、font-weight、font-size、line-height和font-family属性的简写,其语法如下:
font: italic small-caps bold 18px/2 "Times New Roman", Times, Baskerville, Georgia, serif;
描述
在使用font简写属性时,有一些事情需要考虑,以确保其正常工作:
-
至少需要声明
font-size和font-family属性 -
如果省略了上述两个属性中的任何一个,则声明将被忽略
-
如果要声明这两个属性之外的更多属性,则必须遵守以下顺序:
-
font-style -
font-variant -
font-weight -
font-size -
line-height -
font-family
小贴士
在简写中声明
line-height值时,它必须始终跟在font-size属性之后,并用斜杠"/"字符分隔,例如,.element { font: 12px/1.6 Arial; }。 -
-
CSS:
/*All font properties in a single declaration*/ .element { font: italic small-caps bold 18px/2 "Times New Roman", Times, Baskerville, Georgia, serif; } /*font-style*/ .element { font-style: italic; } /*font-variant*/ .element { font-variant: small-caps; } /*font-weight*/ .element { font-weight: bold; } /*font-size*/ .element { font-size: 18px; } /*line-height*/ .element { line-height: 2; } /*font-family*/ .element { font-family: "Times New Roman", Times, Baskerville, Georgia, serif; }
Transform
CSS 转换已经变得如此流行,以至于现在很少看到网站上没有某种转换——从按钮形状和动画到布局。
让我们深入探讨。
transform
transform CSS 属性允许我们在 2D 和 3D 空间中对元素进行缩放、旋转、倾斜和转换,其语法如下:
transform: translate(-10px, 10%);
描述
这个属性支持以下值:scale()、skewX()和skewY()、translate()、rotate()、matrix()和perspective()。
注意,X 轴等于水平,Y 轴等于垂直。
小贴士
记住哪个轴是哪个的一个简单方法是说:“x 是一个十字,所以 x 轴是横跨的”。tiny.cc/xy-axis
scale()
scale()函数用于缩放元素。它也是scaleX()和scaleY()函数的简写。它接受一个不带单位的数字值。数字值表示元素缩放的比例。例如,2表示元素将被缩放至其大小的两倍。负值也是有效的。
skew()
skew()函数使元素倾斜。如果声明了一个单个值,那么它只会使元素在x轴上倾斜。如果声明了两个值,那么元素将在x轴和y轴上倾斜。skew()函数接受一个数值后跟deg、grad、rad或turn单位。然而,deg单位是最常用的单位。负值是有效的。
skewX()和 skewY()
skewX()和skewY()函数仅使元素水平或垂直倾斜。
translate()
translate()函数改变元素的位置。如果声明了一个单个值,那么它只会沿 X 轴平移元素。如果声明了两个值,那么元素将在 X 轴和 Y 轴上平移。负值是有效的。
translateX()和 translateY()
translateX()和translateY()函数改变元素的水平或垂直位置。
rotate()
rotate()函数在 2D 空间中围绕一个固定点旋转一个元素。它接受一个数值后跟deg、grad、rad或turn单位。尽管如此,deg单位是最常用的。负值是有效的。
matrix()
matrix()函数是所有变换值的简写,因为它们可以在这里组合。鉴于matrix()函数的复杂性,这需要扎实的数学基础。
perspective()
此值给元素一个 3D 视角;一旦设置了视角,我们就可以使用其他任何值。相关元素将在 3D 平面上反应。它接受一个带有长度单位的数值。
本书不涉及matrix()函数的高级数学解释。然而,对于非常详细的解释,你可以参考这两篇文章中的任意一篇:
-
《理解 CSS 变换矩阵》,作者:Tiffany Brown,链接:
tiny.cc/css-matrix-1 -
《CSS3 矩阵变换,让数学挑战者也能理解》,作者:Zoltan Hawryluk,链接:
tiny.cc/css-matrix-2
CSS:
/*Scale the same value in both X an Y-axis*/
.element { transform: scale(1.1); }
/*Scale different values for X and Y-axis*/
.element { transform: scale(1.1, 1.5); }
/*Tilt the element on X-axis only*/
.element { transform: skew(10deg); }
/*Tilt the element on both X and Y-axis*/
.element { transform: skew(10deg, -20deg); }
/*Move the element 10px to the right*/
.element { transform: translate(10px); }
/*Move the element 10px to the right and 10% down*/
.element { transform: translate(-10px, 10%); }
/*Rotate in a 2D plane*/
.element { transform: rotate(10deg); }
/*Matrix*/
.element { transform: matrix(2, 2, 1, 2, 0, 0); }
/*Add perspective to the element to make it rotate in a 3D plane*/
.element { transform: perspective(100px) rotateX(40deg); }
transform-origin
transform-origin CSS 属性允许我们改变变换元素的基点,它看起来像这样:
transform-origin: 50px;
描述
只有当声明了transform属性时,transform-origin属性才起作用。
2D 变换可以影响x和y轴。3D 变换可以改变这两个轴,以及z轴。
对于 2D 变换,最多可以声明两个值;第一个是 X 轴(水平),第二个是 Y 轴(垂直)。
3D 变换可以接受最多三个值,代表 X、Y 和 Z 轴。
该属性接受的键值有:top、right、bottom、left和center。
CSS:
/*Single value affects both X and Y-axis*/
.element {
transform: scale(2, 4);
transform-origin: 50px;
}
/*Two values one for each axis*/
.element {
transform: scale(2, 4);
transform-origin: 50px -100px;
}
/*Keyword value*/
.element {
transform: scale(2, 4);
transform-origin: bottom;
}
/*Length and keyword values*/
.element {
transform: scale(2, 4);
transform-origin: 50px bottom;
}
/*Both keyword values*/
.element {
transform: scale(2, 4);
transform-origin: right bottom;
}
transform-style
transform-style CSS 属性定义了元素是在 3D 空间中定位还是在 2D 空间(平坦)中,它看起来像这样:
transform-style: preserve-3d;
描述
该属性只接受两个值:flat和preserve-3d。
当应用 preserve-3d 属性时,元素在 z 轴上的堆叠可以通过 translate() 函数进行更改,因此元素可以出现在不同的平面上,而不管它们在源 HTML 中出现的顺序如何。
当应用 flat 属性时,元素遵循它们在源 HTML 中出现的顺序。
小贴士
注意,此属性应用于父元素,而不是子元素。
CSS:
/*Perspective*/
.parent-container {
transform-style: preserve-3d;
perspective: 500px;
}
.element-1 {
transform: translateZ(1px) rotateX(60deg);
}
.element-2 {
transform: translateZ(-2px);
}
过渡
CSS 过渡使我们能够对我们的动画有非常细粒度的控制。
让我们来看看这些属性。
transition
transition CSS 属性是所有过渡属性的缩写:transition-delay、transition-duration、transition-property 和 transition-timing-function。它看起来像这样:
transition: width 400ms ease-out 1s;
描述
此属性允许我们通过 :hover 或 :active 伪类定义元素两种状态之间的过渡。
需要考虑的一点是,这些属性的顺序并不重要。然而,由于 transition-delay 和 transition-duration 使用相同的值单位,transition-delay 将始终首先考虑,然后是 transition-duration。
CSS:
/*Shorthand with all properties in a single declaration*/
.element {
width: 100px;
/*property - duration - timing function - delay*/
transition: width 400ms ease-out 1s;
}
/*Longhand. Each property is declared separately*/
.element {
transition-property: width;
transition-duration: 400ms;
transition-timing-function: ease-out;
transition-delay: 1s;
}
.element:hover {
width: 300px;
}
transition-delay
transition-delay CSS 属性允许我们设置一个 计时器。当计时器达到零时,过渡开始。它看起来像这样:
transition-delay: 1s;
描述
此属性接受一个 数字 值,后跟 s 或 ms,分别代表 秒 和 毫秒。
CSS:
.element {
transition-delay: 1s;
}
transition-duration
transition-duration CSS 属性允许我们定义过渡从开始到结束需要多长时间。这也被称为 周期,它看起来像这样:
transition-duration: 400ms;
描述
transition-duration 属性接受一个 数字 值,后跟 s 或 ms,分别代表秒和毫秒。
CSS:
.element {
transition-duration: 400ms;
}
transition-property
transition-property CSS 属性指定了哪些 CSS 属性或属性将进行过渡。
虽然并非所有属性都可以动画化。W3C 有一个 animatable CSS 属性的不错列表,可以在 tiny.cc/w3c-animatable-css-props 找到
描述
transition-property CSS 属性接受以下值:
-
none: 这意味着不会发生任何过渡 -
all: 这意味着所有属性都将进行过渡 -
属性名: 这意味着指定的属性或属性将进行过渡
CSS:
.element {
transition-property: width;
}
transition-timing-function
transition-timing-function CSS 属性定义了动画的速度如何在其周期内进展。
transition-timing-function 和 animation-timing-function 属性接受相同的五个预定义值,也称为 贝塞尔 曲线的缓动函数:ease、ease-in、ease-out、ease-in-out 和 linear。
请参考 animation-timing-function 部分,以获取所有值的详细解释。
CSS:
.element {
transition-timing-function: ease-out;
}
定位
在构建网站和应用时,定位元素是我们花费大量时间的事情,因此了解如何将元素放置在布局中至关重要,尤其是在元素可以根据可用空间具有不同位置时。
让我们看看定位究竟是怎么回事。
position
position CSS 属性定义了元素的位置。
描述
position 属性有五个关键字值:static、absolute、relative、fixed 和 sticky。
static
这是 position 属性的默认值。元素保持在文档的流中,并出现在其标记中实际位置。
absolute
元素从文档流中移除,并相对于其最近的定位祖先元素进行定位。
relative
除非声明了 top、right、bottom 或 left 中的一个或多个属性,否则元素不会改变位置。它还为 absolute 定位子元素创建一个 参考位置。
fixed
元素就像 absolute 定位元素一样从文档流中移除。然而,与相对于祖先元素的 absolute 定位元素不同,fixed 元素始终相对于文档。
sticky
此值是 relative 和 fixed 定位的混合。元素被视为 relative,直到达到一个特定的点或阈值,此时元素被处理为 fixed。在撰写本文时,只有 Firefox 支持此属性。
CSS:
/*Position relative*/
.element {
position: relative;
}
/*When the element hits the top of the viewport, it will stay fixed at 20px from the top*/
.element {
position: sticky;
top: 20px;
}
top
CSS 的 top 属性与 position 属性紧密相关。
如果元素声明了 position: relative;,则此属性指定元素从其当前位置的顶部距离;如果祖先具有 position: relative; 且元素声明了 position: absolute;,则指定元素从最近的祖先顶部距离。
如果没有祖先声明了 position: relative;,则绝对定位的元素将遍历 DOM,直到它到达 <body> 标签,此时它将将自己定位在页面的顶部,无论其在源 HTML 中的位置如何。
负值是有效的。
描述
它支持以下值:
-
auto:auto关键字是默认值。浏览器计算顶部位置。 -
长度值:对于长度值,我们使用以下单位之一:px、em、in、mm、cm、vw等。 -
百分比值:对于百分比值,我们使用像50%、85%这样的百分比。
CSS:
/*auto*/
.element { top: auto; }
/*Length value*/
.element { top: 20px; }
/*Percentage value*/
.element { top: 15%; }
bottom
CSS 的 bottom 属性与 position 属性紧密相关。
如果元素本身声明了 position: relative;,则此属性指定元素从其当前位置的底部距离;如果祖先具有 position: relative; 且元素声明了 position: absolute;,则指定元素从最近的祖先底部距离。
如果没有祖先元素声明了 position: relative;,则绝对定位的元素将遍历 DOM,直到它到达 <body> 标签,此时它将将自己定位在页面的底部,而不管它在源 HTML 中的位置如何。
负值是有效的。
描述
它支持以下值:
-
auto:auto关键字是bottom属性的默认值。浏览器计算顶部位置。 -
长度值: 对于长度值,我们使用以下单位之一:px、em、in、mm、cm、vw等等。 -
百分比值: 对于百分比值,我们使用类似50%、85%等的百分比。
CSS:
/*auto*/
.element { bottom: auto; }
/*Length value*/
.element { bottom: 20px; }
/*Percentage value*/
.element { bottom: 15%; }
left
left CSS 属性与 position 属性紧密相关。
该属性指定了元素从其当前位置左侧的距离,如果元素声明了 position: relative; 或者在祖先元素有 position: relative; 且元素有 position: absolute; 声明时,从最近的祖先元素的右侧开始计算。
如果没有祖先元素声明了 position: relative;,则绝对定位的元素将遍历 DOM,直到它到达 <body> 标签,此时它将将自己定位在页面的左侧,而不管它在源 HTML 中的位置如何。
负值是有效的。
描述
left 属性支持以下值:
-
auto:auto关键字是left属性的默认值。浏览器计算顶部位置。 -
长度值: 对于长度值,我们使用以下单位之一:px、em、in、mm、cm、vw等等。 -
百分比值: 对于百分比值,我们使用类似50%、85%等的百分比。
CSS:
/*auto*/
.element { left: auto; }
/*Length value*/
.element { left: 20px; }
/*Percentage value*/
.element { left: 15%; }
right
right CSS 属性与 position 属性紧密相关。
该属性指定了元素从其当前位置右侧的距离,如果元素声明了 position: relative; 或者在祖先元素有 position: relative; 且元素有 position: absolute; 声明时,从最近的祖先元素的右侧开始计算。
如果没有祖先元素声明了 position: relative;,则绝对定位的元素将遍历 DOM,直到它到达 <body> 标签,此时它将将自己定位在页面的右侧,而不管它在源 HTML 中的位置如何。
负值是有效的。
描述
它支持以下值:
-
auto:auto关键字是right属性的默认值。浏览器计算顶部位置。 -
长度值: 对于长度值,我们使用以下单位之一:px、em、in、mm、cm、vw等等。 -
百分比值: 对于百分比值,我们使用类似50%、85%等的百分比。
CSS:
/*auto*/
.element { right: auto; }
/*Length value*/
.element { right: 20px; }
/*Percentage value*/
.element { right: 15%; }
vertical-align
vertical-align CSS 属性控制元素在垂直方向上的定位,以便将其与旁边的另一个(或多个)元素对齐。
描述
它接受以下值:
-
baseline:这是默认值。它将元素与底部对齐,正好在文本的最后一行,无论元素的行高如何。换句话说,它将文本的最后一行与元素的基线对齐。 -
bottom:此属性将元素的容器与底部对齐。不考虑元素的文本和行高,只考虑元素的容器与底部对齐。 -
长度值:对于长度值,我们使用以下单位之一:px、em、in、mm、cm、vw等。负值是有效的。 -
middle:此属性根据元素的垂直中点将元素水平居中对齐。 -
百分比值:对于百分比值,我们使用类似50%、85%等的百分比。负值是有效的。 -
sub:此属性将元素与父容器的下标基线对齐。 -
super:此属性将元素与父容器的上标基线对齐。 -
top:此属性将元素的容器与顶部对齐。不考虑元素的文本和行高。 -
text-bottom:此属性根据父元素的文本基线将元素对齐到底部。不考虑元素的行高,只考虑其容器的底部。 -
text-top:此属性根据父元素的文本基线将元素对齐到顶部。不考虑元素的行高,但考虑其容器的顶部。
文本
字体排印是一个极其强大的设计功能,实际上,使用 CSS 样式化文本实际上非常简单。
让我们看看怎么做。
颜色
color CSS 属性定义文本的颜色,其外观如下:
color: red;
或者,它也可以是这样的:
color: #f00;
描述
color 属性支持所有颜色模式,包括 HEX、RGB、RGBa、HSL、HSLs 和 颜色名称。
CSS:
/*Color Name*/
.element { color: red; }
/*HEX*/
.element { color: #f00; }
/*RGB*/
.element { color: rgb(255, 0, 0); }
/*RGBa - Color has 50% opacity*/
.element { color: rgba(255, 0, 0, .5); }
/*HSL*/
.element { color: hsl(0, 100%, 50%); }
/*HSLa - Color has 50% opacity*/
.element { color: hsla(0, 100%, 50%, .5); }
text-align
text-align CSS 属性定义了文本的对齐方式,其外观如下:
text-align: center;
描述
文本可以居中、左对齐、右对齐和完全对齐。
text-align 属性仅适用于内联元素。如果将此属性应用于块级元素,则它不会应用于该元素本身,但会应用于其内容。
CSS:
/*Centered text*/
.element { text-align: center; }
/*Left aligned text*/
.element { text-align: left; }
/*Right aligned text*/
.element { text-align: right; }
/*Fully justified text*/
.element { text-align: justify; }
text-decoration
text-decoration CSS 属性定义了文本的几个格式化功能,其外观如下:
text-decoration: underline;
描述
text-decoration 属性接受以下关键字值:underline、overline、line-through、none 和 blink。
此属性也是 text-decoration-line、text-decoration-color 和 text-decoration-style 属性的缩写。
如果用作缩写,则可以在同一声明中接受一个、两个或三个值。
CSS:
/*Line above the text*/
.element { text-decoration: overline; }
/*Line under the text*/
.element { text-decoration: underline; }
/*Line across the text*/
.element { text-decoration: line-through; }
/*No underline*/
.element { text-decoration: none; }
/*Blinking text*/
.element { text-decoration: blink; }
/*Shorthand*/
/*Two values*/
.element { text-decoration: underline wavy; }
/*Three values*/
.element { text-decoration: overline dashed yellow; }
text-decoration-line
text-decoration-line CSS 属性定义文本可以具有的装饰线类型,其外观如下:
text-decoration-line: overline;
描述
text-decoration-line 属性可以在单个声明中接受一个、两个或三个值。关键字值与 text-decoration 属性中的相同:underline、overline、line-through、none 和 blink。
CSS:
/*One value*/
.element { text-decoration-line: overline; }
/*Two values*/
.element { text-decoration-line: overline underline; }
/*Three values*/
.element { text-decoration-line: overline underline blink; }
text-decoration-color
text-decoration-color CSS 属性定义了 text-decoration 属性可以具有的颜色类型,其外观如下:
text-decoration-color: red;
描述
它支持所有颜色模式:HEX、RGB、RGBa、HSL、HSLs 和 颜色名称。
CSS:
/*Color Name*/
.element { text-decoration-color: red; }
/*HEX*/
.element { text-decoration-color: #f00; }
/*RGB*/
.element { text-decoration-color: rgb(255, 0, 0); }
/*RGBa - Color has 50% opacity*/
.element { text-decoration-color: rgba(255, 0, 0, .5); }
/*HSL*/
.element { text-decoration-color: hsl(0, 100%, 50%); }
/*HSLa - Color has 50% opacity*/
.element { text-decoration-color: hsla(0, 100%, 50%, .5); }
text-decoration-style
text-decoration-style CSS 属性定义了 text-decoration 属性可以具有的线类型,其外观如下:
text-decoration-style: dotted;
描述
text-decoration-style 属性支持以下关键字值:dashed、dotted、double、solid 和 wavy。
CSS:
.element {
text-decoration-style: wavy;
}
text-indent
text-indent CSS 属性定义了元素中第一行文本的左侧空间(缩进),其外观如下:
text-indent: red;
描述
它接受 length 和 percentage 值。负值是有效的。
CSS:
.element {
text-indent: 50px;
}
text-overflow
text-overflow CSS 属性定义了超出容器外部的文本应该如何被裁剪,其外观如下:
text-overflow: ellipsis;
描述
为了使此属性生效,应该声明另外两个属性:overflow: hidden; 和 white-space: nowrap;。
有两个关键字值:clip 和 ellipsis。
clip
这会在父容器的边缘处精确切断文本。这可能会导致最后一个字符在任何时刻被切断,只显示其一部分。
ellipsis
这在文本行的末尾添加一个省略号字符 "…"。
CSS:
.element {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
text-rendering
text-rendering CSS 属性允许我们定义文本的质量相对于速度/性能,其外观如下:
text-rendering: optimizeLegibility;
描述
根据字体,当应用此属性时,我们可以看到诸如更好的字距调整和更好的连字符等好处。
然而,由于这个 CSS 属性实际上是一个 SVG 属性,并且不属于任何 CSS 标准,因此浏览器和操作系统会根据自己的判断来应用这个属性,这可能会导致在不同的浏览器和/或平台之间无法达到预期的改进。
此外,一些小屏幕设备在遇到 text-rendering CSS 属性时存在严重的性能问题,尤其是较旧的 iOS 和 Android 设备。
小贴士
使用 text-rendering CSS 属性时要格外小心,并确保运行所有相关测试。
此属性支持四个值:auto、optimizeSpeed、optimizeLegibility 和 geometricPrecision。
auto
这是默认值。浏览器会尽力做出最佳猜测,以优化文本的渲染,以实现速度、可读性和几何精度。
记住,每个浏览器对此属性的解析都不同。
optimizeSpeed
浏览器更倾向于渲染速度而不是可读性和几何细节。它禁用了字距调整和连字符。
optimizeLegibility
浏览器更倾向于可读性而非渲染速度和几何细节。它启用了字距调整和一些可选的连字符。请注意,如果浏览器尝试使用任何字距调整和连字符,这些信息需要包含在字体文件中,否则我们不会看到这些功能的效果。
geometricPrecision
浏览器更倾向于几何细节而非可读性和渲染速度。此属性在缩放字体时很有帮助。
例如,某些字体中的字距调整可能无法正确缩放,因此当我们应用此值时,浏览器能够保持文本看起来很漂亮。
CSS:
.element {
text-rendering: geometricPrecision;
}
text-shadow
text-shadow CSS 属性将阴影应用到文本上,它看起来像这样:
text-shadow: 5px -2vw .2cm black;
描述
此属性可以在同一声明中接受两个、三个或四个值。声明中的第一个长度值始终用于x-offset值,第二个长度值用于y-offset值。
它支持以下四个值:x-offset、y-offset、color和blur。
-
x-offset: 这设置了阴影与文本的水平距离。它声明为一个长度值(px、em、in、mm、cm、vw等)。负值是有效的。此值是必需的。 -
y-offset: 这设置了阴影与文本的垂直距离。它声明为一个长度值(px、em、in、mm、cm、vw等)。负值是有效的。此值是必需的。 -
color: 这是文本阴影的颜色。它支持所有颜色模式:HEX、RGB、RGBa、HSL、HSLs和颜色名称。此值是可选的。如果没有指定,默认颜色将与文本本身的颜色相同。 -
blur: 这是模糊效果。它声明为一个长度值(px、em、in、mm、cm、vw等)。它支持所有颜色模式:HEX、RGB、RGBa、HSL、HSLs和颜色名称。此值是可选的。如果没有指定,默认值是零(0)。
CSS:
/*2 values: x-offset and y-offset*/
.element { text-shadow: 5px 10px; }
/*3 values: x-offset, y-offset and blur. Color value defaults to the font color*/
.element { text-shadow: 5px 2vw 5px; }
/*4 values: x-offset, y-offset, blur and color name*/
.element { text-shadow: 5px -2vw .2cm black; }
text-transform
text-transform CSS 属性控制文本的大小写,它看起来像这样:
text-transform: capitalize;
描述
text-transform属性支持以下四个关键字值:none、capitalize、uppercase和lowercase。
-
none: 这是默认值。不应将任何大小写应用于元素。 -
capitalize: 这会将每个单词的首字母大写。此属性足够智能,可以忽略行首的任何特殊字符或符号,并将第一个单词的首字母大写。 -
uppercase: 这会将所有文本转换为大写/首字母大写。此属性还可以忽略行首的特殊字符或符号。 -
lowercase: 这会将所有文本转换为小写。此属性还可以忽略行首的特殊字符或符号。
text-underline-position
text-underline-position CSS 属性定义了具有声明text-decoration属性的元素的下划线位置,它看起来像这样:
text-underline-position: left;
描述
text-underline-position 属性支持四个关键字值:auto、left、right 和 under。
auto
这是默认值。此属性允许浏览器决定下划线的位置,是位于文本的基线还是其下方。
left
这仅适用于垂直书写模式。它将下划线放置在文本的左侧。
right
这仅适用于垂直书写模式。它将下划线放置在文本的右侧。
under
此值将下划线放置在文本的基线之下,因此它不会跨越任何下降线(它支持如 q、p、y 等值)。这对于包含大量下标的数学和化学公式的文本很有帮助,这样下划线就不会干扰某些字符,使这些公式变得混乱或难以阅读。
CSS:
.element {
text-underline-position: left;
}
direction
direction CSS 属性设置文本的方向。对于西方语言和其他类似语言,是从左到右,对于阿拉伯语或希伯来语等语言,是从右到左。其外观如下:
direction: rtl;
描述
文本方向通常通过 HTML 中的 dir 属性而不是通过 CSS 定义。
direction CSS 属性不会由表格单元格继承。因此,除了这个之外,如果 CSS 文件没有加载,建议通过 HTML 文档中的 dir 属性设置文本方向,以保持完整的级联支持。
此属性接受两个关键字值,ltr 和 rtl,分别表示 从左到右 和 从右到左。
CSS:
.element {
direction: rtl;
}
表格
表格,表格,表格!与图像一起,HTML 表格是网页设计的黑羊。
不论是黑羊还是白羊,表格的力量都是惊人的。而且,如果有一个 HTML 元素能很好地完成其工作,那么它就是表格。
让我们深入探讨。
table-layout
table-layout CSS 属性允许我们定义 HTML 表格在文档中的布局方式,其外观如下:
table-layout: fixed;
描述
有两个关键字值:auto 和 fixed。
-
auto:这是默认值。浏览器会以这种方式自动布局表格,而不需要在 CSS 中声明任何内容。表格单元格会适应其内部的内容;表格的行为有时可能是不可预测的。 -
fixed:通过从第一行声明表格单元格的宽度,整个表格的渲染实际上可以更快;我们为提高性能所做的任何努力都是对每个人来说都是一大胜利。
由于表格单元格具有固定宽度,根据单元格中的数据,一些信息可能会溢出单元格。通过组合使用 overflow 属性和 text-overflow: ellipsis;,我们可以解决这个问题。
CSS:
table {
table-layout: fixed;
}
border-collapse
border-collapse CSS 属性告诉表格单元格保持分离或靠近(合并),其外观如下:
border-collapse: collapse;
描述
此属性支持两个关键字值:separate 和 collapse。
-
separate:这是默认值。表格单元格之间有空隙,并且每个单元格都有自己的边框。 -
collapse:此值将单元格聚集在一起,因此空间丢失,单元格共享边框。
CSS:
table {
border-collapse: collapse;
}
border-spacing
border-spacing CSS 属性在表格单元格之间创建空间,它看起来像这样:
border-spacing: 10px;
描述
border-spacing 属性仅在存在 border-collapse: separate; 声明时才起作用。
CSS:
table {
border-collapse: separate;
border-spacing: 10px;
}
empty-cells
empty-cells CSS 属性允许我们定义浏览器应该如何渲染没有内容的单元格的边框和背景,它看起来像这样:
empty-cells: hide;
描述
empty-cells 属性支持两个关键字值:show 和 hide,它们确定是否渲染边框和背景。
CSS:
table {
empty-cells: hide;
}
caption-side
caption-side CSS 属性定义了表格标题的位置,它看起来像这样:
caption-side: bottom;
描述
它支持两个关键字值:top 和 bottom。
在 CSS 2 中,支持了其他关键字值,如 left 和 right,但在 CSS 2.1 中被删除。
CSS:
caption {
caption-side: bottom;
}
单词和段落
继续介绍排版功能,我们现在进入 word 和 paragraph 属性。
让我们开始吧。
hyphens
hyphens CSS 属性告诉浏览器在文本行换行时如何处理连字符,它看起来像这样:
hyphens: auto;
描述
我们可以控制何时连字符化以及是否允许它或在某些条件下发生。
连字符是语言相关的。文档中的语言由 lang 属性定义;如果浏览器支持该语言并且有适当的连字符词典,则会进行连字符化。每个浏览器对连字符化的支持方式不同。
提示
确保在 <html> 标签上全局声明或在每个应进行连字符化的特定元素上声明 lang 属性。
该属性支持三个关键字值:none、manual 和 auto。
-
none:即使有字符建议在哪里引入行中断,文本行也不会在行中断处中断。行仅在空白处中断。 -
manual:文本行在存在字符建议行中断的地方中断。 -
auto:浏览器根据需要决定引入行中断。它的决定基于连字符字符的存在或语言特定的信息。
Unicode 字符用于建议行中断机会
我们可以使用两个 Unicode 字符来手动在文本中设置潜在的行中断:
U+2010 (HYPHEN)
这个字符被称为硬连字符。它是一个实际的连字符 "-",并且在文本中是可见的。浏览器可能会也可能不会在该特定字符处断行。
U+00AD (SHY)
这个字符被称为软连字符。尽管它在标记中存在,但在文本中不会渲染。然而,浏览器会看到这个字符,如果它可以利用它来创建行中断,它将会这样做。要插入软连字符,我们使用 ­。
CSS:
.element {
hyphens: auto;
}
word-break
word-break CSS 属性用于指定是否应在单词内发生换行而不是在连字符或单词之间的空格处断行,其外观如下:
word-break: break-all;
描述
word-break 属性在长字符串(如 URL)比其父容器宽时非常有用,这会破坏布局或溢出到边缘。应用 word-break 属性会使 URL 在字符串的某个位置断开。
该属性支持三个关键字值:normal、break-all 和 keep-all。
normal
这是默认值。换行将根据默认的换行规则发生。
break-all
这允许在任何地方发生换行,包括两个字母之间。
keep-all
这仅影响 CJK(中文、日文和韩文)文本。在这里,文本单词不会断开。
CSS:
.element {
word-break: break-all;
}
word-spacing
word-spacing CSS 属性控制单词之间的空间,其外观如下:
word-spacing: .2em;
描述
它支持以下值:一个 normal 值、一个 length 值和一个 percentage 值。
normal
这是默认值。它由当前字体或浏览器本身定义,并重置为默认间距。
长度值
当我们使用长度值时,我们使用以下单位之一:px、em、in、mm、cm、vw 等
百分比值
对于百分比值,我们使用像 50%、85% 这样的百分比。
CSS:
.element {
word-spacing: .2em;
}
word-wrap
word-wrap CSS 属性允许在长单词中没有建议的断点时在任意位置断开,其外观如下:
empty-cells: hide;
描述
该属性支持两个关键字值:normal 和 break-word。
-
normal:它使长单词在正常断点处断开 -
break-word:它表示原本不可断开单词现在可以在任意位置断开
CSS:
.element {
word-wrap: break-word;
}
line-height
line-height CSS 属性定义了文本行之间的距离。在排版中,行高被称为 leading。
描述
它支持以下值:一个 normal 值、一个 number 值、一个 length 值和一个 percentage 值。
-
normal:这是默认值。行高由浏览器定义。 -
数字值:这是一个没有单位的数字。这是推荐的方法。推荐无单位值的原因是这个值可以级联到子元素。子元素可以根据它们的字体大小调整行高。 -
长度值:当我们使用长度值时,我们使用以下单位之一:px、em、in、mm、cm、vw等。我们也可以使用小数。 -
百分比值:对于百分比值,我们使用像50%、85%这样的百分比。
CSS:
.element {
line-height: 1.6;
}
orphans
让我们先了解术语 孤行。孤行是指当文本块跨越两页时,留在上一页的段落行。在 Web 世界中,这体现在跨越多个列的文本中,其中段落的第一个行留在前一列。
从编辑的角度来看,这非常不好。推荐的孤儿处理方法是至少在上一页或列上留下三行。行数越多越好。
orphans CSS 属性控制上一页上剩余的行数,其格式如下:
orphans: 3;
描述
这个属性在打印样式表中非常有用,但在使用 CSS 列时也可以工作。
它支持不带单位的数值。这个数值定义了上一页或列上剩余的行数。
CSS:
/*Print stylesheet*/
@media print {
.element {
orphans: 3;
}
}
/*Screen stylesheet*/
.element {
orphans: 4;
}
引号
quotes CSS 属性控制要使用的引号类型,其格式如下:
quotes: """ """ "'" "'";
描述
引号通过 :before 和 :after 伪元素添加。
添加引号最简单的方法是让浏览器使用 content 属性和 open-quote 以及 close-quote 值来完成:content: open-quote; 和 content: close-quote;。
我们也可以声明我们想要使用的引号类型,而不是让浏览器决定。我们将在下面的 CSS 示例中看到这一点。
引号始终以双字符符号开始和结束,例如 " " 或例如法语中的 « »。但是,如果有嵌套引号,这个嵌套引号使用单字符符号,例如 ' ' 或例如法语中的 ‹ ›。
这个属性支持两个值:none 和 [string string] 值。
none
使用 content 属性时不会生成引号。
[string string +] 值
每个 string 代表一对引号。第一个 string 代表外层引号,第二个 string 代表嵌套层引号。
+ 符号表示我们可以添加更深层次的嵌套引号,但实际上并不必要,两层通常适用于大多数情况。
考虑到这些考虑因素,我们可以使用 quotes 属性创建以下引号:
CSS:/*Quotation marks inserted by the browser " " and ' '*/
p:before { content: open-quote; }
p:after { content: close-quote; }
/*Custom declared quotation marks*/
p { quotes: """ """ "'" "'"; }
/*French quotation marks*/
p { quotes: "«" "»" "‹" "›"; }
widows
让我们先澄清一下术语 widows。孤儿是指当文本块跨越两页时,出现在下一页的段落行。在 Web 世界中,这体现在跨越几个列的文本中,其中段落的最后一行出现在下一列。
从编辑的角度来看,这非常不好。推荐的孤儿处理方法是至少在下一页或列上留下三行。行数越多越好。
CSS 的 widows 属性控制下一页将出现的行数,其格式如下:
widows: 3;
描述
widows 属性在打印样式表中非常有用,但在使用 CSS 列时也可以工作。
它支持不带单位的数值。这个数值定义了下一页或列将出现的行数。
CSS:
/*Print stylesheet*/
@media print {
.element {
widows: 3;
}
}
/*Screen stylesheet*/
.element {
widows: 4;
}
writing-mode
writing-mode CSS 属性定义文本行或甚至块级元素布局的方向,无论是垂直还是水平,其格式如下:
writing-mode: vertical-rl;
描述
这个属性支持三个关键字值:horizontal-tb、vertical-rl 和 vertical-lr。
horizontal-tb
这意味着水平,从上到下。内容从左到右,从上到下流动。
vertical-rl
这意味着垂直,从右到左。内容被旋转 90 度并垂直流动。
为了更好地理解,可以这样想:将你的头向右肩倾斜,在这个时候,你将能够从顶部(在你倾斜头部之前在右边)读到文本流动到底部(在你倾斜头部之前在左边)。
vertical-lr
这意味着垂直,从左到右。内容被旋转 90 度并垂直流动。
然而,与 vertical-rl 不同,当你将头靠在右肩上时,内容从底部(在你倾斜头部之前在左边)流向顶部(在你倾斜头部之前在右边),并且文本行是颠倒的。
CSS:
.element {
writing-mode: vertical-rl;
}
letter-spacing
letter-spacing CSS 属性定义了文本行中字符之间的空间,它看起来像这样:
letter-spacing: 5px;
描述
letter-spacing 属性支持以下关键字值:normal 和 length。
负值是有效的。
小贴士
除非你理解可读性和设计影响,否则大多数字体中的默认字母间距是理想的,很少需要更改。
CSS:
.element {
letter-spacing: 5px;
}
white-space
white-space CSS 属性定义了元素内部空白将被如何处理,它看起来像这样:
white-space: pre-wrap;
描述
这个属性支持五个关键字值:normal、nowrap、pre、pre-wrap 和 pre-line。
normal
这是默认值。如果有两个或更多空格连在一起,它们将合并为一个空格。这是 HTML 文档的正常行为。它会在必要时换行文本。
nowrap
多个空格将合并为一个空格,除非在标记中有 <br> 标签,否则行永远不会自动换行。
pre
它与 HTML 元素 <pre> 相同,意味着预格式化。这个值将尊重文本中的所有空格,但除非在标记中有 <br> 标签,否则不会换行,就像 nowrap 一样。这个值非常适合显示短段代码。
pre-wrap
这个值尊重所有空格,并在必要时换行。这个值非常适合显示长段代码。
pre-line
这个值将多个空格合并为一个空格,并在必要时换行。
tab-size
tab-size CSS 属性允许我们定义制表符可以有多少个空格。
正如我们在之前的 white-space 属性描述中看到的,默认情况下多个空格会被合并为一个空格。因此,这个属性只会在 <pre> 标签内的元素或具有尊重多个空格的 white-space 属性(pre 和 pre-wrap)的元素上起作用。
这个属性非常适合显示代码。
制表符字符的默认空格数是 8。但我们,作为网页设计师和开发者,很挑剔,喜欢四格或有时是两格。使用 tab-size 属性,我们可以将其默认值修改为我们想要的任何值。
描述
tab-size 属性支持两个值:一个数值和一个长度值。
-
数值:它只是一个没有单位的数字。负值无效。
-
长度值:当我们使用长度值时,我们使用以下单位之一:
px、em、in、mm、cm、vw等。
CSS:
pre {
white-space: pre-wrap;
tab-size: 4;
}
分页
尽管我们为网络构建网站和应用,但有时我们制作的内容也会被打印出来。
以下属性将帮助我们使我们的内容在打印时更具可读性和跨页处理得更好。
让我们来检查这些分页属性。
page-break-after
page-break-after CSS 属性定义了在特定元素之后分页的位置,看起来是这样的:
page-break-after: always;
描述
这意味着当创建新的分页符时,将打印新的一页。
它仅适用于块级元素。此外,由于此属性用于打印,通常在 @print 媒体查询内看到它。
此属性支持五个关键字值:always、auto、avoid、left 和 right。
-
always:此值将在元素后强制分页。 -
auto:这是默认值。它创建自动分页符。 -
avoid:如果可能,这将不允许在元素后有任何分页。 -
left:这将强制在元素后进行一个或两个分页,以便使下一页成为左侧页面。 -
right:这将强制在元素后进行一个或两个分页,以便使下一页成为右侧页面。
CSS:
@media print {
.element {
page-break-after: always;
}
}
page-break-before
page-break-before CSS 属性与 page-break-after CSS 属性类似。然而,它定义了在特定元素之前分页的位置,看起来是这样的:
page-break-before: always;
描述
当创建新的分页符时,将打印新的一页。
它仅适用于块级元素。此外,由于此属性用于打印,通常在 @print 媒体查询内看到它。
此属性支持与 page-break-before 属性相同的五个关键字值:always、auto、avoid、left 和 right。
请参阅 page-break-before CSS 属性部分,了解每个关键字值的描述。
CSS:
@media print {
.element {
page-break-before: always;
}
}
page-break-inside
page-break-inside CSS 属性与 page-break-before 和 page-break-after 属性类似。然而,它定义了在特定元素内部分页的位置,看起来是这样的:
page-break-inside: avoid;
描述
这意味着当创建新的分页符时,将打印新的一页。
尽管这个属性只支持两个关键字值,即 auto 和 avoid。
-
auto:这是默认值。它创建自动分页符。 -
avoid:如果可能,这将不允许在元素内部有任何分页。
CSS:
@media print {
.element {wdwqd
page-break-before: avoid;
}
}
第六章:CSS 属性 – 第三部分
现在我们完成了 CSS 属性的第二部分,让我们以第三部分的内容来结束。
让我们来做这件事。
页面框
页面框是由两部分组成的正方形/矩形区域:页面区域 和 页边距区域。
页面区域是内容所在的地方,所有元素都进行布局。页边距区域位于页面区域周围,是透明的。如果我们给页面区域添加背景颜色,它将覆盖页面区域和页边距区域。
页面框的大小不能修改。但如果我们计划修改页面框的一些属性,我们需要在 @page 规则中包含它们。
让我们来看看。
bleed
bleed CSS 属性也称为 CSS at-rule 描述符。它定义了页面应该溢出或超出页面框的多少。此属性仅在已使用 marks 属性启用标记的情况下才有效,我们将在下一部分看到。
描述
bleed 属性仅支持长度值:px、em、in、mm、cm、vw 等。
CSS:
@page {
bleed: 5mm;
}
marks
marks CSS 属性,也称为 CSS at-rule 描述符,定义了应在页面框外渲染和打印的标记类型。
由于标记是在页面框外打印的,因此页面需要稍微大一点,以便有空间打印标记。
描述
marks 属性支持三个关键字值:crop、cross 和 none。
-
crop:裁剪标记定义了页面应该被裁剪的位置 -
cross:交叉标记用于对齐页面 -
none:标记将不会显示
CSS:
@page {
marks: crop cross;
}
列表
CSS 列表是网页设计中最多变的元素之一。除了用于创建列表之外,它们还用于导航、布局、幻灯片、轮播图等。
让我们看看它们的属性。
list-style
list-style CSS 属性是 list-style-type、list-style-image 和 list-style-position 属性的缩写。这些属性实际上是 list-style CSS 属性支持的值。我们将在下一部分看到所有这些属性。
描述
list-style 属性支持一个、两个或三个值,顺序不限。如果没有声明值,它将使用其默认值。
CSS:
/*Default values*/
ul { list-style: disc outside none; }
/*One value, the other two are default*/
ul { list-style: circle; }
/*Two values, the other one is defaults*/
ul { list-style: lower-roman inside; }
/*Three values*/
ul { list-style: decimal outside url(../images/list-bullet.png); }
list-style-type
list-style-type CSS 属性定义了列表将使用的图形或标记(也称为 项目符号)。标记的颜色由应用到的元素的文本颜色决定。
描述
list-style-type 属性支持许多值,但我们将列出最常用的 15 个:armenian、circle、decimal、decimal-leading-zero、disc、georgian、lower-alpha、lower-greek、lower-latin、lower-roman、none、square、upper-alpha、upper-latin 和 upper-roman。
这里有一个截图,除了 none 值以外的所有值:

CSS:
/*Style: 01, 02, 03...*/
ul { list-style-type: decimal-leading-zero; }
/*Style: α, β, γ...*/
ul { list-style-type: lower-greek; }
/*Style: A, B, C...*/
ul { list-style-type: upper-latin; }
list-style-position
list-style-position CSS 属性定义了标记的位置。
描述
list-style-position 属性支持两个关键字值:inside 和 outside。
内部
当应用 inside 值时,标记将出现在文本内部。如果有换行,标记将被左对齐,不会像传统列表那样“突出”。
外部
默认值是 outside。当应用此值(或没有应用,因为它是默认值)时,标记将出现在文本外部。如果有换行,标记将出现在文本块外部。它将“突出”出来,就像在传统列表中一样。
CSS:
ul {
list-style-position: inside;
}
列表样式图像
list-style-image CSS 属性允许我们用自定义图像替换默认标记。
描述
list-style-image 属性支持一个关键字值和一个函数:none 和 url()。
-
none: 不使用图像替换标记 -
url(): 它用于定义替换标记的图像的路径
CSS:
ul {
list-style-image: url(../images/list-bullet.png);
}
这里有一个包含所有 HTML 列表的 CodePen 示例:tiny.cc/html-lists
计数器
通过 <ul>、<ol>、<dl> 标签的传统列表在样式标记方面并不太灵活。有时,我们必须依赖额外的标记来完成一些基本的自定义样式。
与此同时,CSS 计数器将样式列表(或任何元素)提升到了一个全新的定制和样式水平。
虽然 CSS 计数器不仅依赖于我们接下来将要看到的属性,还依赖于 content 属性和 :before 伪元素。
让我们来看看使 CSS 计数器如此出色的属性。
counter-reset
counter-reset CSS 属性通过提供一个名称来重置计数器,其外观如下:
counter-reset: basic-counter;
描述
counter-reset 属性有两个作用:重置计数器并为计数器定义一个名称。该名称稍后将被我们稍后看到的 counter-increment 和 counter()/counters() 函数使用。
我必须承认,如果用counter-reset来设置计数器的名称,这个术语并不像它应该的那样直观。如果问我,像counter-name这样的术语会更合适。
该属性支持两个值:一个 名称 和一个 数字。
我们可以在同一个声明中引用多个计数器重置。
名称
我们需要给重置计数器一个名称。这个值是必需的。可以是任何名称,但需要遵守以下条件:
-
它可以以字母、下划线 "
_" 或连字符 "-" 开头 -
它可以以连字符 "
-" 字符开头,但不能以两个连续的连字符开头 -
名称不能只是一个连字符"
-";至少需要一个额外的字符,但不能是数字,因为这将解释为“减 1”(-1) -
它不能以数字或像
#、$、!等特殊字符开头
数字
这是计数器重置到的数字。如果没有声明值,默认值是0(零)。
此值是可选的,除非我们想要从不同于 1 的数字开始列表。请特别注意此值,因为列表中的第一个数字不是在此值中声明的数字。
如果我们将值设置为 1,列表从 2 开始。如果我们留空值,它默认为 0(零),列表从 1 开始。负值是有效的。
CSS:
/*Define a name and counter reset to 0*/
ul { counter-reset: basic-counter; }
/*The counter will start at 3*/
ul { counter-reset: basic-counter 2; }
/*Multiple counters in a single declaration*/
ul { counter-reset: basic-counter-A, basic-counter-B 2; }
counter-increment
counter-increment CSS 属性增加一个或多个计数器的值,其外观如下:
counter-increment: basic-counter 2;
描述
这个属性与 counter-reset CSS 属性一起使用。这是因为 counter-reset 属性中指定的名称在 counter-increment CSS 属性中使用。
作为复习,请记住计数器名称也将由 counter()/counters() 函数使用。
我们可以在同一个声明中声明多个计数器增量。多个计数器之间用空格分隔。此属性支持两个值:一个 名称 和一个 数字。
name
它可以是任何名称,但需要遵守以下条件:
-
它可以以字母、下划线 "
_" 或连字符 "-`" 开头 -
它可以以连字符 "
-" 字符开头,但名称开头不能有两个连续的连字符 -
名称不能只是连字符 "
-";至少需要更多字符,但不能是数字,因为这将解释为 "minus 1" (-1)。 -
它不能以数字或特殊字符如
#、$、!等开头。
number
这是计数器重置到的数字。如果没有声明值,默认值为 0(零)。此值是可选的,除非我们想要从不同于 1 的数字开始列表。
现在,number 值定义了每个计数器将有的增量数量。例如,如果我们声明 2,那么计数器将是 2、4、6 等等。如果我们声明 3,那么计数器将是 3、6、9 等等。
如果我们没有声明值,默认增量将是 1,例如 1、2、3 等等。
负值是有效的。如果我们声明 -2,那么计数器将是 -2、-4、-6 等等。
CSS:
/*First, define a name and counter reset to 0 with counter-reset*/
ul { counter-reset: basic-counter; }
/*Then, invoque the counter name and increment every element by 2 (2, 4, 6, and so on.)*/
ul li { counter-increment: basic-counter 2; }
/*Multiple counters*/
ul li { counter-increment: basic-counter 2 roman-numeral-counter; }
这里是一个在 CodePen 上的演示:tiny.cc/css-counters
投影阴影
有三种方法可以创建深度效果:使用灯光、阴影或两者结合。
让我们看看我们是如何为我们的容器创建阴影的。
box-shadow
box-shadow CSS 属性在元素上创建一个或多个阴影,其外观如下:
box-shadow: 10px 10px 13px 5px rgba(0, 0, 0, .5) inset;
描述
box-shadow 属性在同一声明中支持三个、四个、五个或六个值:四个 长度 值、一个 颜色 值和 关键字 inset。
长度值
当我们使用长度值时,我们使用以下单位之一:px、em、in、mm、cm、vw 等等。
四个长度值如下:
-
第一个值是阴影的水平偏移。负值是有效的。此值是必需的。
-
列表中的第二个值是用于阴影的垂直偏移。负值有效。此值是必需的。
-
列表中的第三个值是用于阴影的模糊半径。值越大,阴影扩散得越广,但同时也越透明。负值无效。此值是必需的。
-
列表中的第四个值是用于阴影的大小(或“扩散半径”)。负值有效。此值是可选的。
颜色值
这是列表中的第五个值。它支持所有颜色模式:HEX、RGB、RGBa、HSL、HSLs和颜色名称。
此值是可选的。如果没有指定颜色,则由浏览器决定使用哪种颜色。某些浏览器甚至可能在没有颜色值的情况下根本不显示阴影。
颜色值可以放在声明开始或结束处,但不能放在长度值之间;否则,box-shadow属性将不起作用。
inset
列表中的第六个值是inset。它创建容器内的阴影,就像背景一样。然而,如果实际上有背景颜色或图像,inset阴影将位于其上方但内容下方,不影响容器子元素的布局。
此值是可选的。如果没有声明此值,阴影默认显示在元素外部。
此值可以放在声明开始或结束处,但不能放在长度值之间;否则,box-shadow属性将不起作用。
CSS:
/*Left 10px, top 10px, blur 13px, spread 5px, RGBa mode, inside the element*/
.element {
box-shadow: 10px 10px 13px 5px rgba(0, 0, 0, .5) inset;
}
显示和可见性
显示属性是网页设计和开发中最广泛使用的 CSS 功能之一。
让我们来检查一下。
all
all CSS 属性将元素属性重置为其默认值,其外观如下:
all: initial;
描述
唯一不重置的属性是direction和unicode-bidi属性,它们控制文本方向。这很重要,因为文本方向是理解内容所必需的。如果这些属性被all属性重置,则文本将按照相反的方向运行,完全破坏信息。
此属性支持三个关键字值:initial、inherit和unset。
-
initial: 这将更改元素或其父元素的属性,将其更改为它们的初始值。 -
inherit: 这将更改元素或其父元素的属性,将其更改为父值。 -
unset: 这将更改元素或其父元素的属性,如果这些属性是可继承的,则将其更改为父值,否则将更改为它们的初始值。
CSS:
/*Change an element's properties to their initial value*/
.element { all: initial; }
/*Inherit all the initial properties of the parent container*/
.element { all: inherit; }
/*Change the parent's properties to its parent values if inheritable*/
.parent-container { all: unset; }
clear
clear CSS 属性指定元素哪一侧,或两侧,不应浮动,其外观如下:
clear: both;
描述
当使用clear属性时,它清除特定的框,而不是其子元素。如果我们想清除其子元素,我们必须在它们上声明clear属性。
当处理基于浮动的网格时,此属性对布局至关重要。这是因为浮动元素被移出文档流。因此,其父容器不会考虑它们,其高度也不再由这些浮动元素决定。
因此,向父元素的:after伪元素添加清除声明(带有display和content属性)"告诉"父元素考虑浮动元素,因此父容器的高度现在由最高的浮动子元素决定。让我们看看下面的图片:

这里是一个 CodePen 上的演示:tiny.cc/clearing-floats
clear CSS 属性支持四个值:left、right、both和none。
-
left: 这意味着不允许向左浮动元素。 -
right: 这意味着不允许向右浮动元素。 -
both: 这意味着不允许左右两侧的浮动元素。 -
none: 这是默认值。不执行清除操作,允许两侧都有浮动元素。
CSS:
/*Float an element to the left*/
.element-a { float: left; }
/*Float an element to the right*/
.element-b { float: right; }
/*Clear the floats on the parent container*/
.parent-container:after {
content: '';
display: table;
clear: both;
}
display
display CSS 属性定义了元素(框)应在页面上如何显示或不应显示。它看起来像这样:
display: block;
描述
此属性接受大约 25 个关键字值;其中一些非常晦涩且很少使用。让我们关注最相关的 15 个:
-
block -
flex -
grid -
inline -
inline-block -
inline-flex -
none -
table -
table-cell -
table-column -
table-column-group -
table-footer-group -
table-header-group -
table-row -
table-row-group -
block: 将元素显示为块级元素,就像<div>标签或<h1>元素一样。 -
flex: 将元素显示为块级元素,并根据Flexbox模型布局其内容。 -
grid: 将元素显示为块级元素,并根据Grid模型布局其内容。 -
inline: 将元素显示为内联级元素,就像链接<a>元素一样。 -
inline-block: 将元素显示为内联块级元素,就像列表<li>元素一样。 -
inline-flex: 将元素显示为内联元素,并根据Flexbox模型布局其内容。 -
none: 隐藏元素在浏览器中的渲染。尽管如此,元素仍然存在于标记中。当此值应用于元素时,浏览器不会渲染该元素及其所有子元素。
表相关值
在以下列表中,所有table-related值都映射到一个 HTML 元素。因此,当这些值应用于元素时,它们使该元素表现得像table-related元素。让我们看看属性:
-
table =
<table> -
table-cell =
<td> -
table-column =
<col> -
table-column-group =
<colgroup> -
table-footer-group =
<tfoot> -
table-header-group =
<thead> -
table-row =
<tr> -
table-row-group =
<tbody>
访问 MDN 以获取所有显示值的列表:tiny.cc/mdn-display
CSS:
/*Make an element display like a block level element*/
.element { display: block; }
/*Make an element display like a <table> element*/
.element { display: table; }
/*Make an element display like an inline-block element - <li>*/
.element { display: inline-block; }
/*Hide an element an its children*/
.element { display: none; }
透明度
The opacity CSS property defines the transparency (opacity) of an element, and it looks like this:
opacity: .55;
描述
当opacity属性应用于一个元素时,该元素及其子元素都会受到影响。
该属性支持从 0.0(零)到 1.0 的数值范围,默认值为 1.0。值为 0 表示完全透明,即 0%不透明,值为 1 表示 100%不透明,没有任何透明度。允许使用小数。
该属性的行为与 RGBa 和 HSLa 颜色模式中使用的 alpha 通道值相同。
CSS:
/*Make an element 55% opaque. This affects its children as well*/
.element { opacity: .55; }
/*Makes shadow 20% opaque. Same effect as in RGBa and HSLa color modes.*/
.element { box-shadow: 0 0 5px rgba(0, 0, 0, .2); }
filter
The filter CSS property allows us to apply visual effects to an img element or to the background or border properties, and it looks like this:
filter: blur(10px);
描述
CSS 滤镜的一些例子包括模糊、将彩色图像转换为灰度或棕褐色,或改变其透明度。
小贴士
This filter property is not the same as Microsoft's proprietary filter property that only IE supports. Unlike Microsoft's proprietary filters, which are not part of a standard, this CSS filter property is part of a work in progress of the W3C.
该属性支持 11 个值。这些值被称为 CSS 函数。可以在同一个选择器中声明多个函数,用空格分隔。
让我们看看列表:
-
blur() -
brightness() -
contrast() -
drop-shadow() -
灰度
-
hue-rotate() -
invert() -
opacity() -
saturate() -
sepia() -
url()
blur()
这会产生一种模糊效果。值以长度值(px、em、in、mm、cm、vw等)声明。值越高,模糊效果越强烈(反之亦然)。
不允许使用百分比和负值,但允许使用小数。
brightness()
这会修改图像的照明。值以百分比或没有单位的数字声明,例如,10%和 0.5%。
值为 100%保持元素不变,值为 0%使元素完全变黑。允许使用大于 100%的值,以产生更强烈的效果。值没有上限。
然后,值为 1 保持元素不变;值为 0 使元素完全变黑。允许使用大于 1 的值,以产生更强烈的效果。值没有上限。
对比度
这会修改元素的对比度。值以百分比或没有单位的数字声明,例如,10%和 0.5%。
值为 100%保持元素不变,值为 0%使元素完全变黑。允许使用大于 100%的值,以产生更强烈的效果。值没有上限。
然后,值为 1 保持元素不变;值为 0 使元素完全变黑。允许使用大于 1 的值,以产生更强烈的效果。值没有上限。负值无效,允许使用小数。
drop-shadow()
这将在元素下方添加一个阴影。
此函数几乎与box-shadow属性完全相同,但有两个不同之处:drop-shadow()函数不支持spread-radius属性或inset值。
请参阅box-shadow属性以获取所有值的详细描述。
此外,一些浏览器在使用此函数时实际上会提供硬件加速,这最终会提高性能。你知道的,我们能做的任何提高性能的事情都是加分项。
grayscale()
这将元素转换为灰度。值声明为不带单位的百分比或数字,例如,10%和 0.5%。
0%的值不会改变元素;100%的值将元素转换为灰度。不允许超过 100%的值。
0 的值不会改变元素,而 1 的值将元素转换为灰度。不允许超过 1 的值。负值无效,允许使用小数。
hue-rotate()
这将对元素应用色调旋转。它接受一个角度值。
角度值定义了元素样本将修改到的颜色轮上的度数。然而,如果没有最大值,如果值大于360deg,旋转将只是循环。例如,如果我们声明380deg,那么它等同于20deg。
invert()
invert()函数反转元素的颜色。如果用于图像,它会使图像看起来像负片。
100%的值完全反转元素的颜色;0%的值不会改变元素。不允许超过 100%的值。
1 的值完全反转元素的颜色,而 0 的值不会改变元素。不允许超过 1 的值。
负值无效,允许使用小数。
opacity()
它定义了元素的透明度(不透明度)。当此函数应用于元素时,元素及其子元素都会受到影响。
此函数支持从 0(零)到 1 的数值范围,这是默认值。0 是完全透明的,就像 0%不透明一样,而 1 是 100%不透明,没有任何透明度。
负值无效,允许使用小数。
saturate()
它影响元素的饱和度级别。值声明为不带单位的百分比或数字,例如,10%和 0.5%。
元素的默认饱和度值为 100%,或使用无单位数字时的 1。
0%的值完全去饱和元素(它移除所有颜色,使元素变为灰度);100%的值不会改变元素。允许超过 100%的值,创建更强烈的效果。
0 的值完全去饱和元素(它移除所有颜色,使元素变为灰度),而 1 的值不会改变元素。允许超过 1 的值,创建更强烈的效果。
sepia()
这会将元素转换为棕褐色——想象一下灰度图像,但以棕色色调呈现。
值为 100% 完全将元素转换为棕褐色;值为 0% 保持元素不变。不允许超过 100% 的值。
值为 1 完全将元素转换为棕褐色;值为 0 保持元素不变。不允许超过 1 的值。负值无效。
url()
它接受一个 XML 文件的位置,该文件包含应用于元素的 SVG 过滤器。URL 可以包含指向 SVG 中特定过滤元素的锚点。
CSS:
/*Blur*/
.element { filter: blur(10px); }
/*Brightness*/
.element { filter: brightness(20%); }
/*Contrast*/
.element { filter: contrast(10); }
/*Drop shadow*/
.element { filter: drop-shadow(5px 5px 3px rgba(0, 0, 0, .5)); }
/*Grayscale*/
.element { filter: grayscale(.8); }
/*Hue rotation*/
.element { filter: hue-rotate(80deg); }
/*Invert*/
.element { filter: invert(1); }
/*Opacity*/
.element { filter: opacity(.2); }
/*Saturation*/
.element { filter: saturate(300%); }
/*Sepia*/
.element { filter: sepia(100%); }
/*URL*/
.element { filter: url(/images/file.svg#blur); }
/*Multiple filters for a single element*/
.element { filter: sepia(100%) saturate(200%) hue-rotate(50deg); }
overflow
overflow CSS 属性定义了块级元素应该如何处理超出其边界的内容(“溢出”),其外观如下:
overflow: auto;
描述
overflow 属性的一个特性是它用于清除浮动,并使父容器垂直扩展以包裹浮动元素。这是通过使用以下任何值(除了 visible)来实现的。
然而,有一个警告。当使用先前的技术时,可能会有意想不到的效果。例如,如果一个子元素有 box-shadow,阴影可能会被裁剪/隐藏。
为了使内容溢出,父容器需要具有固定高度,或者内容需要应用 white-space: nowrap; 声明。
该属性支持四个关键字值:auto、hidden、scroll 和 visible。
-
auto:只有当需要时才会创建水平和垂直滚动条。换句话说,如果内容在任何方向上超出容器,浏览器将在一个或两个轴上创建滚动条。 -
hidden:这将裁剪/隐藏元素之外的内容。不会生成滚动条。这个值在清除浮动时非常受欢迎。再次提醒,使用此值时要小心。 -
scroll:即使内容没有超出容器,也会创建水平和垂直滚动条。 -
visible:这是默认值。不裁剪/隐藏任何内容,也不生成滚动条。
CSS:
/*Scroll bars are generated if the content needs them*/
.element {
white-space: nowrap;
overflow: auto;
}
/*Clearing floats. Be careful with this technique*/
.parent-container { overflow: hidden; }
overflow-x
overflow-x CSS 属性的行为与 overflow 属性相同,其外观如下:
overflow-x: auto;
描述
不同之处在于 overflow-x 属性处理的是 X 轴(水平)上的溢出。请参考 overflow 的描述,因为值是相同的。
CSS:
.element {
white-space: nowrap;
overflow-x: auto;
}
overflow-y
overflow-y CSS 属性的行为类似于 overflow 属性,其外观如下:
overflow-y: auto;
描述
不同之处在于 overflow-y 属性处理的是 Y 轴(垂直)上的溢出。请参考 overflow 的先前描述,因为值是相同的。
CSS:
.element {
height: 100px;
overflow-y: auto;
}
visibility
visibility CSS 属性定义了元素是否可见,其外观如下:
visibility: hidden;
描述
在隐藏元素方面,visibility 属性类似于 display: none;,区别在于使用 visibility 属性隐藏元素时,该元素占据的空间仍然会影响布局。它只是“不可见”。使用 display: none;,就像元素根本不存在一样。
visibility CSS 属性是不可继承的;换句话说,即使它们的父容器不可见,我们仍然可以使子元素可见。它也可以用于隐藏表格中的行和列。
这个属性支持三个不同的关键字值:collapse、hidden和visible。
-
collapse:这个属性仅用于表格元素,用于删除行或列。然而,折叠/隐藏的元素仍然会影响布局,因为它们仍然占据着它们的空间。如果在这个值用于除表格元素之外的元素上,它们将被视为使用了hidden值。 -
hidden:这个属性用于视觉上隐藏一个元素。然而,任何隐藏的元素仍然会影响布局,因为它们仍然占据着它们的空间。 -
visible:这是默认值。它使一个元素可见。
CSS:
/*Hide an element*/
.element { visibility: hidden; }
/*Parent container visible while child heading is visible*/
.parent-container { visibility: hidden; }
.parent-container h1 { visibility: visible; }
/*Hide table elements*/
tr { visibility: collapse; }
tfoot { visibility: collapse; }
z-index
z-index CSS 属性定义了元素的堆叠顺序。可以这样想:元素有时会重叠,就像桌子上的一叠扑克牌。位于堆叠顶部的牌具有最高的 z-index,位于底部的牌具有最低的 z-index。
为了使这个属性生效,元素必须有一个声明了任何不同于 static 值的 position 属性。
描述
z-index 属性接受两个值:一个数字和一个关键字值。
-
数值类型:这也可以称为一个“整数”。它只是一个没有单位的数字。
-
auto:这是默认值。元素的堆叠顺序与它们的父元素相同。
CSS:
/*Set all cards to relative position so z-index can work*/
.card { position: relative; }
/*The Ace card sits on top of the pile*/
.card.ace { z-index: 2; }
/*The Five card sits at the bottom of the pile*/
.card.five { z-index: 0; }
/*The Queen card sits in between the Ace and the Five*/
.card.queen { z-index: 1; }
遮罩和裁剪
这两个特性允许我们隐藏元素的一部分,以便显示背景图像或颜色,或者给元素一个特殊的形状。这两个术语可能有点令人困惑,所以让我们简要地描述每个术语:
-
裁剪是通过向量或路径完成的,因为这项 CSS 功能是从 SVG 规范中借鉴的。它创建了一个元素与其背景之间的实边。
-
另一方面,遮罩使用图像/位图。使用图像,我们可以有“羽化”或模糊的边缘,而使用裁剪则有直边。
让我们来看看这些属性。
mask
mask CSS 属性是 mask-clip、mask-composite、mask-image、mask-mode、mask-origin、mask-position、mask-repeat 和 mask-size 属性的缩写。我们将在稍后更详细地了解每个属性。mask 属性看起来是这样的:
mask: url(../images/mask.png) 50% 50% / contain no-repeat border-box;
描述
所有先前属性的组合被称为一个“遮罩层”。
建议使用简写语法而不是单个特定属性,因为简写语法会将未声明的属性重置为其初始值。这很有用,因为它使得在层叠中稍后覆盖值变得更容易,从而避免了特定性问题以及潜在的使用 !important 指令。
此外,mask-clip 和 mask-origin 使用 geometry 值。如果我们只声明一个值,那么这两个属性都将使用该值。如果有两个值,mask-clip 将使用第一个值,而 mask-origin 将使用第二个值。
如我之前提到的,CSS 蒙版使用图像,这意味着我们可以使用 linear-gradient() CSS 函数引用具有透明度的位图/光栅文件或具有背景渐变的背景。我们甚至可以通过在同一个声明中引用多个图像来创建蒙版。
有两种类型的蒙版:alpha 蒙版和 亮度 蒙版。我们将在稍后了解每种类型蒙版的内容。
CSS:
/*Mask referencing a bitmap file.
We are specifying: mask-image mask-position / mask-size mask-repeat mask-clip
*/
.element {
mask: url(../images/mask.png) 50% 50% / contain no-repeat border-box;
}
/*Mask using the CSS linear-gradient property*/
.element {
mask: linear-gradient(black 5%, transparent);
}
/*Mask created by declaring multiple masks*/
.element {
mask:
url(../images/mask.png) 50% 50% / contain no-repeat border-box,
linear-gradient(white 5%, transparent);
}
mask-clip
mask-clip CSS 属性确定元素受蒙版影响的区域,其外观如下:
mask-clip: padding-box;
描述
这个属性类似于 background-clip CSS 属性。有关更多信息,请参阅第四章,CSS 属性 - 第一部分。
同一个声明中可以存在多个以逗号分隔的关键字值。每个值代表 mask-image 属性逗号分隔值中的相应图像。
它支持四个关键字值:border-box、content-box、padding-box 和 no-clip。
-
border-box:这是默认值。如果元素有任何边框,它们将通过蒙版可见。 -
content-box:只有元素内容区域内的部分通过蒙版可见。 -
padding-box:如果元素有任何填充,它将通过蒙版可见。 -
no-clip:内容不会被 裁剪。
CSS:
/*Padding box clipping*/
.element { mask-clip: padding-box; }
/*Multiple values*/
.element { mask-clip: padding-box, border-box; }
mask-composite
mask-composite CSS 属性定义了如何将具有不同形状的多个蒙版组合或 合成 成单个蒙版,其外观如下:
mask-composite: intersect;
描述
mask-composite 属性在 mask-image 被使用并且至少声明了两个蒙版图像时起作用。同一个声明中可以存在多个以逗号分隔的关键字值。每个值代表 mask-image 属性逗号分隔值中的相应图像。
mask-composite CSS 属性支持四个关键字值:add、subtract、exclude 和 intersect。
例如,想象一个三角形覆盖在圆形的一部分上,其中三角形在上,圆形在下;不同的 合成 类型会形成不同形状的蒙版:

-
intersect:蒙版的形状是三角形和圆形重叠的部分,或 交集。其余的形状将被丢弃。 -
exclude:三角形和圆形相交的部分被丢弃,其余的元素构成了蒙版。 -
subtract:由于三角形位于上方,它将 裁剪 或 裁剪 圆形,从而留下一个 吃豆人 形状的蒙版。 -
add:三角形与圆形融合,形成一个单一形状,该形状将用作蒙版。
CSS:
/*Intersect the masks*/
.element { mask-composite: intersect; }
/*Multiple values*/
.element { mask-composite: intersect, exclude; }
mask-image
mask-image CSS 属性定义了在给定元素上用作蒙版层的图像或图像,其形式如下:
mask-composite: intersect;
描述
mask-image 属性还可以引用 SVG 文件中的 <mask> 元素。多个值以逗号分隔。图像可以是位图文件、SVG,甚至是图像的 CSS 渐变。
CSS:
/*Mask referencing a bitmap*/
.element { mask-image: url(../images/mask.png); }
/*Mask using a CSS gradient*/
.element { mask-image: linear-gradient(black 5%, transparent); }
/*Mask referencing an SVG <mask>*/
.element { mask-image: url(../images/file.svg#mask); }
/*Multiple values*/
.element { mask-image: url(../images/mask.png), linear-gradient(black 5%, transparent); }
mask-mode
mask-mode CSS 属性定义了蒙版层是 alpha 蒙版还是 luminance 蒙版。这些术语是实际的关键字值,其形式如下:
mask-mode: alpha;
描述
同一个声明中可以存在多个以逗号分隔的关键字值。每个值代表 mask-image 属性逗号分隔值中对应的图像。
Alpha 蒙版
Alpha 蒙版使用图像的 alpha 通道。透明部分将被覆盖;不透明部分将显示出来。当然,图像上的半透明区域将被部分覆盖。
亮度蒙版
亮度蒙版使用图像的 亮度值。在用作蒙版的图像上,白色的部分将显示出来。黑色部分将被隐藏。灰色区域部分覆盖图像。
CSS:
/*Alpha mask*/
.element { mask-mode: alpha; }
/*Multiple values*/
.element { mask-mode: alpha, luminance; }
mask-origin
mask-origin CSS 属性定义了蒙版层相对于元素框从左上角开始的位置或位置,其形式如下:
mask-mode: alpha;
描述
mask-origin 属性的工作方式与 background-origin 属性类似。有关更多信息,请参阅第四章,CSS 属性 - 第一部分。
现在,此属性可以在 HTML 和 SVG 元素中使用。然而,有些关键字值适用于一个,但在另一个中不起作用。
同一个声明中可以存在多个以逗号分隔的关键字值。每个值代表 mask-image 属性逗号分隔值中对应的图像。
HTML 关键字值是 border-box、padding-box、margin-box 和 content-box。
SVG 关键字值是 view-box、fill-box 和 stroke-box。
-
border-box:原点从边框框的左上角开始。应用蒙版时将包括边框和任何填充(如果声明了),但不会超出该边框。 -
padding-box:原点从填充框的左上角开始。应用蒙版时将包括填充,但如果声明了边框,则不包括任何边框。 -
margin-box:原点从边框框的左上角开始。应用蒙版时将包括边距、边框和填充(如果声明了)。 -
content-box:原点从内容框的左上角开始。它只包括 内容 区域。不考虑边距、填充或边框。 -
view-box: 它使用最近的 SVG 视口作为参考框。 -
fill-box: 遮罩的位置相对于对象边界框。 -
stroke-box: 遮罩的位置相对于描边边界框。
CSS:
/*Content box origin; the mask will exclude borders and paddings*/
.element { mask-origin: content-box; }
/*Multiple values*/
.element { mask-origin: border-box, padding-box; }
mask-position
mask-position CSS 属性定义了遮罩的起始位置,其外观如下:
mask-position: right top;
描述
该属性的工作方式与background-position属性类似。有关更多信息,请参阅第四章,CSS 属性 - 第一部分。
同一个声明中可以存在多个以逗号分隔的关键字值。每个值代表mask-image属性逗号分隔值中对应的图像。
mask-position CSS 属性支持几种类型的值:四个关键字值,top、right、bottom和left;一个长度值,px、em、in、mm、cm、vw等等;以及一个百分比值,如 50%、85%等等。
CSS:
/*Keyword values*/
.element { mask-position: right top; }
/*Length and Percentage values*/
.element { mask-position: 50px 25%; }
/*Multiple values*/
.element { mask-position: right top, 50% 50%; }
mask-repeat
mask-repeat CSS 属性定义了遮罩层是否重复,其外观如下:
mask-repeat: space;
描述
该属性的工作方式与background-repeat属性类似。有关更多信息,请参阅第四章,CSS 属性 - 第一部分。
同一个声明中可以存在多个以逗号分隔的关键字值。每个值代表mask-image属性逗号分隔值中对应的图像。
它支持六个关键字值:repeat、no-repeat、repeat-x、repeat-y、space和round。
-
repeat: 遮罩将在X轴和Y轴上重复。这是默认值。 -
no-repeat: 遮罩在任何轴向上都不会重复。遮罩图像只显示一次。 -
repeat-x: 遮罩在X轴(水平方向)上重复。 -
repeat-y: 遮罩在Y轴(垂直方向)上重复。 -
space: 遮罩在X轴和Y轴上尽可能多次重复,而不会被裁剪或切割。 -
round: 与space值类似,不同之处在于遮罩图像会按指定方向进行缩放以适应。
CSS:
/*Space out the mask without clipping it*/
.element { mask-repeat: space; }
/*Repeat the mask in the X-axis (horizontally)*/
.element { mask-repeat: repeat-x; }
/*Multiple values*/
.element { mask-repeat: space, repeat-x; }
mask-size
mask-size CSS 属性定义了遮罩图像的尺寸或大小,其外观如下:
mask-size: contain;
描述
mask-size属性的工作方式与background-size属性类似。有关更多信息,请参阅第四章,CSS 属性 - 第一部分。
同一个声明中可以存在多个以逗号分隔的关键字值。每个值代表mask-image属性逗号分隔值中对应的图像。
mask-position CSS 属性支持几种类型的值:一个长度值,一个百分比值,以及三个关键字值。
-
长度值:这是当我们使用以下单位之一时:px、em、in、mm、cm、vw等等。 -
百分比值:这是当我们使用百分比,如 50%、85%等等时。 -
contain:此选项将图像遮罩缩放,而不扭曲其宽高比,以适应元素的宽度和高度的最大值。 -
cover:此选项将图像遮罩缩放并扭曲(如果需要),以适应元素的宽度和高度的最大值。如果图像遮罩在宽度和高度上更大,它将被裁剪。 -
auto:此选项将图像遮罩缩放至图像固有比例的实际大小,而不会扭曲图像。
CSS:
.element {
mask-size: contain;
}
mask-type
mask-type CSS 属性专门用于 SVG 文件。它指定 SVG <mask> 元素是 alpha 遮罩还是 luminance 遮罩。
关于 alpha 和 luminance 遮罩的定义,请参考 mask-mode 属性。
mask-border
mask-border CSS 属性是 mask-border-source、mask-border-mode、mask-border-slice、mask-border-width、mask-border-outset 和 mask-border-repeat 属性的缩写。其外观如下:
mask-border: url(../images/border-image-mask.png) 15 / 15px stretch and so on;
描述
建议使用缩写,因为未声明的任何值都将设置为它们的初始值,这使得在以后覆盖时更加容易,从而最小化了 !important 指令的使用。
CSS:
.element {
mask-border: url(../images/border-image-mask.png) 15 / 15px stretch;
}
mask-border-source
mask-border-source CSS 属性定义了一个要在 border-image 声明中使用的图像。
CSS:
/*Border image referencing a bitmap file*/
.element { mask-border-image: url(../images/border-image-mask.png); }
/*Border image using a CSS gradient*/
.element { mask-border-image: linear-gradient(red, transparent); }
mask-border-mode
mask-border-mode CSS 属性定义了用于遮罩的图像是 alpha 遮罩还是 luminance 遮罩。
关于 alpha 和 luminance 遮罩的定义,请参考 mask-mode 属性。
CSS:
.element {
mask-border-mode: luminance;
}
mask-border-slice
mask-border-slice CSS 属性用于将图像切割成九部分,其外观如下:
mask-border-slice: 40;
描述
想象这个例子:取一个正方形图像,画两条垂直线和两条水平线。我们最终在图像上得到九个部分,就像 井字棋 一样。
此属性支持一个、两个、三个或四个关键字偏移值:top、right、bottom、left 和 fill。这些值(除了 fill)可以使用不带单位的 number 值或使用 50%、85% 等的 percentage 值声明。
如果声明了一个值,则所有四边都采用该值。如果声明了两个值,则第一个值用于顶部和底部边,第二个值用于左侧和右侧边。如果声明了三个值,则第一个值用于顶部边,第二个值用于左侧和右侧边,第三个值用于底部边。如果声明了四个值,则它们分别对应顶部、右侧、底部和左侧边。
小贴士
当使用位图图像遮罩声明无单位值时,该值被解释为像素。
fill
默认情况下,图像遮罩的中心会被丢弃并视为空白。如果存在此值,则中心将被考虑,并成为遮罩的一部分。
CSS:
/*All sides are offset by 40*/
.element { mask-border-slice: 40; }
/*Top & bottom and left & right values*/
.element { mask-border-slice: 20% 30%; }
/*Make the center of the image part of the mask with top & bottom, and left & right offsets*/
.element { mask-border-slice: fill 40 25; }
mask-border-width
mask-border-width CSS 属性缩放由 mask-border-slices 属性创建的遮罩图像切片,其外观如下:
mask-border-width: auto;
描述
该 mask-border-width 属性支持一个、两个、三个或四个关键字偏移值:top、right、bottom、left 和 auto。除了 auto 之外,这些值可以使用不带单位的 number 值或使用如 50%、85% 等的 percentage 值来声明。
如果声明了一个值,则所有四个边都采用该值。如果声明了两个值,则第一个值用于顶部和底部边,第二个值用于左侧和右侧边。如果声明了三个值,则第一个值用于顶部边,第二个值用于左侧和右侧边,第三个值用于底部边。如果声明了四个值,它们分别对应顶部、右侧、底部和左侧边。
auto
它使遮罩边框使用图像切片的内联宽度和高度。浏览器将决定是否需要使用这个内联宽度和高度。
CSS:
.element {
mask-border-width: auto;
}
mask-border-outset
mask-border-outset CSS 属性定义了边框遮罩图像区域超出其边框框的量,其外观如下:
mask-border-outset: 10px;
描述
该属性支持一个、两个、三个或四个关键字外延值:top、right、bottom 和 left。这些值可以使用不带单位的 number 值或使用 px、em、in、mm、cm、vw 等单位的 length 值来声明。不带单位的 number 值是元素 border-width 属性的乘数。
如果声明了一个值,则所有四个边都采用该值。如果声明了两个值,则第一个值用于顶部和底部边,第二个值用于左侧和右侧边。如果声明了三个值,则第一个值用于顶部边,第二个值用于左侧和右侧边,第三个值用于底部边。如果声明了四个值,它们分别对应顶部、右侧、底部和左侧边。
CSS:
/*All four sides have the same value*/
.element { mask-border-outset: 10px; }
/*Top & bottom and left & right values*/
.element { mask-border-outset: 2 6; }
/*Top, left & right, and bottom values*/
.element { mask-border-outset: 5 20px 2; }
mask-border-repeat
mask-border-repeat CSS 属性定义了图像蒙版如何缩放和铺贴(重复)在元素的所有四个边和中心周围,其外观如下:
mask-border-repeat: repeat;
描述
mask-border-repeat 属性支持一个或两个关键字值。这些值是:repeat、round、stretch 和 space。
repeat
遮罩边框图像是平铺(重复)的。在特定情况下,图像蒙版可以在边缘被裁剪,只显示其中的一部分。
round
这与 repeat 的作用方式类似;区别在于图像蒙版被缩放到正好适合分配的距离,而不会裁剪图像蒙版。
stretch
这是默认值。图像蒙版被拉伸以完全填充区域。
space
与 repeat 类似,但不同之处在于,如果区域没有被完整的图像蒙版填满,它将分配围绕瓦片的空间。
CSS:
.element {
mask-border-repeat: repeat;
}
clip-path
clip-path CSS 属性用于部分或完全隐藏元素的一部分,其外观如下:
clip-path: url(..images/file.svg#clipping-path);
描述
我们可以说clip-path是一种遮罩形式。区别在于裁剪使用矢量图形进行裁剪,而不是位图/光栅图像。
这个矢量图形可以是基本形状或SVG 路径。
小贴士
注意:由于 SVG 的特性和限制不佳,clip CSS 属性现在已被弃用。当前的广泛支持的clip-path属性是 SVG 规范的一部分,并且已被 CSS 遮罩模块采用。
clip-path CSS 属性与shape-outside属性结合可以创建令人惊叹的布局。通过这种组合,我们可以使一个段落围绕一个裁剪元素“弯曲”,其基本形状也是一个曲线或圆形。
该属性支持四个值:三个函数:url()、一个形状、一个几何框,以及一个关键字值none。
url()
这个 CSS 函数指向一个 SVG clipPath 元素,该元素将被用作裁剪路径。
CSS:
/*Clipping path referenced from an external SVG file*/
.element { clip-path: url(..images/file.svg#clipping-path); }
/*Clipping path referenced from an embedded SVG*/
.element { clip-path: url(#clipping-path); }
circle()
这个 CSS 函数声明一个圆作为裁剪路径。此函数接受两个参数:一个形状半径和一个位置。
-
形状半径:它定义了圆的半径。它支持长度、百分比和两个关键字值。不允许使用负值。
两个关键字值是:
closest-side或farthest-side。-
closest-side:这是默认值。如果没有声明此值,浏览器将取圆的中心到其最近边的长度,并基于该距离创建一个圆。这样,圆永远不会溢出或超出内容,它总是完整的。 -
farthest-side:此值将通过从中心到最远边的长度创建一个圆。这意味着如果元素有一边比另一边长,圆将溢出或溢出到对面。
-
-
位置:它定义了圆的位置。位置值由
at词 precede。如果没有声明此值,圆将位于元素的中心。此参数的值与background-position属性的值相同。
CSS:
/*Circle 150px wide and tall with location*/
.element { clip-path: circle(150px at 0 50%); }
/*Circle without location is centered on the element*/
.element { clip-path: circle(150px); }
/*Circle defaults to closest-side and is centered on the element*/
.element { clip-path: circle(); }
ellipse()
这个 CSS 函数声明一个椭圆作为裁剪路径。它接受与circle()函数相同的参数;唯一的区别是它接受两个半径值,rx和ry,用于形状半径而不是一个。rx代表X轴,ry代表Y轴。
CSS:
/*Ellipse with location*/
.element { clip-path: ellipse(200px 100px at 0 50%); }
/*Ellipse without location is centered*/
.element { clip-path: ellipse(200px 100px); }
/*No value makes an ellipse that is as wide an tall as the element*/
.element { clip-path: ellipse(); }
inset()
这个 CSS 函数在元素内部定义一个矩形形状。它可以接受一个、两个、三个或四个偏移值。其语法与margin属性的语法相同。
它支持长度和百分比值。
此外,inset()函数还支持一个可选的border-radius值。此值必须在声明任何长度或百分比之前,由术语round precede。
CSS:
/*Inset clip path where all four offset sides have the same distance*/
.element { clip-path: inset(20px); }
/*Inset clip path with border-radius declared*/
.element { clip-path: inset(5% 20px 10% 40px round 20px); }
polygon()
这个 CSS 函数用于声明更多种类的形状,通常是不同于正方形、圆形或椭圆的不规则形状。
坐标对 用于声明多边形的点;每一对指定一个点的位置。第一个参数表示 X 位置,第二个参数表示 Y 位置坐标。浏览器会自动关闭第一个和最后一个坐标点。坐标值用逗号分隔,并支持 长度 或 百分比 值。
现在,手动创建多边形不仅是一项重大任务,而且可能非常耗时。最好的解决方案是使用工具进行创建过程:
-
Bennet Feely 的 Clippy (
bennettfeely.com/clippy/) -
裁剪路径 生成器 (
cssplant.com/clip-path-generator)
CSS:
/*This polygon has 3 pairs of coordinates so it creates a triangle-shaped clipping path*/
.element { clip-path: polygon(0 0, 0 100%, 100% 0); }
/*Custom polygon (a star) from Bennett Feely's, Clippy tool*/
.element { clip-path: polygon(50% 0%, 63% 38%, 100% 38%, 69% 59%, 82% 100%, 50% 75%, 18% 100%, 31% 59%, 0% 38%, 37% 38%); }
none
没有创建裁剪路径。
图像渲染和方向
确保图像正确显示不仅是设计师的责任,我们作为网页设计师和开发者也有权决定图像在特定情况下的行为和显示方式。
让我们看看如何使用 CSS 改变图像的方向和渲染质量。
image-orientation
image-orientation CSS 属性定义了我们可以对图像应用的旋转,其外观如下:
image-orientation: flip;
描述
许多图像包含有关拍照时使用的设置的详细信息,例如 ISO 速度、光圈、快门速度、相机型号、白平衡、日期和时间等。这些信息被称为 EXIF 数据,CSS 使用这些数据用于图像方向的目的。它还支持在单个声明中包含一个或两个值。
image-orientation 属性支持两个关键字值和一个 角度 值:from-image、flip 和一个 角度 值。
-
from-image:图像使用图像中包含的 EXIF 数据进行旋转。 -
flip:图像水平翻转;它被反射。这个值应该跟在 角度 值之后。 -
角度值:这定义了应用于图像的旋转。它使用一个数字后跟deg单位。这个值应该在flip关键字值之前。
CSS:
/*Flip the image horizontally*/
img { image-orientation: flip; }
/*Rotate the image 180 degrees and flip it horizontally*/
img { image-orientation: 180deg flip; }
/*Follow the orientation from the EXIF information in the image*/
img { image-orientation: from-image; }
image-rendering
image-rendering CSS 属性定义了浏览器应使用哪种算法来渲染缩放图像,其外观如下:
image-rendering: pixelated;
描述
image-rendering CSS 属性适用于缩小或放大的图像。此属性支持三个关键字值:auto、crisp-edges 和 pixelated。
-
auto:这是默认值。当图像放大或缩小时,此属性会 平滑 或模糊图像以保留最佳外观。然而,有时这可能会产生不期望的结果,具体取决于图像类型。 -
crisp-edges:此属性不对图像应用任何平滑或模糊。它保留了其对比度、边缘和颜色。此属性专门为像素艺术创建。 -
pixelated:此属性仅适用于通过最近****邻算法缩放的图像,这使得图像看起来像是用大像素制作的。这在放大类似棋盘、棋盘或二维码的棋盘图案时很有用。
CSS:
/*Good for checkered patterns or QR codes*/
img { image-rendering: pixelated; }
/*Exclusively for pixel art*/
img { image-rendering: crisp-edges; }
用户界面
以下属性直接与用户体验设计相关,但位于前端。在任何构建的开始阶段解决以下属性可以大有裨益。
让我们来看看它们。
cursor
cursor CSS 属性定义了指针的样式,其外观如下:
cursor: pointer;
描述
cursor 属性旨在仅在悬停状态下工作;此属性不打算替换指针在其正常状态下的样式。
所有操作系统都有许多类型的指针,用于各种行为,所以每当我们需要某种动作时,可能已经存在一个相应的指针。
我们还可以使用自定义指针。请注意以下注意事项:
-
建议指针图像为 32 x 32 像素。
-
在自定义图像(或图像)无法加载的情况下,需要声明一个内置指针作为后备。
-
IE 的旧版本需要自定义指针图像的绝对路径。
-
我们可以使用
.cur或.png文件作为自定义指针。然而,旧版 IE 只支持.cur扩展名。
cursor CSS 属性可以在同一声明中接受一个或多个值。
此属性支持以下值:一个 URL、X 和 Y 坐标以及 32 个关键字值。
一个 URL(或 URI)
URL 用于自定义指针。它是图像的路径。可以在同一声明中定义多个 URL。因此,可以使用多个自定义指针。如果声明多个 URL,则值以逗号分隔。
在 URL 声明之后,必须声明一个本地非 URL 值。这样,如果所有其他方法都失败,用户仍然可以使用指针。此值是可选的。
X 和 Y 坐标
X 和 Y 坐标用于将自定义指针与正确的热点对齐。这些坐标只是两个没有单位的数字,仅由空格分隔。
不允许使用负数,值范围从 0 到 32。
32 个关键字值
关键字值使用操作系统或浏览器本地的指针。实际上,对于任何指针动作都有相应的指针。
这里是 32 个关键字值的列表:
-
alias -
all-scroll -
auto -
cell -
col-resize -
context-menu -
copy -
crosshair -
default -
e-resize -
ew-resize -
help -
move -
n-resize -
ne-resize -
nesw-resize -
no-drop -
none -
not-allowed -
ns-resize -
nw-resize -
nwse-resize -
pointer -
progress -
row-resize -
s-resize -
se-resize -
sw-resize -
text -
vertical-text -
w-resize -
wait
最常用的值包括 default、move、pointer 和 text:
-
default:这设置了默认指针。这是我们所有人都知道的箭头指针。 -
move:这设置了移动指针。它看起来像一个大加号,四个端点都有箭头。 -
pointer:这设置指针为“手”图标。 -
text:这设置文本指针。它通常看起来像带衬线的字母"I"但更高。
在这里查看所有光标的动作:tiny.cc/cursor
CSS:
/*Custom cursor with absolute path and coordinates*/
.element { cursor: url(/images/cursor.cur) 10 10, default; }
/*Multiple custom cursors with coordinates*/
.element { cursor: url(/images/cursor-1.png) 5 5, url(/images/cursor-2.png) 0 0, default; }
/*Assign a pointer on the <button> and <select> elements*/
button,
select { cursor: pointer; }
pointer-events
pointer-events CSS 属性控制文档中的元素何时可以成为鼠标/触摸事件的目标,其外观如下:
pointer-events: none;
描述
pointer-events的一个特殊性如下所示:假设我们有两个容器,它们有相当大的重叠。如果我们将pointer-events: none;应用于顶部的元素,点击/触摸就会穿过该元素并针对下方的元素内容。基本上,即使我们点击/触摸顶部的元素,我们也可以选择下方的元素内容。
这个属性支持十个关键字值。然而,只有两个与 HTML 相关;其余的都是 SVG 规范的一部分,这超出了本指南的范围。
与 HTML 相关的值是none和auto。
none
不会有鼠标/触摸事件作用于该元素。然而,如果元素有pointer-events设置为不同值的后代,这些后代元素将触发鼠标事件。
auto
这是默认值。这相当于没有声明pointer-events。
更多关于 MDN 的信息可以在以下链接找到:tiny.cc/mdn-pointer-events
CSS:
/*Clicking/tapping on the element won't work*/
.element { pointer-events: none; }
/*Restore the default clicking/tapping behavior to the element*/
.element { pointer-events: auto; }
outline
outline CSS 属性在元素周围创建一个边框,以提供视觉提示,表明它处于活动状态或已获得焦点。
这个属性是outline-color、outline-width和outline-style属性的简写。为了方便,建议在声明outline时始终使用这个简写,而不是单独的属性。
outline和border之间的区别在于outline不占用空间;它是在内容之上创建的,因此布局永远不会受到影响。
然而,声明outline值与声明border值完全相同。
描述
outline CSS 属性支持三个用长写属性表示的值:颜色、宽度和样式。所有三个值都是必需的,可以在声明中按任何顺序出现。
-
color:这映射到outline-color属性。它是轮廓的颜色。它支持所有颜色模式:HEX、RGB、RGBa、HSL、HSLs和颜色名称。 -
width:这映射到outline-width属性。它是轮廓的厚度。它支持任何长度值,例如px、em、in、mm、cm、vw等等。百分比值无效。 -
style:这映射到outline-style属性。它表示要使用的线的类型。它接受与border相同的值:dashed、dotted、double、groove、hidden、inset、none、outset、ridge和solid。
CSS:
.element {
outline: dotted 2px rgba(0, 0, 0, .5);
}
三维
CSS 的功能令人惊叹;我们不仅可以用 CSS 做出惊人的动画,CSS 还可以处理三维设计。
让我们来看看那些使我们能够做到这一点的属性。
视点
perspective CSS 属性定义了屏幕和用户在 Z 轴之间的距离,其外观如下:
perspective: 300px;
描述
请记住,perspective 属性应用于父元素,以便启用一个 3D 画布或空间,其中其子元素将移动。
该属性接受一个关键字值 normal 和一个长度值。
normal
父元素上没有定义透视。
长度值
这时我们会使用以下单位之一:px、em、in、mm、cm、vw 等等。
值越低,元素在 Z 轴上移动得越近。因此,透视效果越明显。值越高,透视效果越不强烈。
CSS:
/*Enable perspective for child elements by applying it on the parent container*/
.parent-container { perspective: 300px; }
/*Child element will move in a 3D plane*/
.parent-container .element { transform: rotateX(170deg); }
视点原点
perspective-origin CSS 属性定义了元素在 3D 空间中 X 和 Y 轴的原点,其外观如下:
Perspective-origin: 24% center;
描述
这就是 perspective 属性所使用的所谓消失点。perspective-origin 属性支持三种类型的值组合:一个长度值、一个百分比值,以及 X 和 Y 轴上的五个关键字值。
长度值
这时我们会使用以下单位之一:px、em、in、mm、cm、vw 等等。
百分比值
这时我们会使用百分比,如 50%、85% 等等。
关键字值
五个关键字值是 top、right、bottom、left 和 center。
CSS:
在 perspective 示例中的先前 CSS 上添加:
/*Enable perspective for child elements by applying it on the parent container*/
/*The origin of the perspective X and Y-axis*/
.parent-container {
perspective: 300px;
perspective-origin: 24% center;
}
/*Child element will move in a 3D plane*/
.parent-container .element { transform: rotateX(170deg); }
backface-visibility
backface-visibility CSS 属性定义了面向观察者的元素的背面是否可见,其外观如下:
backface-visibility: hidden;
描述
backface-visibility 属性支持两个自解释的关键字值:visible 和 hidden。
CSS:
And finalizing the prior example from the perspective-origin example:
/*Enable perspective for child elements by applying it on the parent container*/
/*The origin of the perspective X and Y-axis*/
.parent-container {
perspective: 300px;
perspective-origin: 24% center;
}
/*Child element will move in a 3D plane*/
/*The backside of the element will not be visible*/
.parent-container .element {
transform: rotateX(170deg);
backface-visibility: hidden;
}
摘要
这就是 CSS 属性章节的全部内容,相当刺激吧?
在最后一章中,我们学习了如何处理页面框的属性,如出血和印刷标记。我们还了解到,HTML 列表用于许多其他事物,如菜单、导航、幻灯片放映等,以及其他事物,如 CSS 计数器和如何为列表标记创建自定义样式。
使用 box-shadow 属性创建具有阴影效果的深度感相当简单。只是不要过度使用。然后我们学习了显示和可见性,这是 CSS 中最重要的特性之一。在本节中,我们学习了如何清除浮动元素,以及如何对图像和元素应用过滤器。
元素遮罩和裁剪实际上并不难,我们可以根据具体情况使用位图或矢量图。这使我们更好地理解了如何处理图像及其方向。
然后我们讨论了一些用户界面特性,比如创建自定义光标或根据上下文改变默认光标。
最后,我们学习了 3D 属性,如透视和背面可见性,这些属性使我们能够仅使用 CSS 就完成一些相当酷的事情。
下一章关于 CSS 函数的内容将把我们迄今为止所看到的内容提升到一个新的可能性水平。
让我们飞吧。
第七章:CSS 函数
CSS 函数在 CSS 中用于许多事情。它们可以用来创建特殊类型的进程,例如创建动画或使用自定义字体,或者创建透明度或变换元素在二维和三维平面上的视觉效果。
让我们看看 CSS 函数都是关于什么的。
过滤器
CSS 过滤器允许我们以不同的方式操纵元素的颜色。
brightness()
brightness() CSS 函数与 filter 属性一起使用,其语法如下:
filter: brightness(20%);
描述
brightness() 函数修改图像的照明。值可以声明为不带单位的百分比或数字,例如,10% 和 0.5%。
值为 100% 保持元素不变;值为 0% 使元素完全变黑。允许值超过 100%,这将产生更强烈的效果。值的范围没有限制。
值为 1 保持元素不变;值为 0 使元素完全变黑。允许值超过 1,这将产生更强烈的效果。值的范围没有限制。此外,对于百分比和数字,负值均无效。
CSS:
.element {
filter: brightness(20%);
}
contrast()
contrast() CSS 函数与 filter 属性一起使用,其语法如下:
filter: contrast(10);
描述
contrast() 函数修改元素的对比度。值可以声明为不带单位的百分比或数字,例如,10% 和 0.5%。
值为 100% 保持元素不变;值为 0% 使元素完全变黑。允许值超过 100%,这将产生更强烈的效果。值的范围没有限制。
值为 1 保持元素不变;值为 0 使元素完全变黑。允许值超过 1,这将产生更强烈的效果。值的范围没有限制。此外,负值无效,并且允许使用小数。
CSS:
.element {
filter: contrast(10);
}
grayscale()
grayscale() CSS 函数与 filter 属性一起使用,其语法如下:
filter: grayscale(.8);
描述
grayscale() 函数将元素转换为黑色调。值可以声明为不带单位的百分比或数字,例如,10% 和 0.5%。
值为 0% 保持元素不变;值为 100% 使元素变为灰度。不允许值超过 100%。
值为 0 保持元素不变;值为 1 使元素变为灰度。不允许值超过 1。此外,对于两种情况,负值均无效。允许使用小数。
invert()
invert() CSS 函数与 filter 属性一起使用,其语法如下:
filter: invert(1);
描述
invert() 函数反转元素的色彩。如果用于图像,它会使图像看起来像负片。
值为 100% 完全反转元素的色彩;值为 0% 保持元素不变。不允许值超过 100%。
值为 1 完全反转元素的颜色;值为 0 保持元素不变。不允许超过 1 的值。也不允许负值。两者都允许小数值。
hue-rotate()
hue-rotate() CSS 函数与 filter 属性一起使用,看起来像这样:
filter: hue-rotate(80deg);
描述
hue-rotate() 函数应用于元素,进行色调旋转。它接受一个 角度 值。
角度值定义了元素样本在色轮上修改的度数。
没有最大值。然而,如果值大于 360deg,旋转将只是绕一圈。例如,如果我们声明 380deg,那么它等同于 20deg。
blur()
blur() CSS 函数与 filter 属性一起使用,看起来像这样:
filter: blur(10px);
描述
blur() 函数产生 模糊 效果。值声明为 长度 值(px、em、in、mm、cm、vw 等)。值越高,模糊效果越强烈,反之亦然。
不允许百分比和负值,但允许小数值。
saturate()
saturate() CSS 函数与 filter 属性一起使用,看起来像这样:
filter: saturate(300%);
描述
它会影响元素的饱和度水平。值可以声明为 百分比 或不带单位的 数字,例如 10% 和 0.5%。
元素的默认饱和度值为 100%,或使用无单位数字时为 1。
值为 0% 完全去饱和元素(移除所有颜色,使元素变为灰度);值为 100% 保持元素不变。允许超过 100% 的值,以创建更强烈的效果。
值为 0 完全去饱和元素(移除所有颜色,使元素变为灰度);值为 1 保持元素不变。允许超过 1 的值,以创建更强烈的效果。
sepia()
sepia() CSS 函数与 filter 属性一起使用,看起来像这样:
filter: sepia(100%);
描述
sepia() 函数将元素转换为棕褐色。想象一下灰度图像,但以棕色色调呈现。
值为 100% 完全将元素转换为棕褐色;值为 0% 保持元素不变。不允许超过 100% 的值。
值为 1 完全将元素转换为棕褐色;值为 0 保持元素不变。不允许超过 1 的值。
此外,对于两者,负值都是无效的。
变换
CSS 变换已经变得如此流行,以至于现在在网站上几乎看不到没有某种变换的情况,例如按钮形状、动画和布局。
让我们看看变换 CSS 函数。
matrix()
matrix() CSS 函数与 transform 属性一起使用,看起来像这样:
matrix(0.5, 0, 0.0881635, 0.5, 0, 0);
描述
matrix() 函数是所有变换属性的缩写,因为它们可以在这里组合。此函数用于定义二维变换矩阵。
这个函数需要扎实的数学理解,但在现实中,这个函数并不是手动完成的。相反,我们可以使用像 Eric Meyer 和 Aaron Gustafson 的《矩阵解析》这样的工具(tiny.cc/eric-meyer-matrix)。
matrix() 函数的高级数学解释超出了本书的范围。然而,对于非常详细的解释,你可以参考以下两篇文章中的任何一篇:
-
《理解 CSS 转换矩阵》由 Tiffany Brown 撰写(
tiny.cc/css-matrix-1) -
《CSS3 矩阵变换对数学挑战者的解释》由 Zoltan Hawryluk 撰写(
tiny.cc/css-matrix-2)
CSS:
/*This*/
.element { transform: skew(10deg) scale(.5); }
/*Is the same as this*/
.element { transform: matrix(0.5, 0, 0.0881635, 0.5, 0, 0); }
matrix3d()
matrix3d() CSS 函数与transform属性一起使用,其形式如下:
matrix3d(0.852825, 0.195593, -0.484183, 0, 0.0958426, 0.852825, 0.513326, 0, 0.513326, -0.484183, 0.708564, 0, 0.948667, 1.04842, 0.0291436, 1);
描述
就像二维的 matrix() 函数一样,matrix3d() 函数是一个简写,但这个简写适用于 4 x 4 网格中所有 3D 转换属性。
这个函数需要扎实的数学理解,但在现实中,这个函数并不是手动完成的。相反,我们可以使用像 Eric Meyer 和 Aaron Gustafson 的《矩阵解析》这样的工具(tiny.cc/eric-meyer-matrix)。
CSS:
/*This*/
.element { transform: rotate3d(10, 10, 1, 45deg) translate3d(1px, 1px, 0); }
/*Is the same as this*/
.element { transform: matrix3d(0.852825, 0.195593, -0.484183, 0, 0.0958426, 0.852825, 0.513326, 0, 0.513326, -0.484183, 0.708564, 0, 0.948667, 1.04842, 0.0291436, 1); }
rotate()
rotate() CSS 函数与transform属性一起使用,其形式如下:
rotate(10deg);
描述
rotate() 函数在二维空间中围绕一个固定点旋转元素。它接受一个使用deg、grad、rad或turn单位的 角度 值。deg单位最常用。负值是有效的。
CSS:
.element {
transform: rotate(10deg);
}
rotate3d()
rotate3d() CSS 函数与transform属性一起使用,其形式如下:
rotate3d(1, 2, 1, 10deg);
描述
rotate3d() 函数通过 X、Y 和 Z 轴在三维平面上围绕一个固定位置旋转元素。它接受四个值:对应于 X、Y 和 Z 轴的三个无单位的 数字 值,以及一个定义旋转量的 角度 值。
正值在相应轴上按顺时针方向旋转元素。负值按逆时针方向旋转元素。
CSS:
.element {
transform: rotate3d(1, 2, .5, 10deg);
}
rotateX()
rotateX() CSS 函数与transform属性一起使用,其形式如下:
transform: rotateX(25deg);
之前的代码与以下代码类似:
transform: rotate3d(1, 0, 0, 25deg);
描述
rotateX() 函数在三维平面上沿 X 轴旋转元素。它接受一个 角度 值。
正值按顺时针方向旋转元素。负值按逆时针方向旋转元素。
CSS:
/*This*/
.element { transform: rotateX(25deg); }
/*Is the same as this*/
.element { transform: rotate3d(1, 0, 0, 25deg); }
rotateY()
rotateY() CSS 函数与transform属性一起使用,其形式如下:
transform: rotateY(75deg);
上面的行与这一行相同:
transform: rotate3d(0, 1, 0, 75deg);
描述
rotateY() 函数在三维平面上沿 Y 轴旋转元素。它接受一个 角度 值。
正值按顺时针方向旋转元素。负值按逆时针方向旋转元素。
CSS:
/*This*/
.element { transform: rotateY(75deg); }
/*Is the same as this*/
.element { transform: rotate3d(0, 1, 0, 75deg); }
rotateZ()
rotateY() CSS 函数与 transform 属性一起使用,其形式如下:
transform: rotateZ(33deg);
这与以下内容相同:
transform: rotate3d(0, 0, 1, 33deg);
描述
rotateY() 函数用于在三维平面上沿 Z 轴旋转元素。它接受一个 角度 值。
正值会使元素顺时针旋转。负值会使元素逆时针旋转。
CSS:
/*This*/
.element { transform: rotateZ(33deg); }
/*Is the same as this*/
.element { transform: rotate3d(0, 0, 1, 33deg); }
scale()
scale() CSS 函数与 transform 属性一起使用,其形式如下:
.element { transform: scale(2); }
或者:
.element { transform: scale(2, 3); }
描述
scale() 函数用于在二维平面上改变元素的大小,使其变大或变小。它支持一个或两个无单位的数值,其中第二个值是可选的。数值表示元素应该缩放多少次。例如,值为 2 表示元素被缩放(放大)到 200%;值为 0.5 表示元素应该缩放(缩小)到 50%。
第一个值代表水平缩放,第二个值代表垂直缩放。如果只声明一个值,则表示两个方向将使用相同的值。
允许使用负值。然而,当使用负值时,元素会被翻转。
提示
当元素被缩放时,它不会影响布局;它将根据源顺序简单地重叠或出现在其他元素下方。
CSS:
/*Element is flipped in both directions and scaled to 200% its size*/
.element { transform: scale(-2); }
/*Element is scaled to 200% horizontally and 300% vertically*/
.element { transform: scale(2, 3); }
scale3d()
scaled3d() CSS 函数与 transform 属性一起使用,其形式如下:
transform: scale3d(2, 2, 2);
描述
scaled3d() 函数通过 X、Y 和 Z 轴改变元素在三维平面上的大小,使其变大或变小。
它支持三个无单位的数值,这些数值是必需的。允许使用负值。然而,当使用负值时,元素会被翻转。
CSS:
/*The element is twice the size*/
.element { transform: scale3d(2, 2, 2); }
/*Flipped element in both X and Y-axis while scaled to 300%, and 200% on the Z-axis*/
.element { transform: scale3d(-3, -3, 2); }
scaleX()
scaleX() CSS 函数与 transform 属性一起使用,其形式如下:
transform: scaleX(-2);
描述
scaleX() 函数用于在二维平面上沿 X 轴改变元素的大小。它支持一个无单位的数值。
允许使用负值。然而,当使用负值时,元素会被翻转。
CSS:
.element {
transform: scaleX(-2);
}
scaleY()
scaleY() CSS 函数与 transform 属性一起使用,其形式如下:
transform: scaleY(4);
描述
scaleY() 函数用于在二维平面上沿 Y 轴改变元素的大小。它支持一个无单位的数值。
允许使用负值。然而,当使用负值时,元素会被翻转。
CSS:
.element {
transform: scaleY(4);
}
scaleZ()
scaleZ() CSS 函数与 transform 属性一起使用,其形式如下:
transform: scaleZ(3);
描述
scaleZ() 函数用于在二维平面上沿 Y 轴改变元素的大小。它支持一个无单位的数值。
允许使用负值。然而,当使用负值时,元素会被翻转。
CSS:
.element {
transform: scaleY(4);
}
skew()
skew() CSS 函数与 transform 属性一起使用,其形式如下:
transform: skew(20deg);
或者您也可以使用以下代码:
transform: skew(20deg, 25deg);
描述
skew() 函数在二维平面上对元素进行倾斜或倾斜 X 轴或 X 和 Y 轴。例如,平行四边形是一个倾斜的矩形。
它支持一个或两个角度值:第一个对应于 X 轴,第二个对应于 Y 轴。如果只声明了一个值,则元素仅在 X 轴上倾斜。允许使用负值。
建议您使用 skewX() 或 skewY() 函数而不是 skew(),因为 skew() 已经从规范中移除(尽管大多数浏览器仍然支持它)。
CSS:
/*One value only affects the element on the X-axis*/
.element { transform: skew(20deg); }
/*Two values affects the element on both X and Y-axis*/
.element { transform: skew(20deg, 25deg); }
skewX()
@skewX() CSS 函数与 transform 属性一起使用,看起来像这样:
transform: skewX(40deg);
描述
@skewX() 函数在二维平面上对元素进行倾斜或倾斜 X 轴。
它支持一个角度值。允许使用负值。
CSS:
.element {
transform: skewX(40deg);
}
skewY()
@skewY() CSS 函数与 transform 属性一起使用,看起来像这样:
transform: skewY(36deg);
描述
@skewY() 函数在二维平面上对元素进行倾斜或倾斜 Y 轴。
它支持一个角度值。允许使用负值。
CSS:
.element {
transform: skewY(36deg);
}
steps()
steps() 时间函数与 transition-timing-function 或 animation-timing-function 属性一起使用,看起来像这样:
transition-timing-function: steps(3);
animation-timing-function: steps(3);
描述
steps() 时间函数将过渡或动画分成相等大小的间隔。我们还可以指定过渡或动画的步骤是在间隔的 start 还是 end 处发生。如果没有声明参数,则默认为 end 值。
它支持一个数值值,或者一个数值值和一个可选的 start 或 end 值。
通过一个例子来理解 start 或 end 的工作方式是最好的:使用 start 时,动画将立即开始,使用 end 时,将稍微延迟。
CSS:
/*The transition is divided in 3 equal size intervals*/
.element { transition-timing-function: steps(3); }
/*The transition is divided in 3 equal size intervals but it will delay a bit before it starts*/
.element { transition-timing-function: steps(3, end); }
translate()
translate() CSS 函数与 transform 属性一起使用,看起来像这样:
transform: translate(20px);
或者像这样:
transform: translate(20px, -50%);
描述
translate() 函数影响元素在二维平面上的位置,在 X 轴或 X 和 Y 轴上。
它支持长度和百分比值。允许使用负值。它支持一个或两个长度和百分比值;第一个对应于 X 轴,第二个对应于 Y 轴。如果只声明了一个值,则元素仅在 X 轴上移动。允许使用负值。
CSS:
/*One value, the element is moved on the X-axis only*/
.element { transform: translate(20px); }
/*Two values, the element is moved on the X and Y-axis*/
.element { transform: translate(20px, -50%); }
translate3d()
translate3d() CSS 函数与 transform 属性和 perspective 函数一起使用,看起来像这样:
transform: perspective(100px) translate3d(75px, 75px, -200px);
描述
translate3d() 函数用于在三维平面上沿 X、Y 和 Z 轴移动元素。
它支持长度和百分比值。允许使用负值。
为了能够看到这个函数的工作效果,我们需要给相关元素使用perspective函数创建一个三维平面,否则translate3d()声明将没有任何效果。
CSS:
.element {
transform: perspective(100px) translate3d(75px, 75px, -200px);
}
translateX()
translateX() CSS 函数与transform属性一起使用,其语法如下:
transform: translateX(99%);
描述
translateX()函数用于在二维平面上沿X轴移动元素。
它支持长度和百分比值。允许使用负值。
CSS:
.element {
transform: translateX(99%);
}
translateY()
translateY() CSS 函数与transform属性一起使用,其语法如下:
transform: translateY(55px);
描述
这用于在二维平面上沿Y轴移动元素。它支持长度和百分比值。允许使用负值。
CSS:
.element {
transform: translateY(55px);
}
translateZ()
translateZ() CSS 函数与transform属性和perspective函数一起使用,其语法如下:
transform: perspective(100px) translateZ(77px);
描述
这用于在三维平面上沿Z轴移动元素。它支持长度和百分比值。允许使用负值。
为了能够看到这个函数的工作效果,我们需要给相关元素使用perspective函数创建一个三维平面;否则,translateZ()声明将没有任何效果。
CSS:
.element {
transform: perspective(100px) translateZ(77px);
}
颜色
颜色可以成就或毁掉一个设计,有很多方法可以创建调色板和所有那些好东西。
让我们看看HSL(a)和RGB(a)。
hsl()和 hsla()
hsl()和hsla() CSS 函数表示法以 HSL/HSLa 格式设置颜色,其语法如下:
background-color: hsl(10, 20%, 30%);
background-color: hsla(10, 20%, 30%, .5);
描述
HSL代表色调、饱和度和亮度(或亮度)。a代表Alpha,它是 alpha 通道,我们用它来声明颜色的透明度。
hsl()函数支持用逗号分隔的三个或四个值。第一个值是色调,它是基础颜色。这个值以无单位的数字表示。这个数字代表在色轮上的角度(10 = 10º),范围从 0 到 360。因此,0 和 360 是红色,90 是黄绿色,180 是青色,270 是蓝紫色。
第二个值是饱和度,这基本上是基础颜色的量。这个值以百分比表示。0%表示完全没有基础颜色,显示灰色。100%表示基础颜色是完整的。
第三个值是亮度,也称为亮度。这基本上是基础颜色的亮度。0%表示没有亮度,因此是黑色。100%表示完全亮度,因此看起来是白色。50%表示基础颜色是完整的。
第四个值是 alpha 通道。这是颜色的透明度。它以无单位的数字小数形式从0到1声明。完全透明是0,1是完全不透明。
HSL 颜色命名系统相对于 RGB 的一个巨大优势是它更直观。一旦我们选择了一个基础颜色,我们就可以通过只改变饱和度和亮度值来轻松地创建基于该颜色的调色板。
你可以在 CodePen 中看到 HSL 颜色轮:tiny.cc/hsl-color-wheel
CSS:
/*HSL*/
.element { background-color: hsl(240, 100%, 50%); }
/*HSLa*/
.element { background-color: hsla(10, 20%, 30%, .5); }
rgb()和rgba()
rgb()和rgba() CSS 功能符号设置 RGB/RGBa 格式的颜色,它们看起来是这样的:
background-color: rgb(240, 100, 50);
background-color: rgba(10, 20, 30, .5);
描述
RGB代表红色、绿色和蓝色。a代表Alpha,这是我们声明颜色透明度的 alpha 通道。
这支持三个或四个由逗号分隔的无单位数值,或者三个百分比值和一个无单位数值。最后一个值用于 alpha 通道。
数值的范围是 0 到 255。百分比值的范围是 0%到 100%。例如,我们可以将绿色表示为rgb(0, 255, 0)或rgb(0, 100%, 0)。
正如我刚才提到的,第四个值是 alpha 通道。这是颜色的透明度。它用一个无单位的数值十进制值从0到1声明。完全透明是0,1是完全不透明。
CSS:
/*RGB*/
.element { background-color: rgb(240, 100, 50); }
/*RGBa*/
.element { background-color: rgba(10, 20, 30, .5); }
渐变
对于那些不知道的人来说,CSS 渐变实际上是图像。但这些图像是在浏览器看到声明渐变颜色时由浏览器创建的。这些图像的特点是它们是即时创建的,不会引起任何 HTTP 请求。
CSS 渐变功能非常强大,我们不仅可以创建任何方向和各种形状的渐变,还可以创建令人惊叹的图案。
话虽如此,Lea Verou 有一个用渐变创建的 CSS 图案库,每个阅读这本书的人都应该将其收藏。在这里查看:tiny.cc/leave-verou-css3-patterns
让我们看看如何在 CSS 中创建渐变。
linear-gradient()
linear-gradient() CSS 函数创建一个从一种颜色过渡到另一种颜色的线形渐变。它的最简单形式如下所示:
background-image: linear-gradient(red, blue);
描述
我们可以创建遵循任何方向的线性渐变,称为渐变线:从左到右,从右到左,从上到下,从下到上,对角线,以及在任何 360º半径内的任何角度。
如果没有指定渐变线的方向,则默认值是从上到下。
渐变线中可以声明任意数量的颜色。从技术上来说,没有限制,但从设计角度来看,我们应始终尝试保持简单。至少需要两个颜色值。
linear-gradient()函数支持所有颜色模式:HEX,RGB,RGBa,HSL,HSLa,和颜色名称。
方向
我们还可以通过一个角度值或四个关键字值来声明渐变线的方向:to top,to bottom,to left,和to right。
-
to top:渐变将从底部开始,到顶部结束 -
to bottom: 渐变将从顶部开始,并在底部结束 -
to left: 渐变将从右侧开始,并在左侧结束 -
to right: 渐变将从左侧开始,并在右侧结束
角度 值在声明的开始处定义,范围从 0 到 360。较大的值会绕圆周循环。
颜色停止
我们还可以定义颜色在渐变中的停止位置。颜色停止是颜色值和 停止位置 的组合,其中停止位置是可选的。
停止位置可以用任何 长度 值或 百分比 值声明,并跟在颜色值之后。
小贴士
百分比值更常用,因为它们可以与元素一起缩放。像素值也可以,但它们没有相对单位那样灵活。
颜色停止非常灵活,因为它们允许我们在颜色之间创建平滑的过渡。这对于制作需要平滑颜色过渡的图案或其他类型的图形非常有用,例如国旗。
当没有声明 停止位置 时,浏览器会在渐变线上均匀地分布渐变颜色。
CSS:
/*Basic gradient. Colors are distributed evenly along the gradient line*/
.element { background-image: linear-gradient(red, blue); }
/*Gradient goes from right to left and starts with color red*/
.element { background-image: linear-gradient(to left, red, blue); }
/*Gradient line is diagonal; inclined 170 degrees*/
.element { background-image: linear-gradient(170deg, red, blue); }
/*Gradient with stop positions in percentages*/
.element { background-image: linear-gradient(red 50%, blue 75%); }
/*Gradient with stop positions in pixels*/
.element { background-image: linear-gradient(red 100px, blue 150px); }
/*Colombian flag (yellow, blue and red bands) made with solid color transitions using stop positions*/
.element { background-image: linear-gradient(#fcd116 50%, #003893 50%, #003893 75%, #ce1126 75%); }
radial-gradient()
CSS 函数 radial-gradient() 创建的渐变从一种颜色过渡到另一种颜色,但以圆形或椭圆形的形式,其最简单的形式如下:
background-image: radial-gradient(orange, green);
描述
径向渐变有三个部分:其 中心、其 结束形状 和 颜色停止。
中心 定义了从元素中开始径向渐变的点;径向渐变不必从元素的中心开始。结束形状 定义了径向渐变是圆形还是椭圆形。如果没有声明 circle 关键字,则默认形状是椭圆形。颜色停止 是构成渐变的颜色,如果声明了,任何可选的 停止位置。记住,停止位置可以用任何 长度 值或 百分比 值声明,并跟在颜色值之后。
至少需要两种颜色来创建径向渐变,或者任何类型的渐变。
位置
我们可以定义径向渐变的中心在元素内的位置。正如我之前提到的,默认位置是在元素的中心。
要声明一个特定位置,我们使用关键字 at 并定义 X 和 Y 轴坐标。这个值应该在声明任何颜色值之前,但在 结束形状 之后。
X 和 Y 轴坐标可以用任何 长度 值、百分比 值或任何关键字值(top、right、bottom 和 left)声明。这基本上与我们声明元素上的 background-position 的方式相同。
位置需要声明一个 结束形状,可以是 circle 或 ellipse;否则,声明无效。
尺寸
我们还可以改变径向渐变的大小。渐变的大小在位置之前声明,但它可以在结束形状之前或之后。它可以接受一个或两个值,用于宽度和高度。如果声明了一个值,它将用于两者。
大小可以用长度值、百分比值或四个关键字值之一来定义:closest-corner、farthest-corner、closest-side和farthest-side。
-
closest-corner:渐变的大小取决于离中心最近的角。 -
farthest-corner:渐变的大小取决于离中心最远的角。 -
closest-side:渐变的大小取决于离中心最近的边。 -
farthest-side:渐变的大小取决于离中心最远的边。
CSS:
/*Basic gradient. Colors are distributed evenly in the ellipse*/
.element { background-image: radial-gradient(red, blue); }
/*Ending shape declared as circle*/
.element { background-image: radial-gradient(circle, red, blue); }
/*Position declared (only one value). Gradient will start at the left and center*/
.element { background-image: radial-gradient(circle at left, red, blue); }
/*Position declared (two values)*/
.element { background-image: radial-gradient(circle at left top, red, blue); }
/*Position declared with percentages. An ending shape value is required*/
.element { background-image: radial-gradient(circle at 25% 75%, red, blue); }
/*Size of the gradient declared in pixels*/
.element { background-image: radial-gradient(100px 50px ellipse at 25% 75%, red, blue); }
/*Size of the gradient relative to the farthest side of the element. Ending shape can be after or before size*/
.element { background-image: radial-gradient(circle farthest-side at 25% 75%, red, blue); }
repeating-linear-gradient()
repeating-linear-gradient() CSS 函数用于重复渐变图像,其外观如下:
background-image: repeating-linear-gradient(orange 50px, green 75px);
Description
repeating-linear-gradient()函数使用与linear-gradient() CSS 函数相同的语法和值,因此请参阅该函数以获取所有可用值的详细说明。
为了使repeating-linear-gradient()函数正常工作,我们需要在颜色上定义停止位置。否则,重复的渐变看起来就像我们只是使用了linear-gradient()。
CSS:
/*Basic repeating linear gradient*/
.element { background-image: repeating-linear-gradient(orange 50px, green 75px); }
/*Repeating gradient goes from right to left and starts with color orange*/
.element { background-image: repeating-linear-gradient(to left, orange 50px, green 75px); }
/*Repeating gradient line is diagonal; inclined 170 degrees*/
.element { background-image: repeating-linear-gradient(170deg, orange 50px, green 75px); }
/*Repeating gradient with stop positions in percentages*/
.element { background-image: repeating-linear-gradient(orange 25%, green 50%); }
repeating-radial-gradient()
repeating-radial-gradient() CSS 函数用于重复渐变图像,其外观如下:
background-image: repeating-radial-gradient(navy 50px, gray 75px);
Description
repeating-linear-gradient()函数使用与radial-gradient() CSS 函数相同的语法和值,因此请参阅该函数以获取所有可用值的详细说明。
为了使repeating-radial-gradient()函数正常工作,我们需要在颜色上定义停止位置。否则,重复的渐变看起来就像我们只是使用了radial-gradient()。
CSS:
/*Basic repeating linear gradient*/
.element { background-image: repeating-radial-gradient(navy 50px, gray 75px); }
/*Ending shape declared as circle*/
.element { background-image: repeating-radial-gradient(circle, navy 50px, gray 75px); }
/*Position declared (only one value). Gradient will start at the left and center*/
.element { background-image: repeating-radial-gradient(circle at left, navy 50px, gray 75px); }
/*Position declared (two values)*/
.element { background-image: repeating-radial-gradient(circle at left top, navy 50px, gray 75px); }
/*Position declared with percentages. Defaults to ellipse shape unless 'circle' is specified*/
.element { background-image: repeating-radial-gradient(at 25% 75%, navy 50px, gray 75px); }
/*Size of the gradient declared in pixels*/
.element { background-image: repeating-radial-gradient(200px 25px at 25% 75%, navy 50px, gray 75px); }
/*Size of the gradient relative to the farthest side of the element. Ending shape can be after or before size*/
.element { background-image: repeating-radial-gradient(circle farthest-side at 25% 75%, navy 50px, gray 75px); }
Values
以下 CSS 函数允许我们为各种结果声明许多自定义值。让我们来看看它们。
attr()
attr() CSS 函数允许我们针对任何 HTML 属性的值并在 CSS 中使用它,其外观如下:
attr(href);
Description
术语attr是单词attribute的缩写。这个 CSS 函数针对一个HTML 属性,并使用其值通过 CSS 完成不同的事情。
在 CSS 中,attr()函数最常与content属性以及:after CSS 伪元素一起使用,以将内容注入文档中,但事实上,attr()函数可以与任何其他 CSS 属性一起使用。
在 HTML 中,使用attr() CSS 函数针对 HTML5 的data-或href属性是非常常见的。attr()函数可以用来针对任何HTML 属性。
在 CSS3 中,attr() CSS 函数的语法略有不同。它不仅接受属性值,还接受两个额外的参数,即类型或单位参数和属性回退参数。类型或单位参数是可选的。它告诉浏览器哪种类型的属性正在使用,以便解释其值。属性回退参数定义了在解析元素的主要属性时出现错误的情况下的回退值。
小贴士
新的 CSS3 语法包括类型或单位和属性回退参数,尚不稳定,并且可能从规范中删除。在决定使用新语法之前,请做好研究。
打印网页文档的一个良好实践是将 URL 打印在链接元素旁边。另一个常见做法是结合使用attr() CSS 函数、content属性和 HTML5 的data-属性在响应式表格中注入单元格(通常是标题)的内容,从而节省空间。
CSS:
/*Print the links from the content*/
@media print {
main a[href]:after {
content: attr(href);
}
}
响应式表格
当视口宽度为 640 像素或更小时,表格将变为响应式。这是通过结合使用attr() CSS 函数、content属性和 HTML5 的data-属性来实现的。
HTML:
<table>
<tr class="headings">
<th>Plan</th>
<th>Price</th>
<th>Duration</th>
</tr>
<tr>
<td data-label="Plan:">Silver</td>
<td data-label="Price:">$50</td>
<td data-label="Duration:">3 months</td>
</tr>
</table>
CSS:
/*40em = 640÷16*/
@media (max-width:40em) {
/*Behave like a "row"*/
td, tr {
display: block;
}
/*Hide the headings but not with display: none; for accessibility*/
.headings {
position: absolute;
top: -100%;
left: -100%;
overflow: hidden;
}
/*Inject the content from the data-label attribute*/
td:before {
content: attr(data-label);
display: inline-block;
width: 70px;
padding-right: 5px;
white-space: nowrap;
text-align: right;
font-weight: bold;
}
}
calc()
calc() CSS 函数允许我们执行数学计算,其格式如下:
width: calc(100% / 2 + 25px);
或者像这样:
padding: calc(5 * 2px - .25em);
描述
我们可以使用加法(+)、减法(-)、除法(/)和乘法(*)来进行这些计算。它通常用于计算width和height的相对值,但如您所见,我们可以使用此函数与任何 CSS 属性一起使用。
需要考虑的一些事情是,在加法(+)和减法(-)运算符前后都需要有空格,否则,例如,减法可以被认为是具有负值,例如calc(2.5em -5px)。这个calc()函数是无效的,因为第二个值被认为是负值。减法运算符后面需要有空格。然而,除法(/)和乘法(*)运算符不需要空格。
现在,在进行除法(/)时,右侧的值必须是数字值。对于乘法(*)操作,至少有一个值必须是数字值。
CSS:
/* The element's width is half its intrinsic width plus 25px*/
.element { width: calc(100% / 2 + 25px); }
/*The element's padding is 10px minus .25em of the result*/
.element { padding: calc(5 * 2px - .25em); }
url()
url() CSS 函数用于指向外部资源,其格式如下:
background-image: url(..images/sprite.png);
描述
url()函数使用 URL 值来指向或链接到资源。URL代表统一资源定位符。
此函数通常与background或background-image属性一起使用,但可以与任何接受 URL 作为值的属性一起使用,如@font-face、list-style、cursor等。
URL 可以用单引号(' ')或双引号(" ")引用,或者根本不引用。然而,不能有引号样式的组合,例如以单引号开头并以双引号结尾。
此外,在单引号使用的 URL 中的双引号和双引号使用的 URL 中的单引号 必须 用反斜杠(\)转义。否则,它将破坏 URL。
指向资源的 URL 可以是绝对路径或相对路径。如果是相对路径,它相对于样式表在文件夹结构中的位置,而不是网页本身的位置。
url() CSS 函数还支持 Data URI,这基本上是图像的代码。因此,我们不必将选择器指向 /images 文件夹中的图像下载,而是可以将实际图像嵌入到 CSS 中。
注意这一点,因为尽管我们减少了 HTTP 请求(这是一个 巨大的 成功),但如果图像发生变化,我们可能会使 CSS 文件变得更大,并且更难维护。也可能存在潜在的性能和渲染阻塞问题。
关于 Data URI 的更多信息,您可以阅读尼古拉斯·扎卡斯的这篇文章:Data URIs Explained (www.nczonline.net/blog/2009/10/27/data-uris-explained/).
CSS:
/*Colombian flag icon as Data URI. No quotes in URL*/
.element { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAYAAAB24g05AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAAkSURBVCiRY3y7leE/AwWAiRLNw8QARgbO40M8EBnvMgz1dAAAkeoGYBluZXgAAAAASUVORK5CYII=) #ccc no-repeat center; }
/*Custom cursor. Single quotes in URL*/
.element { cursor: url('../images/cursor.cur') 10 10, default; }
/*Web font. Double quotes in URL*/
@font-face {
font-family: Franchise;
src: url("../fonts/franchise.woff") format("woff");
}
cubic-bezier()
cubic-bezier() 函数允许我们创建自定义的加速度曲线,其外观如下:
animation-timing-function: cubic-bezier(.42, 0, 1, 1);
描述
cubic-bezier() 函数与 animation-timing-function 和 transition-timing-function CSS 属性一起使用。大多数用例都可以从我们在第四章中提到的已定义缓动函数中受益,CSS 属性 - 第一部分(ease、ease-in、ease-out、ease-in-out 和 linear);如果你喜欢冒险,cubic-bezier() 是你的最佳选择。
请参考第四章中关于 animation-timing-function CSS 属性的说明,以了解 贝塞尔 曲线的外观。cubic-bezier() 函数以以下形式接受四个参数:
animation-timing-function: cubic-bezier(a, b, a, b);
让我们用 cubic-bezier() 函数表示所有五个预定义的缓动函数:
-
ease:animation-timing-function: cubic-bezier(.25, .1, .25, 1); -
ease-in:animation-timing-function: cubic-bezier(.42, 0, 1, 1); -
ease-out:animation-timing-function: cubic-bezier(0, 0, .58, 1); -
ease-in-out:animation-timing-function: cubic-bezier(.42, 0, .58, 1); -
linear:animation-timing-function: cubic-bezier(0, 0, 1, 1);
我不确定你是否也是这样,但我更喜欢使用预定义的值。
现在,我们可以开始调整和测试每个值到小数点后,保存,并等待实时刷新完成其工作。但如果你问我,太多的测试时间是被浪费的。
惊人的 Lea Verou 创建了最好的用于处理贝塞尔曲线的 Web 应用程序:www.cubic-bezier.com。这是处理贝塞尔曲线最简单的方法。我强烈推荐这个工具。
之前展示的贝塞尔曲线图像是从www.cubic-bezier.com网站获取的。
CSS:
.element {
width: 300px;
height: 300px;
animation: fadingColors 2s infinite alternate 3s none running cubic-bezier(.42, 0, 1, 1);
}
杂项
以下 CSS 函数没有特定的类别,因此我们将它们分组在这里的杂项部分。
让我们看看我们有什么。
drop-shadow()
drop-shadow() CSS 函数与filter属性一起使用,在元素下方添加阴影,其外观如下:
drop-shadow(5px 5px 3px rgba(0, 0, 0, .5));
描述
drop-shadow()函数几乎与box-shadow属性完全相同,但有两大区别:drop-shadow()函数不支持spread-radius或inset值。
请参考box-shadow属性以获取所有值的详细描述。此外,一些浏览器在启用此功能时实际上会提供硬件加速,这最终会提高性能。你知道的;任何能提高性能的方法都是加分项。
CSS:
.element {
filter: drop-shadow(5px 5px 3px rgba(0, 0, 0, .5));
}
element()
element() CSS 函数允许我们使用任何 HTML 元素作为另一个 HTML 元素的背景,其外观如下:
background: element(#other-element);
描述
element()函数的使用案例很少,但无论如何,它对我们是可用的(当然,浏览器的支持还不是很好)。
CSS:
.element {
background: element(#other-element);
}
image()
image() CSS 函数允许我们指定一个图像文件作为背景使用,其外观如下:
image(../images/sprite.png);
描述
image()函数实际上与url()函数相同,但它被认为更加灵活,是声明背景图像而不是使用众所周知的url()函数的理想选择。然而,由于浏览器支持不足,image() CSS 函数有被从规范中删除的风险。
CSS:
.element {
background-image: image(../images/sprite.png);
}
opacity()
opacity() CSS 函数与filter属性一起工作。它定义了元素的不透明度(透明度),其外观如下:
filter: opacity(.2);
描述
当此功能应用于一个元素时,该元素及其子元素都会受到影响。此功能支持从0(零)到1的数值范围,这是默认值。0的值是完全透明的,就像0%不透明,而1是100%不透明,完全没有透明度。允许使用小数,但不允许使用负值。
CSS:
.element {
filter: opacity(.2);
}
perspective()
perspective() CSS 函数与transform CSS 属性一起使用,其外观如下:
perspective(300px);
描述
此值给元素提供了三维透视效果。相关的元素将在三维平面上反应。
此函数的工作方式与 perspective 属性类似,区别在于 perspective() 函数用于给单个元素添加透视效果。因此,它应用于元素本身。perspective 属性适用于一次性给多个元素添加透视效果,因此它应用于父元素。
例如,如果我们将 perspective() 函数应用于列表上的每个元素,每个元素都会有自己的消失点。但如果我们将 perspective 属性应用于该列表的父容器,所有元素将共享相同的消失点。
perspective() 函数本身并没有什么作用,因此为了看到它的实际效果,我们必须将其与其他转换函数(如 rotate()、rotateX() 或 rotateY())结合使用。
它接受一个带有长度单位的数值。不允许使用负值。该值定义了从用户到 Z 轴的距离。
值越高,透视效果越不强烈。这是因为元素离我们越远。然而,值越低,透视效果看起来越明显。这是因为元素离我们越近。
CSS:
.element {
transform: perspective(300px) rotateY(45deg);
}
rect()
rect() CSS 函数用于使用 clip 属性创建矩形形状的裁剪遮罩,其格式如下:
clip: rect(0, 100px, 200px, 0);
小贴士
由于与 SVG 相关的功能和限制不佳,clip CSS 属性现在已被弃用。当前广泛支持的 clip-path 属性是 SVG 规范的一部分,并且已被 CSS 遮罩模块采用。
描述
此功能仅与 clip 属性一起使用,正如我提到的,此属性现在已被弃用。此外,此 CSS 函数不与更现代的 clip-path CSS 属性一起使用,因此建议使用 inset() CSS 函数代替。
请参考第六章中的 inset() CSS 函数,CSS 属性 – 第三部分。
规则
CSS 规则以 @ 字符开头,后跟一个关键字或标识符。它们必须以分号 (;) 字符结尾。
一些最流行的规则包括 @font-face,用于声明自定义字体;@import 用于导入外部 CSS 文件(不过出于性能考虑并不推荐使用),它也被一些 CSS 预处理器用来引入外部部分文件,这些文件最终会被编译成一个单一的 CSS 文件(推荐方法);@media 用于在响应式项目中声明媒体查询或打印样式表等;@keyframes 用于创建动画等。
规则,让我们看看它们在哪里应用。
@charset
@charset() 规则定义了样式表所使用的字符编码,其格式如下:
@charset "UTF-8";
描述
只要 HTML 中已经定义了字符编码,我们就很少需要在样式表中定义字符编码。当浏览器检测到 HTML 中的字符编码时,它意味着 CSS 文件(们)使用相同的字符编码。
如果你喜欢在 CSS 文件中声明字符编码,那也行。如果你计划在样式表中使用它,它应该是文件顶部第一件事。它不能在@符号之前有空格字符,或者在其上方有空行。字符编码名称应始终在引号内,无论是单引号(')还是双引号(").
CSS:
/*Correct character encoding directive*/
@charset "UTF-8";
/*Character encoding of the CSS is set to Latin-9 (Western European languages, with Euro sign)*/
@charset 'iso-8859-15';
/*This is invalid, there is a space before the @ symbol*/
@charset "UTF-8";
/*This is invalid, character encoding name should be inside single [''] or double quotes [""]*/
@charset UTF-8;
@document()
@document() 规则允许定义仅适用于网站特定页面的样式,其一种形式如下所示:
@document url('http://website.com/page.html') { ... }
描述
有四个 CSS 函数是@document()规则独有的:url()、url-prefix()、domain()和regexp("")。可以在单个声明中定义多个函数。
函数内的值可以不使用引号声明,或者使用单引号(')或双引号(").只有regexp("")函数需要使用双引号(").
-
url(): 这将样式限制在匹配 URL 的文档中 -
url-prefix(): 这将样式限制在以指定 URL 开始的文档中 -
domain(): 这将样式限制在文档的特定域名中 -
regexp(""): 这将样式限制在匹配正则表达式的文档中
CSS:
/*url() function*/
@document url('http://website.com/page.html') { ... }
/*url-prefix() function*/
@document url-prefix("http://website.com/about/") { ... }
/*domain() function*/
@document domain(website.com) { ... }
/*regexp() function*/
@document regexp("https:.*")
/*Multiple functions in a single declaration*/
@document url('http://website.com/page.html') { ... },
url-prefix("http://website.com/about/") { ... },
domain(website.com) { ... },
regexp("https:.*") { ... }
@font-face
@font-face() 规则用于定义在文档中使用的自定义字体,其最简单的形式如下:
@font-face {
font-family: Franchise;
src: url("../fonts/franchise.woff") format("woff");
}
描述
@font-face() 规则实际上比许多人认为的还要存在得更久,因此我们的朋友 IE6 支持这个功能。使用 @font-face() 规则,我们可以针对网站/webapp 上使用的自定义字体文件进行定位,并将设计和品牌推广的可能性扩展到系统字体之外。
自定义字体有一个特性,即每个浏览器的不同版本支持一种格式,但不支持另一种,甚至有自己的专有字体格式。
Paul Irish 的文章《Bulletproof @font-face Syntax》,其中笑脸技术起源于此,是所有网页设计师和开发人员必读的@font-face文章(tiny.cc/paul-irish-font-face)。
我们需要考虑的五种字体格式是:WOFF/WOFF2、EOT、TTF、OTF 和 SVG。
WOFF/WOFF2
WOFF 代表 Web 开放字体格式,由 Mozilla 创建。WOFF 格式是 OTF/TTF 字体格式的包装器,并且比任何其他格式都提供了更好的字体数据压缩,从而使得文件(们)更小。
WOFF2 实际上是增强版的 WOFF。它提供了更多的压缩,平均约 30%,在某些情况下甚至高达 50%。
所有现代浏览器都支持这两种格式。
EOT
EOT代表嵌入式 OpenType,由微软创建。只有旧版本的 IE(IE6 到 IE8)需要使用这种字体格式。其他浏览器不支持此格式,因此如果我们不需要支持旧版浏览器,我们就不需要在@font-face()规则声明中声明对此字体格式的链接。
OTF 和 TTF
OTF和TTF代表OpenType 字体和TrueType 字体。这些字体格式是跨平台兼容的,包括高级布局功能和专家排版控制的信息。OTF 是一种较新的格式,比 TTF 具有更多功能,例如小写字母、连字符、分数等。
SVG
SVG代表可缩放矢量图形。SVG 字体文件实际上并没有字体;它有字体的矢量表示。此类字体文件用于需要支持旧版 iOS 设备的情况。然而,如果未声明此类字体,旧版 iOS 设备将简单地使用系统字体,如果问我,我完全没问题。
@font-face括号内的值被称为字体描述符。在其中,我们可以声明几个值:font-family、src、font-variant、font-stretch、font-style、font-weight和unicode-range。
font-family
这是一个必需的值。它定义了在样式表中使用的字体名称。
src
这是一个必需的值。它定义了字体文件的位置或 URL。可以在同一个src声明块中定义多个 URL,以适应每个浏览器支持的字体类型。然而,如果需要支持旧版 IE,当它发现同一个src声明块中有多个 URL 时,旧版 IE 会崩溃,因此如果需要支持旧版 IE,需要声明独立的src声明块。
除了针对带有 URL 的外部文件,我们还可以使用local()函数针对本地安装的文件进行定位。
font-variant
font-variant CSS 属性将目标文本转换为小写字母。在 CSS3 中,它被视为一个简写,并扩展了新的值,但开发者很少使用。有关更多信息,请参阅第五章,CSS 属性 - 第二部分。
font-stretch
font-stretch CSS 属性允许我们从相关的字体族中选择一个紧凑型、正常型或扩展型面。有关更多信息,请参阅第五章,CSS 属性 - 第二部分。
font-weight
font-weight CSS 属性定义了字体的粗细(重量)。有关更多信息,请参阅第五章,CSS 属性 - 第二部分。
unicode-range
unicode-range CSS 属性描述符定义了应从 @font-face 声明中下载的特定字符或符号的范围。这在处理涉及不同语言的网站时非常有用。通过声明 unicode-range,浏览器只为该页下载该语言的特定字符,从而节省带宽并优化性能。
这个属性很少使用。
Google 字体
我们在谈论 @font-face 时不能不提到 Google Fonts。Google Fonts 是一个免费的网页字体服务,它通过给我们一个指向所选字体(或字体组)的 HTML <link> 标签,使我们能够跳过在 CSS 文件中创建 @font-face 声明块的繁琐工作。
查看 Google Fonts,链接为 tiny.cc/google-fonts。
HTML:
<!-- Google Fonts link snippet -->
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
CSS:
/*Full descriptive @font-face declaration*/
@font-face {
font-family: Roboto;
/*IE9 Compat Modes*/
src: url("../fonts/roboto.eot");
/*Locally installed font file*/
src: local("roboto"),
/*IE6-IE8*/
url("../fonts/roboto.eot?#iefix") format("embedded-opentype"),
/*Modern Browsers*/
url("../fonts/roboto.woff2") format("woff2"),
url("../fonts/roboto.woff") format("woff"),
/*Safari, Android, iOS*/
url("../fonts/roboto.ttf") format("truetype"),
/*Old iOS devices*/
url("../fonts/roboto.svg#roboto") format("svg");
/*Unicode range*/
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
/*Font properties*/
font-weight: normal;
font-style: normal;
}
/*Recommended @font-face syntax*/
@font-face {
font-family: Roboto;
src: url("../fonts/roboto.woff2") format("woff2"),
url("../fonts/roboto.woff") format("woff");
font-weight: normal;
font-style: normal;
}
/*Usage*/
.element {
font-family: Roboto, Arial, Helvetica, san-serif;
}
@import
@import() 规则用于将样式表导入另一个样式表中,其语法如下:
@import "other-style-sheet.css";
描述
之前的例子使用一个 string 值来指向另一个样式表。但样式表也可以通过 url() 函数导入。
@import 规则应该始终位于除 @charset 规则之外的所有其他规则之前,否则浏览器将忽略它。
需要考虑的一点是层叠。导入的样式表按导入的顺序层叠。还可以通过媒体查询指定特定导入样式表针对的媒体。如果声明了多个媒体查询,它们需要用逗号分隔。
提示
众所周知,使用 @import 由于按顺序下载而不是并行下载以及多次 HTTP 请求,会对性能产生负面影响。关于此问题的更多信息,请参阅 Steve Souders 的文章 不要使用 @import,链接为 tiny.cc/steve-souders-avoidimport。
CSS:
/*Import a style sheet in the same directory*/
@import "other-style-sheet.css";
/*Import a style sheet from a relative path*/
@import url(../other-stylesheets/other-style-sheet.css);
/*Import a style sheet with an absolute path*/
@import url(http://website.com/other-stylesheets/other-style-sheet.css);
/*Define a print style sheet with the 'print' media query*/
@import "print.css" print;
/*Declare multiple media queries*/
@import "screen.css" screen, projection;
/*Use more a commonly known media query*/
@import url("portrait.css") screen and (orientation: portrait);
@keyframes
@keyframes() 规则用于列出要动画化的 CSS 属性,其语法如下:
@keyframes animationName {
from {
/*Animation properties START here*/
}
to {
/*Animation properties END here*/
}
}
描述
使用 @keyframes 规则创建的动画只运行一个周期。如果我们想让动画反复播放,实现渐入渐出,或者展示其他行为,我们需要在元素本身中声明这些属性,而不是在 @keyframes 规则之外。
请参考第四章(ch04.html "第四章. CSS 属性 – 第一部分")中的动画部分,以获取有关这些 CSS 属性的详细解释。
动画名称(也称为 标识符)始终位于 @keyframes 关键字之后,两者之间用空格分隔。这个动画名称将在稍后通过 animation-name 或 animation 简写 CSS 属性进行引用。
动画的开始和结束可以使用两个选择器关键字 from 和 to,或者使用两个关键帧选择器 0% 和 100% 来声明。不允许使用负值。
显然,我们可以声明中间路径点,但我们只能使用 关键帧选择器 来做到这一点。在 @keyframes 规则中声明的属性数量没有限制。然而,一些浏览器会动画化规范中说不应该动画化的属性,而其他浏览器则正确地遵循规范。当然,规范对一些定义不够明确,所以请确保运行适当的测试。
现在使用 @keyframes 规则和 transition 属性之间的区别在于,使用 @keyframes 规则,我们可以定义中间路径点发生的事情,而不是让浏览器为我们找出它。
基本上,如果我们有一个简单的动画,我们可以直接使用 transition 属性。如果我们有更复杂和精细的动画,则使用 @keyframes。
CSS:
@keyframes diamond {
from {
top: 0;
left: 0;
}
25% {
top: 200px;
left: -200px;
}
50% {
top: 400px;
left: 0;
}
75% {
top: 200px;
left: 200px;
}
to {
top: 0;
left: 0;
}
}
.element {
position: relative;
animation: diamond 3s infinite ease-in-out;
}
@media
@media() 规则允许我们定义一组应用于特定媒体类型的 CSS 样式,其外观如下:
@media (min-width: 40em) { ... }
您可以使用前面的代码或以下代码:
@media print { ... }
描述
这段 CSS 允许我们为特定的媒体类型声明任何一组样式。
在 @media() 规则之后出现的两种指令类型,例如 print 和 screen,甚至是 (min-width: 40em) 或 (max-width: 40em),它们被称为 媒体查询。
关键字(print 和 screen)被称为 媒体类型。而那些测试特定 用户代理(UA)或显示功能的被称为 媒体特性。
媒体类型
媒体类型区分大小写。我们可以使用 @media() 规则与以下 10 种媒体类型一起使用:
-
all: 这是为了在所有设备上工作 -
braille: 这是为了与盲文触觉反馈设备一起工作 -
embossed: 这是为了在盲文打印机上工作 -
handheld: 这是为了与手持“移动”设备一起工作 -
print: 这是为了打印文档 -
projection: 这是为了与投影仪一起工作 -
screen: 这是为了与所有尺寸的计算机屏幕一起工作 -
speech: 这是为了与语音合成器一起工作 -
tty: 这是为了与电传打字机一起工作 -
tv: 这是为了与电视一起工作
CSS:
/*Viewport width media query*/
@media (min-width: 40em) {
header { background: red; }
}
/*Print media query*/
@media print {
*, *:before, *:after { background-image: none; }
}
@namespace
@namespace() 规则用于在样式表中定义 XML 命名空间,其外观如下:
@namespace url(http://www.w3.org/1999/xhtml);
您可以使用前面的代码或以下代码:
@namespace svg url(http://www.w3.org/2000/svg);
描述
当我们需要在 CSS 文档中使用应用于或针对特定命名空间中元素的选择器时,我们使用 @namespace() 规则。例如,我们可以在我们的 HTML 文档中嵌入 SVG 文件。问题是 SVG 与 HTML 和 XML 共享一些常见元素,例如 <a> 元素。因此,我们不必创建单独的样式表来针对 SVG 元素,我们可以使用 @namespace() 规则声明 SVG 命名空间,以针对同一 HTML 文档中的 <a> 元素,这样我们只需要在一个样式表中工作,而不是两个(或更多)。
现在,@namespace() 规则主要用于需要声明 <html> 元素中的命名空间的旧版 XHTML 文档:
<html xml:lang="en" lang="en">
使用 xmlns 指令后,我们现在可以在 CSS 中声明命名空间。最后,我们可以针对 SVG 块中的 <a> 元素进行定位,而不会影响 HTML <a> 元素。
URLs 仅用于使标记更易于阅读和理解,当有人阅读时。
****XHTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html ** xml:lang="en" lang="en">**
CSS:
**@namespace "http://www.w3.org/1999/xhtml";
@namespace svg "http://www.w3.org/2000/svg";
svg|a {
background: orange;
}**
@page
@page() 规则用于修改页面的某些属性以准备打印,其语法如下:
**@page {
margin: 2cm;
}**
描述
当使用 @page() 规则时,只有页面的少数属性可以更改:margins、widows、orphans 和 页面分页。声明任何其他类型的属性都将被忽略。
我们还可以声明是否只想针对 第一页、所有左页 或 所有右页 使用 :first、:left 和 :right 伪类。@page() 规则最常用于更改边距。**
CSS:
**/*Affects all pages*/
@page {
margin: 2cm;
}
/*Affects all left pages only*/
@page :left {
margin: .8in;
orphans: 3;
}
/*Affects all right pages only*/
@page :right {
margin: 15mm;
}**
@supports
@supports() 规则用于检测浏览器上的 功能,其语法如下:
**@supports (display: flex) { ... }**
描述
功能检测 通常使用类似 Modernizr 的 polyfills 来实现。通过 @supports() 规则,我们可以仅使用 CSS 就达到类似的效果。
为了使此函数正常工作,我们需要指定一个 属性 和一个 值。我们可以与 @supports() 规则一起使用三个关键字操作符:not、and 和 or。
not 操作符
就像我们可以检查浏览器支持的功能一样,我们也可以使用 not 操作符检查浏览器 不支持 的功能。
and 操作符
and 操作符允许我们在同一个声明中检查多个 CSS 属性。
or 操作符
此操作符的一个好例子是当我们需要检查带有供应商前缀的 CSS 属性以支持旧版浏览器时。当使用此操作符时,如果其中一个表达式为 true,则所有其他表达式也将有效。此外,我们还可以在必要时组合操作符。
CSS:
**/*Detect a feature that is supported*/
@supports (transform: translateX(-50%)) {
.element {
transform: translateY(-50%)
}
}
/*Detect a feature that is NOT supported*/
@supports not (transform: translateX(-50%)) {
.element {
margin-left: 120px;
}
}
/*Detect multiple features*/
@supports (transform: translateX(-50%)) and (display: flex) {
.element {
transform: translateY(-50%);
justify-content: space-between;
}
}
/*Detect at least one feature*/
@supports (-webkit-box-pack: justify) or (-webkit-justify-content: space-between) or (-ms-flex-pack: justify) or (justify-content: space-between) {
.element {
justify-content: space-between;
}
}
/*Combining conditions*/
@supports (transform: translateX(-50%)) and ( (-webkit-justify-content: space-between) or (justify-content: space-between) ) {
transform: translateY(-50%);
justify-content: space-between;
}**
****# 全局 CSS 关键字值
以下关键字值对网页设计师和开发者来说是普遍存在的,但你是否曾想过它们的确切含义和作用?
auto
auto CSS 关键字值指示浏览器自动计算 CSS 属性的值,其语法如下:
margin: auto;
auto 这个术语是 自动 的简称。它与说 100% 不同,因为 100% 是一个实际定义的值;auto 是由浏览器计算的。
auto 关键字最常见的应用位置之一是使用 margin CSS 属性水平居中元素。
CSS:
.element {
margin: auto;
}
小贴士
我看到大多数人使用 margin: 0 auto; 来居中元素。这没问题,但值零(0)可以省略。margin: auto; 就足够了,并且会产生相同的结果。
继承
inherit CSS 关键字值使元素从其父容器继承值。
CSS:
/*All <h1>'s are red*/
h1 { color: red; }
/*All text in .element is blue*/
.element { color: blue; }
/*Make all <h1>'s inside .element blue*/
.element h1 { color: inherit; }
默认
initial CSS 关键字值将 CSS 属性设置为规范中定义的默认值。
CSS:
/*All <h1>'s are red*/
h1 { color: red; }
/*Set the color of all <h1>'s inside .element to the default (black)*/
.element h1 { color: initial; }
无
none CSS 关键字值定义了没有特定的样式。
CSS:
.element {
border: none;
}
标准
normal CSS 关键字值定义了一个标准值。
CSS:
.element {
font-weight: normal;
}
未设置
unset CSS 关键字是 inherit 和 initial 关键字的组合,看起来是这样的:
color: unset;
通过组合 inherit 和 initial 关键字,unset CSS 关键字值重置了属性的值。
如果一个元素正在从其父容器继承值,并且声明了 unset 关键字,那么属性的值将重置为父容器的值(因为它正在继承)。但如果一个元素没有父容器,并且声明了 unset 关键字,那么其属性的值将重置为规范中定义的默认值(因为它没有继承)。
CSS:
/*All <h1>'s are set to the default color per the spec*/
h1 { color: unset; }
/*All <h1>'s are set to the default color of the parent*/
.element { color: green; }
.element h1 { color: unset; }
回退
revert CSS 关键字值就像 CSS 中的 撤销,它会将层叠回滚到之前的状态,并将属性重置为用户代理定义的默认值。它看起来是这样的:
display: revert;
这与 initial CSS 关键字不同,因为 revert 会回滚层叠并重置属性值为用户代理的 样式表 值。而 initial 则将值重置为其规范中定义的默认值。
例如,规范说明 display 的默认值是 inline。然而,大多数用户代理将 <div> 的默认值设置为 display: block;,或者将 <table> 的默认值设置为 display: table;。
CSS:
/*Default value per the spec*/
display: inline;
/*Default value per the UA style sheet*/
div { display: block; }
/*Style defined by the developer/designer*/
.element { display: inline-block; }
/*Style sheet is rolled back and DIV behaves as display: block;*/
div.element { display: revert; }
摘要
这就结束了关于 CSS 的章节,很有趣吧?
我们学习了 CSS 过滤器以及我们如何在不依赖图像编辑工具的情况下修改元素的色彩。这也适用于 CSS 变换,因为我们可以使用 CSS 很容易地修改元素的形状和方向,至少在一定程度上。
同时,我们还了解了在 CSS 中创建颜色的不同方法,以及 HSL 模式比其他任何颜色模式都更直观和灵活。
使用 attr() 或 calc() 函数计算和声明不同的值,为我们的 CSS 工具箱打开了新的可能性,例如,如何制作响应式表格。
我们现在知道,为了提高阴影效果的性能,我们可以使用 drop-shadow() 函数;或者要修改元素的透明度,我们可以使用 opacity() 函数;或者使用 perspective() 函数来修改元素的透视。
现在,@规则更有意义了。此外,我们还讨论了不同的字体格式,并了解到如果我们不需要支持旧版 IE,我们就可以直接使用 WOFF 和 WOFF2。
最后,我们终于弄清楚了所有常用的全局 CSS 关键字值,比如 auto 或 inherit,我们经常使用它们,却从未真正质疑过它们是什么以及它们是如何工作的。
注意,你不需要知道和记住所有的 CSS 函数,你需要知道在哪里查找——这本书。****
第八章:JavaScript 实现、语法基础和变量类型
JavaScript(JS)是一种主要用于生成动态和用户交互式网页的编程语言。大量网站和所有最新的互联网浏览器(客户端)都使用并支持 JavaScript。它是每个网络开发者必须学习的技术堆栈的一部分;这些包括 HTML(内容)、CSS(内容的呈现)和 JS(当用户与网页交互时内容的动作)。
以前,JavaScript 的使用仅限于输入验证。例如,如果用户输入无效信息或尝试提交缺少信息的表单,它会产生一个错误消息。现在,JS 被认可为一种完整的编程语言,能够处理复杂的计算,并处理客户端窗口的所有方面。JS 通过使其更具交互性来增强网页。例如,可以将散布的缩略图页面转换为漂亮的图片库,可以在不强制客户端反复重新加载的情况下加载网站内容,可以以优雅的方式处理各种错误处理,可以创建用户投票并在网站上查看结果,以及通过 JavaScript 的力量在移动中与 HTML 元素互动等等。
JavaScript 非常快——真的非常快。它对用户操作,如点击、双击、调整大小、拖动、滚动等,能立即做出响应。JavaScript 的语法与 Java 语言类似。JavaScript这个名字让很多人感到困惑。只有 JS 的语法与 Java 语言的语法相似。否则,它与 Java 编程语言根本没有任何关系。
以下是一些 Java(编程语言)和 JS(脚本语言)之间的关键区别:
-
JavaScript 嵌入到 HTML 中,并在浏览器中运行,而 Java 需要Java 虚拟机(JVM)来执行;然而,Java 小程序可以在浏览器中运行。
-
JavaScript 被称为客户端语言,因为它在客户端的浏览器中运行,但现在,Node.js 是 JS 进入服务器端的大门。另一方面,Java 在 Web 服务器上运行,例如,Apache Tomcat。
-
JavaScript 通常由客户端解释,而 Java 则由 JVM 编译然后执行。
-
JavaScript 是由Netscape(现在是 Mozilla)创建的,而 Java 是由Sun Microsystems(现在是 Oracle)开发的。
JavaScript 的历史
Netscape(现在为 Mozilla)的 Brendan Eich 在 1995 年开发了 JavaScript。最初,它被命名为 Mocha,后来其名称改为 Livescript,最终更名为 JavaScript。在发布后,Microsoft 引入了 Jscript——他们自己的 JavaScript 版本,包含在 Internet Explorer 中。Netscape 将 JavaScript 提交给 欧洲 计算机制造商协会(ECMA)进行标准化和规范。标准化版本被命名为 ECMAScript。ECMAScript 是由 ECMA 国际标准化的脚本语言规范。
ECMAScript V5 引入了一种新的模式,称为 严格模式;这引入了更好的、彻底的错误检查,以避免导致错误的构造。许多来自第三版本的不确定性都被移除,并添加了现实世界的实现。
ECMAScriptV6 添加了许多新的语法来编写复杂的程序。它引入了类和模块,扩展了 V5 的语义。迭代器也在此版本中添加,以及许多类似 Python 的语义,包括代理、箭头函数、生成器和生成器表达式、映射、集合等。
JavaScript 的演变
在将 JavaScript 标准化为 ECMAScript 之后,下一步是实现对 文档对象模型(DOM)的完全控制。
网页浏览器通过 DOM API 将 HTML 解析为 DOM。DOM 是客户端对网页的理解。所有元素/节点都被转换为称为 DOM 树的树状结构。可以使用不同的方法(如 getElementById() 和 getElementsByName())实时操作此树的结构成员。我们在开发者工具中看到的 HTML 源代码,如 Inspect Element、Fire Bug 等,都是 DOM 视图。这些开发工具也极大地帮助我们在瞬间修改我们的 DOM。
之后,异步 JavaScript 和 XML(AJAX)被引入以实现异步应用程序。数据被发送到并从网络服务器接收,而不需要重新加载或刷新整个 DOM 树(异步)。
随着 JavaScript 的发展,开发了不同的 JS 库以简化 DOM 操作。其中一些流行的库是 jQuery、Prototype 和 Mootools。这些库的主要功能是处理 DOM 操作、动画和 AJAX。最著名且广泛使用的 JS 库是 jQuery。此外,还开发了一个名为 Node.js 的服务器端 JavaScript 版本。
在这本书中,你将了解 JavaScript、其历史和演变。你将学习其实现和语法。还提供了函数引用和如何在不同情况下使用的完整示例。
JavaScript 实现
由于 JavaScript 和 ECMAScript 在类似的应用场景中被使用,JavaScript 比 ECMAScript 提供了更多功能。它由以下三个部分实现:
-
核心 JavaScript(ECMAScript)
-
文档对象模型(DOM)
-
浏览器对象模型(BOM)
核心 JavaScript(ECMAScript)
JavaScript 支持移动设备和桌面计算机;这一特性使其成为一种跨平台脚本语言。然而,如果单独使用,它并不太有用,这就是为什么它通常与服务器端语言一起使用,以创建强大且交互式应用程序。它可以轻松地集成到网络浏览器环境中,使用户能够完全控制浏览器对象和事件。
JavaScript 的核心功能也称为 ECMAScript。ECMAScript 实际上不依赖于浏览器或环境。它是一组核心语言元素,用于不同的环境,例如 ScriptEase 和 Flash 动作脚本。因此,我们可以说 ECMA Script 包含以下内容的定义:
-
语言语法
-
关键字/保留字
-
数据类型
-
语句
-
运算符
-
控制结构
-
对象(例如,数组、日期、数学等)
因此,ECMAScript 定义了脚本语言的所有函数、方法、属性和对象。其他脚本语言,如 JavaScript,是 ECMAScript 的实现。
ECMAScript 在不同的浏览器中有不同的实现,之后 DOM 和 BOM 才被包含。
文档对象模型 (DOM)
DOM 是 HTML 和 XML 文档的 应用程序 编程接口 (API)。它是网络文档的逻辑结构。它是文档中存在的节点的高层次树视图。浏览器将文档转换为 DOM,并且只理解它。DOM 允许开发者控制节点,并实时更改文档。
例如,这是一个简单的网页:
<html>
<head>
<title>My Web Document</title>
</head>
<body>
<p>Javascript Reference!<p>
</body>
</html>
浏览器对象模型 (BOM)
当 DOM 处理文档时,浏览器对象模型 (BOM) 处理浏览器窗口。BOM 允许程序员在浏览器窗口上执行多个操作,这些操作与 HTML 文档本身没有直接关系,也没有影响。BOM 还处理浏览器对象,例如历史记录、屏幕、导航器和位置。
注意
BOM 在不同的客户端中有不同的实现。
客户端 JavaScript
JavaScript 主要被认知为一种客户端脚本语言。任何用于编写在客户端(任何网络浏览器,如 Internet Explorer、Safari、Google Chrome、Mozilla Firefox、Opera 等)上执行程序或脚本的编程语言都称为 客户端脚本语言。这些脚本使你的 HTML 看起来交互式和动态。JavaScript 允许用户与网页内容以及客户端窗口本身进行交互。
将 JavaScript 添加到网页中
大多数情况下,JavaScript 代码被嵌入到 HTML 中的<script>标签内,可以通过查看页面源代码来查看。将 JavaScript 嵌入到页面中的良好实践是将所有脚本放在一个单独的文件中(一个具有.js扩展名的 JavaScript 文件)。然后,此文件可以包含在页面中。当页面被解释时,它将被视为与在同一页面上嵌入的相同。
小贴士
JavaScript 文件必须具有.js扩展名。
由于客户端始终期望 HTML,因此任何其他内容,如样式或脚本,都必须包含在其特定的标签内;例如:
<style>
/* all css code */
</style>
<script>
//all scripts
</script>
当浏览器的渲染引擎发现任何<script>标签时,JavaScript 解释器就会被调用。
大多数时候,JavaScript 位于网络文档的<head>标签内:
<html>
<head>
<title>My First JavaScript Example</title>
<script type="text/javascript">
alert("Hello earthlings!");
</script>
</head>
<body>
</body>
</html>
type属性指定这些<script>标签内封装的代码是纯 JavaScript 代码。不强制提及type属性。前面的代码也可以不使用它来编写,并且将按完全相同的方式工作。
虽然可以在 HTML 文档的任何位置放置<script>标签,但另一个良好的实践是在文档末尾关闭</body>标签之前将其放置,以确保在执行任何脚本之前所有页面都已加载。
加载外部 JavaScript 文件
就像外部 CSS 文件被包含到网页中一样,JavaScript 也可以从外部 JavaScript 文件中包含到网页中。让我们看看以下 HTML 代码:
<html>
<head>
<title> My First JavaScript Example </title>
<script src="img/external_javascript_Planets.js"></script>
</head>
<body>
</body>
</html>
src属性与用于图像<img>标签的属性非常相似。它只是提到了外部 JavaScript 文件的引用路径,这些文件稍后将被包含到页面中。不要在导入外部 JS 文件的<script>标签中添加任何其他 JavaScript 代码。如果需要,请放置另一个<script>标签。
也可以包含多个外部 JS 文件,如下所示:
<html>
<head>
<title> My First JavaScript Example </title>
<script src="img/external_javascript_Moon.js"></script>
<script src="img/external_javascript_Sun.js"></script>
<script src="img/external_javascript)Stars.js"></script>
</head>
<body>
</body>
</html>
小贴士
在使用外部 JavaScript 库(如 jQuery 和 MooTools)的情况下,必须注意文件包含的顺序。
在 JavaScript 中编写我们的第一个程序
别担心,这绝对不是一门陌生的语言。它是一种高级语言,由于其语句、关键字和其他语法基于基本英语,因此可以很容易地理解。学习任何编程语言的最简单方法是跳进去并玩其代码。为了在 JavaScript 中入门,我们将编写一个非常基础的 JavaScript 程序。
前提条件
以下是我们编写第一个 JavaScript 程序所需的前提条件:
-
一个网络浏览器
-
一个文本/代码编辑器
-
一个网络文档
如何操作
-
在您舒适的任何代码编辑器中创建一个
index.html文件。将以下代码复制并粘贴到您的文档中。这是一个简单的 HTML 代码:<html> <head> <title> My First JavaScript Example </title> </head> <body> <h1>The Planetary System</h1> </body> </html> -
在头部部分在关闭
</head>标签之前创建一个<script>标签:<html> <head> <title> My First JavaScript Example </title> <script type="text/javascript"></script> </head> <body> <h1>The Planetary System</h1> </body> </html> -
在脚本标签内插入
alert("hello world"); document.write('<h2>This text has been added by JavaScript!</h2>');。 -
alert属性是一个 JavaScript 函数,它创建一个带有内部引号和括号中消息的弹出窗口。该消息被视为传递给警告函数的字符串。同样,document.write是一个 JavaScript 函数,它将给定的字符串输出到网页上。<html> <head> <title> My First JavaScript Example </title> <script type="text/javascript"> alert("Hello Earthlings"); document.write('<h2>Greetings from Mars!</h2>'); </script> </head> <body> <h1>The Planetary System</h1> </body> </html> -
双击
index.html文件以执行并在浏览器中打开。将出现一个带有警告信息的弹出窗口。
点击确定以关闭警告框,网页将显示。
这是你进入 JavaScript 世界的第一步,尽管它非常基础,并没有展示 JavaScript 的真实力量。我们将在接下来的章节中练习高级 JavaScript 代码。
服务器端 JavaScript
服务器负责以编程语言提供网页。客户端向服务器发送带有命令的请求,服务器响应该客户端请求。服务器端编程是指运行在服务器上的程序。我们将在第十一章中进一步详细研究,扩展 JavaScript 和 ECMA Script 6。
术语服务器端意味着网页的控制由 Web 服务器而不是网页处理。Web crossing 运行该脚本,并以 HTML 的形式将信息发送到每个用户的浏览器。
Rhino和Node都常用于创建服务器。服务器端脚本不会下载到客户端浏览器。
服务器端
服务器端指的是在客户端-服务器关系中的计算机网络中由服务器执行的操作。术语服务器端也可以理解为浏览器之外的一切。
客户端
任何在客户端运行的东西意味着它在 Web 浏览器内部运行。
使用 Rhino 进行脚本编写
Rhino 是一个用 Java 语言开发和编写的 JavaScript 引擎/解释器,由 Mozilla 基金会管理,作为开源软件(www.mozilla.org/rhino)。它使 JavaScript 程序元素能够访问完整的 Java API。
描述
Rhino 是用纯 Java 编写的 JavaScript 开源实现。Rhino 用于为最终用户提供脚本。基本上,Rhino 将 JavaScript 脚本转换为类。它用于 JavaScript 的服务器端编程。
MDN 提到以下内容:“使用 Java 脚本有许多用途。它允许我们通过利用许多可用的 Java 库来快速编写强大的脚本。”关于this语句等内容的更多信息将扩展一般性陈述,并给出this语句实现和目的的见解。
我们可以将 Rhino 脚本用作类似于调试器的壳。这个壳以批处理模式运行代码。批处理模式指的是批处理,意味着无需人工干预的自动化处理。批处理是交互式的对立面。
注意
由于是开源的,Rhino 是由 Mozilla 提供的免费程序,可以从 www.mozilla.org/rhino 下载。Rhino 以 JAR 文件的形式分发。要使用命令行启动它,您可以在命令行界面中执行 Rhino JAR 文件:
java -jar rhino1_7R3/js.jar programfiles.js
Rhino 1.7R2 版本使用 ECMAScript 3,而 1.7R3 版本的 Rhino 部分使用 ECMAScript 5。Rhino 的最新稳定版本是 1.7R5,该版本于 2015 年 1 月 29 日发布。
这里有一些函数及其用法和描述:
| 函数 | 用法 | 描述 |
|---|---|---|
print |
print(x) |
这是一个全局的打印函数,用于在控制台打印 |
version |
version(170) |
这用于告诉 Rhino 我们想要 JS 1.7 的功能 |
load |
load(file1,file2…) |
这将加载并执行一个或多个 JavaScript 代码文件 |
readFile |
readFile(file) |
这将读取一个文本文件,并返回其内容作为字符串 |
readUrl |
readUrl(url) |
这将读取 URL 的文本内容,并将输出作为字符串返回 |
spawn |
spawn(f) |
这将运行 f() 或 load 并在新线程中执行 f 文件 |
runCommand |
runCommand(cmd,[args..]) |
这将运行一个系统命令,带有零个或多个命令行参数 |
quit |
quit() |
这将使 Rhino 退出 |
这里是一个简单的示例,它显示 strNote 字符串中的消息:
Dim strNote
strNote = "Welcome to Rhino"
Rhino.printstrNote
您可以在 www.rhinoscript.org/ 找到一些有用的脚本。
Node.js
Node.js 是 JavaScript 的一个实现,允许 JavaScript 在浏览器之外运行并执行基于 OS 和网络的任务。它是一个 JavaScript 的运行时接口。
Node 使用 Google V8,它实现了 ECMAScript 5 标准,这意味着 JavaScript 和 Node 的语法之间没有太大差异。例如,如果您想在控制台打印出 "Hello World",您将编写以下代码:
console.log("Hello from Mars!"); //This is same for JavaScript as well.
描述
Node.js 是一个运行在 Google Chrome V8 引擎上的超级快速接口。Node.js 易于使用,快速且可扩展。像 JavaScript 客户端编程一样,Node.js 提供了抽象。因此,通过这种抽象,Node.js 可以处理大量的代码。
这里是一个 Node.js 的服务器端编码示例:
var http=require("http");
http.createServer(function(request,response){
response.writeHead(200,{"content-type":" text/plain"});
response.write("Hello from Mars!");
response.end();
}).listen(8080)
语言语法
语言语法基本上是一种通信手段。在编程语言中,这是一种与算法正式通信的方式,无论是从算法到程序员还是从程序员到机器。这是因为机器根据给定的指令工作。
这些指令旨在以特定格式编写,以便机器能够正确理解并编译它。这种特定格式由编程语言的某些一般规则定义,称为语言语法。
计算机包含要执行的指令列表。每种计算机语言都有不同的语法和规则。要使用不同的语言,我们必须了解它们的语言语法,如下所示:
-
语法(一组符号和规则)
-
语义学(用于术语到术语的转换)
-
语义学(语言的具体结构)
类似地,JavaScript 中的其他语言也有独特的语法。JavaScript 不是 Java 语言;这两个是不同的语言,两种语言的语法也不同。JavaScript 是一种强大且表达性强的语言。JavaScript 的语句以分号结尾进行分隔。
对于有面向对象编程概念的初学者来说,JavaScript 的语言语法非常容易。JavaScript 包含在<scripts>…</script>标签之间。在任何网络浏览器中,这些都被视为 HTML 标签。
你可以将你的 JavaScript 代码放置在网页的任何位置,但我更喜欢使用<head>标签来定义你的脚本。因此,你的脚本结构如下所示:
<head>
<script>
……………..
</script>
</head>
基本上,当在<head>标签中写入<script>标签时,它告诉浏览器在网页加载时需要首先执行这些脚本。尽管如此,将 JavaScript 放在网页底部是一个好的实践。这个script标签有两个重要的属性。
语言
language属性将告诉您正在使用哪种语言属性;通常,它是 JavaScript。如果该属性不存在,则默认值为 JavaScript。
类型
type属性与前面的解释相同。这不是一个必需的属性。其值设置为text/javascript,这表明正在使用这种脚本语言。
<script language=" javascript" type="text/javascript">
.Script code.
</script>
字符集
字符集基本上是一组由计算机硬件和软件识别的字符。它用一个数字表示。早期 ASCII 被用作网页的标准字符集编码。在 HTML5 和 XML 出现之后,解决了许多字符编码问题。JavaScript 为不同类型的语言及其字符提供支持。字符集属性显示外部文件中的字符编码。对于 HTML5,默认字符集编码是 UTF-8。
字符集编码有一些常见的值,如下所示:
-
ISO-8859-1:这是用于编码拉丁字母
-
UTF-8:这是用于与 ASCII 兼容的 Unicode 编码
例如,如果你的前端页面是西班牙语,而你未在页面中使用字符集属性,那么它将无法清楚地显示一些特殊的西班牙语字符。为此,你必须在页面的顶部<head>标签中声明一个字符集属性,如下所示:
<meta charset="utf-8">?
注意
对于这一点,您也可以更改您的网络服务器配置以作为 UTF-8 服务。或者,我们可以向服务器端脚本发送内容类型头。
在 JavaScript 中,charset 属性返回当前文档的字符编码。从文档中读取 characterSet 属性的语法是 document.characterSet;。
我们可以在我们网站的父页面的 <script> 标签中定义 characterSet 属性,如下所示:
<script type="text/javascript"charset="utf-8"></script>
注意
另一种方法是将 UTF-8 字符集添加到服务器配置文件(.htaccess)中,如下所示:
AddCharset UTF-8
因此,字符集编码将应用于您应用程序中的所有 JavaScript 页面。
大小写敏感性
HTML 不是大小写敏感的语言,但 XML 和 JavaScript 是大小写敏感的语言。
描述
JavaScript 是大小写敏感的语言。JavaScript 中的大小写敏感性不仅适用于变量名,还适用于 JavaScript 关键字和 JavaScript 的事件处理器。例如,如果您有 firstname 和 firstName 变量,那么这些将是两个不同的变量。在 JavaScript 中,在调用函数时,您必须按照定义时的确切方式写出其名称,匹配字母大小写。
在 JavaScript 的原始方法中常用的一个流行约定是使用驼峰式命名法,其中短语以第一个单词的首字母小写开始,每个后续单词的首字母大写,这使得阅读更加容易。
一些函数的示例如下:
-
toUpper(); -
toArray();
注意
JavaScript 中的关键字都是小写的,例如 while、for、if 等等。
JavaScript 有一些内置的函数;它们接受字符串并将它们转换为大写或小写。这可以在输入具有不同大小写时使字符串的处理更容易操作。以下是可以由这些函数接受的两个参数:
-
.toUpperCase() -
.toLowerCase()
.toUppercase() 函数将字母转换为大写,而 .toLowerCase() 函数将字母转换为小写。这些都是 JavaScript 的内置且大小写敏感的函数。
空白和换行符
空白和换行符用于以整洁和一致的方式格式化和缩进代码,以便代码易于阅读和理解。
描述
空格、制表符、不是字符串一部分的换行符称为空白。JavaScript 在程序中的标记之间删除空白和换行符,当脚本执行时,字符串中的空格和换行符不会被删除。
在任何文本中,都有三种类型的换行符:\r\n 或 \r 或 \n。
这些换行符在不同的操作系统中出现:
-
\r\n通常在 Windows 上创建 -
\n通常在 OS X 上创建
如果您想从任何文本中删除换行符,那么我们必须处理所有类型的换行符,因为文本可能来自这三个来源:Windows、Linux 和 Mac。
我们有几种方法可以去除任何文本中的换行符。例如,我们有以下方法:
varabc = abc.replace(/(\r\n|\n|\r)/gm,"");
在此代码中,我们使用了正则表达式来从我们的文本中去除换行符。这将去除换行符 \r\n,然后是 \n,最后是 \r。我们在正则表达式的末尾使用了后缀 gm,因为 m 表示应该从所有文本中去除换行符,而 g 表示应该多次执行此操作。
正则表达式在 第八章 中详细讨论,JavaScript 表达式、运算符、语句和数组。
现在,文本之间存在一些空格;您可以使用 JavaScript 来去除这些空格。JavaScript 有不同的函数可以用来从字符串中去除所有前导空格;您可以使用以下函数:
str = str.replace(/^\s+|\s+$/g,'');
这段代码使用正则表达式,检查字符串开头和结尾的多个空格。
在这个正则表达式中,g 表示在检查文本时应执行全局搜索。还有更多方法,例如以下方法:
-
string.replace()函数用于将所有前导空格替换为空字符串 -
str.trim()函数用于从字符串的两端去除空格
Unicode 转义序列
每个 Unicode 转义序列由六个字符组成,具有明确的语法:四个字符跟在 \u 之后。较小的代码点前面有前导零,但序列的长度保持不变。例如,\u00a9 有两个前导零。同样,版权符号可以表示为 \u00A9。
任何小于 65536 的代码点的字符都可以使用其代码点的十六进制值进行转义,前面加上 \u。
注意
代码点(也称为 字符代码)是特定 Unicode 字符的数值表示。
描述
JavaScript Unicode 转义序列允许您在字符串中放置特殊字符。支持 JavaScript 的浏览器可以使用 escape 函数。
要在同一个字符串中添加下一行,我们可以使用 \n。让我们看看以下代码:
alert("Welcome to JavaScript. \n We hope you love it!")
要在字符串中添加引号,我们可以使用如下方式:
var myquote="Jinnah said \"Impossible is a word unknown to me.\""
这个 Unicode 转义序列以反斜杠 (\) 开头,后跟字符。这个反斜杠是转义序列字符。要插入一个反斜杠本身,只需在下一个反斜杠之前添加另一个反斜杠 "\"。也称为双反斜杠 (\\)。
您可以通过 \uaaaa 指定一个 Unicode 字符,其中 aaaa 是一个十六进制数。因此,Unicode 转义字符可以表示一个 16 位字符。
Unicode 转义序列表示一个 Unicode 序列,如下所示:
-
反斜杠 (
\) -
字符 (
u) -
十六进制数 (
0-9)(a-f)
例如,单词 cat 将表示为 \u732b。
Unicode 转义序列也可以用于注释和字面量。考虑以下示例:
var x = "http\\u00253A\\u00252F\\u00252Fexample.com";
注意
这种字符转义序列的十六进制部分不区分大小写,这意味着 \u041a 和 \u041A 是等效的。
你也可以表示一个转义序列来表示一个 Unicode 字符 ["\u03b1"] 作为 ["a"]。例如,字符 é 的 Unicode 转义是 \u00E9,以下两个 JavaScript 字符串是相同的:
"cafn" === "caf\u00e9" // => true
== 操作符在测试它们是否相同之前会尝试将值转换为相同的类型;而 === 则不会这样做。它要求对象类型相同才能相等。
这里有一些字符转义序列的示例:
| Unicode | 转义序列 | 含义 |
|---|---|---|
\u000B |
\v |
垂直制表符 |
\u000A |
\n |
换行 |
\u0009 |
\t |
空白字符 |
\u000C |
\f |
表单字段 |
\u000D |
\r |
行终止符 |
\u0020 |
空白字符 |
规范化
Unicode 标准(可在 unicode.org/standard/standard.html 找到)定义了编码字符的最可接受模式以及规范化方法。JavaScript 假设它读取和解释的代码具有所有 Unicode 表示的规范化。ECMAScript V6 有一个字符串原型函数 (string.prototype.normalize()) 来修复任何未处理的编码。
注意
ECMAScript 6 引入了 String.prototype.normalize() 方法,负责处理 Unicode 规范化。
标识符
标识符用于给函数和变量命名。这些标识符有一些规则,并且这些规则对所有编程语言都是相同的。标识符可以包含字母和完整的 Unicode 字符集的摘要。这些 JavaScript 标识符包括变量、对象、函数、属性、方法、事件等。
这里是标识符的规则:
-
标识符不能以数字开头
-
标识符可以包含数字、字母、下划线和美元符号 (
$) -
它可以是任何长度
-
这些是区分大小写的
-
我们不能使用保留词作为标识符
小贴士
我们还可以使用 Unicode 字符作为标识符。例如,Unicode 转义序列 \uaaaa 也可以用作标识符。我们必须避免使用全局方法或属性作为标识符。
在编写标识符时,一个最佳实践是使用一个单词并使用驼峰式命名法。考虑以下示例:
-
myNote
-
myNewNotebook
-
$sum
var 变量是一个有效的标识符名称,但由于它是保留词,因此不是一个有效的标识符。如果你使用一个有效的标识符,那么你的浏览器将正确处理它;然而,如果你使用一个无效的标识符,你的浏览器将显示警告,将其识别为错误。
保留关键字
保留字是 JavaScript 中的关键字。有一些字不能用作函数或变量名。这些保留字也是标识符。这些保留字是为 JavaScript 引擎保留的。如果你将这些保留字用作函数、变量或方法名,那么你的浏览器将显示警告,并且你的脚本可能会失败。
保留字基本上是具有特殊意义的 JavaScript 关键字,例如break、case、do、delete、else等等。
有三种类型的保留字:
-
受保护的保留字
-
新保留字
-
未来保留字
受保护的保留字
受保护的保留字不能用作变量或函数名。如果我们使用这些字,那么在编译时将会出现错误。以下是一些受保护的保留字的例子:
Break |
case |
catch |
|---|---|---|
class |
const |
Continue |
Debugger |
Default |
Delete |
do |
Else |
Export |
Extends |
False |
If |
Import |
in |
var |
新保留字
JavaScript 还发布了新的关键字,这些保留字在当前版本的 JavaScript 中具有特殊意义。这些保留字也可以用作标识符。一旦你将其声明为标识符,那么它就会忘记它曾经是一个关键字。以下是一些新保留字的例子:
Abstract |
Boolean |
byte |
|---|---|---|
char |
enum |
final |
doubke |
implements |
int |
interface |
internal |
long |
set |
short |
static |
uint |
ulong |
ushort |
未来保留字
未来保留字是为 JavaScript 未来的扩展而提出的。这些字在当前版本的 JavaScript 中也被用作标识符。当你选择一个字作为标识符时,也很重要的是要注意它是否已经是 JavaScript 保留字的名字。以下是一些未来保留字的例子:
asset |
event |
|---|---|
namespace |
require |
transient |
violate |
ensure |
goto |
native |
synchronized |
use |
Invariant |
注释
在任何编程语言中,注释都用于使你的代码可读。在 JavaScript 中,注释用于解释 JavaScript 代码。
注释的另一个用途是写入它们,以在我们的 JavaScript 代码中添加提示、建议和警告,这样如果除了开发者之外的其他人想要更改或修改你的脚本,他们可以很容易地进行修改。在脚本中使用注释被认为是最佳实践。注释还用于禁用代码的一些部分执行。在调试中,注释非常有帮助,因此它是开发者的宝贵调试工具。
你可以在你的 JavaScript 脚本中放入三种不同类型的注释:
-
多行注释
-
单行注释
-
HTML 注释的起始序列
多行注释
我们可以在注释边界之间写多行;这段代码将不会被执行:
/* this is a comment */
单行注释
在行首添加两个正斜杠来注释它。//和行尾之间的文本将被注释,并且不会编译。双正斜杠用于一次注释一行:
// this is comment
HTML 注释的开头序列
JavaScript 将 HTML 注释的开头序列,即<!--视为//注释。它不识别 HTML 注释的结尾序列,即-->。HTML 样式的注释通常不在 JavaScript 代码块中使用,因为//更为方便。建议不要在 JS 中使用 HTML 注释,因为这已经是一种旧习惯了。它们被用来隐藏与旧浏览器不兼容的 JavaScript 代码。
字面量
字面量用于表示 JavaScript 中不同数据结构的值;例如:
-
3.14 -
to be or not to be
在接下来的章节中,我们将介绍 JavaScript 的字面量类型。
对象字面量
对象字面量用于在对象中保存值。
描述
对象字面量包含逗号分隔的属性名和关联值的列表对,并且它们被括在{}内。对象字面量也可以没有值。在对象字面量中,每个name:value对由逗号分隔。
下面是一个对象字面量的例子:
varbookObj={
bookName="The Kite Runner",
CoverImage="KiteRunner1.png",
Author="KhaledHoesenni",
bookCategory ="Bestseller"
};
数组字面量
数组字面量包含表示数组元素的列表表达式。
描述
数组字面量包含数组内的值。它们放在数组括号[]内,每个元素由逗号(,)分隔。就像对象字面量一样,数组可以是空的,包含0个元素。当你创建一个数组字面量时,它指定了值作为其元素,并且其长度由这个数组的参数数量指定。下面是一个数组字面量的例子:
var Planets= ["Earth", "Neptune", "Saturn", "Mars"];
布尔字面量
如其名所示,布尔字面量具有布尔值,因此其值要么是true要么是false。
整数
整数字面量必须包含仅限于整数的值。
描述
在 JavaScript 中,整数字面量必须包含从 0 到 9 的数字。整数字面量不允许使用逗号和括号。整数可以是负数或正数。如果没有符号,则默认为正数。
浮点字面量
浮点字面量用于包含浮点数——具有小数点、分数或指数的数字。
描述
浮点字面量的例子如下:
22.56
-26.35689
18.4e2 //Equivalent to [18.4 x 10²]
-17.22E3 //Equivalent to [17.22 x 10^-3]
字符串字面量
字符串字面量,正如其名所示,只包含字符串值,即放在一对引号内的值。
描述
字符串字面量包含放在引号内的字符。您还可以创建一个空字符串,不包含任何内容。可以使用+符号将两个或多个字符串连接在一起。可以在字符串中插入特殊字符。一些特殊字符包括\n、\r、\b、\t等。
一些字符串字面量的例子如下:
strFirstName= "Jamie";
strLastName="Down";
strMarksObtained="200";
strClassesJoined="Microprocessors, "+ "Microcontrollers";
strAddress= "Michigan University \n United States";
语句
JavaScript 还支持一组用于识别一组指令并执行任务的语句。JavaScript 中有不同类型的语句,如if、for、while等。使用这些语句的基本目的是评估或检查是否满足某些条件。这些语句对所有编程语言都是通用的。
条件语句
如其名所示,条件语句基于条件和if以及then规则。例如,“如果你努力工作,你会得到回报”。在这里,努力工作是得到回报的条件。
考虑以下示例:
if (age < 20 && age > 12) {
person = "Teen ager";
}
else {
person = "Not a Teenager";
}
循环语句
在循环语句中,在括号内提供一个条件。如果条件评估为true,则循环将继续工作;如果条件等于false,程序将跳转到循环之后的下一行。一个例外是do while循环,它将始终至少执行一次。编程语言中有不同类型的循环;它们如下:
-
for循环 -
for/in循环 -
while循环 -
do/while循环
这里有一个示例,展示了如何使用while循环:
var number = "";
var n = 0;
while (n < 10) {
number += "\nThe number is " + n;
n++;
}
console.log(number);
循环在第八章中详细介绍,JavaScript 表达式、运算符、语句和数组。
对象操作语句
JavaScript 中的对象操作语句用于在运行时访问对象的属性和方法以执行特定功能。JavaScript 使用for...in和with语句来操作对象。
这里有一个示例,展示了如何操作对象car:
<script type="text/javascript">
var x;
var car = new Object();
car.brand = "Porche";
car.model = "2014";
car.colour = "Black";
for (x in car) {
console,log(x + " --- " + car[x] + "<br />");
}
</script>
输出:
brand — Porche
model — 2014
color — Black
异常处理语句
try、catch、throw和finally语句用于 JavaScript 异常处理。让我们看看以下描述:
-
try语句用于测试代码中的错误。 -
catch语句通常跟在try语句后面,捕获并处理try块中找到的错误。 -
throw语句创建自定义错误或警报。 -
finally语句在try和catch之后执行代码,无论结果如何。通常,这个代码块用于清理和释放资源。
这里有一个示例,展示了如何使用try和catch块来处理异常:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
<!--
function Calculate() {
x = document.getElementById("Val1").value;
y = document.getElementById("Val2").value;
try{
if ( x == 0 ||y==0 ) {
throw("Divide by zero error." );
}
else {
var a = x / y;
alert("The answer is: " + a );
}
catch ( err ) {
alert("Error: " + err );
}
}
//-->
</script>
</head>
<body>
<form>
<p>Enter first value</p>
<input id="Val1" type="text">
<p>Enter second value</p>
<input id="Val2" type="text">
<p><input type="button" value="Calculate" onclick="Calculate();" /></p>
</form>
</body>
</html>
可选分号
JavaScript 中的分号用于分隔语句。比如说,如果你有两个不同的语句,你只是把它们写下来,那么它们将不会容易理解。所以,JavaScript 使用分号来分隔语句。这将使你的代码更清晰、更有意义。如果你在 JavaScript 中不使用分号,那么它会使你的语句变得复杂,意味着你语句的结尾可能是你语句的开始。
注意
在你的代码中放置分号可以帮助你防止许多错误。代码块中缺少分号,在编译时将视为单行代码,从而导致多个错误。
JavaScript 不将换行符视为分号。以下是在 JavaScript 中使用分号的示例:
a=10;
b=20;
a=10; b=20;
注意
JavaScript 中的分号不是一个终止符;这些只是用于分隔语句的分隔符。
JavaScript 会自动在语句的末尾插入分号。你不应该在闭合的大括号后加分号。同样,有时在圆括号 () 后加分号也是一个坏主意,更重要的是,代码将无法运行。
如果你的脚本中有一个 for 循环,那么在第一个和第二个语句后加上分号,在第三个语句后不要加分号。这将产生语法错误。例如,如果你有一个这样的 for 循环:
for(i=0;i<5;i++;){}
上述代码将导致语法错误。正确的方法如下:
for(i=0;i<5;i++){}
这里有一些关于分号的规则:
-
当使用赋值运算符时插入分号
-
在赋值运算符的右侧操作数后插入分号
-
在函数的闭合圆括号后插入分号
-
在关键字后插入分号
-
当你声明一个变量时插入分号
数据类型
计算机根据一组给定的指令工作;它不能区分数字和字符。例如,如果你写了一些数字,如 12345,和一些字符,如 abcsd,它不能区分整数和字符。所以,数据类型被用来做这个。数据类型告诉在语句中使用或引用的数据类型。
在所有编程语言(C、C++、Java、JavaScript)中,都使用数据类型。每个数据类型都有存储数据的具体功能。许多经典的计算机编程语言要求你在声明数据对象时指定数据类型。JavaScript 没有这样的要求。同样,一些数据库要求声明存储数据的数据类型。
JavaScript 是一种动态语言。这意味着如果你声明了一个对象,那么它的数据类型可以动态地改变,例如:
var a=16;
a="abc";
a=true;
在第一个语句中,数据类型是整数;在第二个语句中,数据类型是字符;在第三个语句中,数据类型是布尔值。所以,在 JavaScript 中,数据类型在程序处理过程中会动态改变。
ECMAScript 标准中定义了六种主要的数据类型。
-
Null -
Undefined -
Boolean -
String -
Symbol -
Number
注意
JavaScript 将整数和浮点数视为相同。它不区分这两者。JavaScript 中的所有数字都表示为浮点类型值。
在这里,Null 和 undefined 是 JavaScript 中的简单数据类型,因为每个都定义了单个值。JavaScript 还支持一种复合数据类型,称为对象。JavaScript 中的对象被视为关联数组。
JavaScript 中的函数也被视为对象。因此,函数也可以作为变量存储。
typeof operator
运算符用于查找 JavaScript 变量的类型。例如,你有两个数字变量,如下所示:
5+1=6
在这里,5 和 1 是操作数,+ 是运算符。
该运算符的语法如下:
Typeof(operand)
描述
Typeof 运算符是一个一元运算符;它返回一个字符串,指示 typeof 表达式的类型。typeof 运算符以字符串的形式返回信息。它可以返回六个可能的字符串值。它们是 string、number、object、function、Boolean 和 undefined。
这里有一些 typeof 运算符的示例:
-
typeof("5"+"1"): 这将返回一个字符串 -
typeof(5+1): 这将返回一个数字 -
typeof(5+"1"): 这将返回一个字符串 -
typeof(5*"1"): 这将返回一个数字
注意
typeof 运算符不是一个函数。操作数用圆括号括起来,所以看起来像是一个函数,但它们不是函数。当你使用 typeofnull 运算符时,它返回一个对象。
The undefined type
在 JavaScript 中,一个空变量或没有值的变量有一个未定义的值。并且,typeof 也是未定义的。如果你想清空一个变量,你可以给它赋予一个未定义的值;例如:
var employee = undefined;
描述
在 JavaScript 中,undefined 是 global 对象的一个属性。这意味着值是未定义的,我们在浏览器的全局范围内声明它。
undefined 的基本有三个 property 属性:
-
Writeable -
Enumerable -
Configurable
这三个 property 属性表明,对于现代浏览器,这些属性是不可写的、可枚举的和可配置的。因此,我们应该避免覆盖这些属性。undefined 类型是 JavaScript 中的一个原始类型。
注意
Undefined 类型表示一个变量尚未被赋予值。所有浏览器,如 Firefox、Google Chrome、Opera 和 Safari,都根据 ECMAScript 支持该 undefined 属性。
Undefined 是 JavaScript 库中的一个内置类型。对于任何值未定义的函数类型,都被视为 undefined 类型。例如,如果你有一个没有 return 语句的函数,该函数的结果将被视为未定义。
作为全局对象的属性,它的值最初是未定义的。我们可以将其作为全局变量访问,尽管它是一个全局属性。一个简单的 undefined 类型想法是,当你的脚本中没有定义变量,但它确实存在,并且你将其视为全局变量时。
每当函数在脚本中执行,并且执行完毕没有返回值时,它将返回 undefined 类型,例如:
var abc,
f1=function(){}
f2=function() {
var hello;
return hello;
}
typeof(abc) ; // undefined
typeof(f1); // function
typeof(f2); // function
在这个例子中,变量 abc 被定义了,但没有给它赋值。请注意,undefined 类型是全局作用域中声明对象的原生属性。在这里,将其定义为全局对象并不意味着它不能被重新定义。它可以按照 ECMAScript 的规则被重新定义。因此,undefined 不是一个保留字;它可以在其全局作用域之外的其他作用域中用作变量名。
当你使用比较操作符时,你还可以在那里声明 undefined 类型,以了解变量是否有值。
空类型
在 JavaScript 中,null 表示一个空值。
以下是语法:
varabc; // Here abc does not exist and it has been not initialized
varabc=null; // Here abc exist but it does not has a value or a type
描述
在 JavaScript 中,null 的数据类型是对象。Null 表示在脚本中该值不存在。当你想要清空一个值时,你可以将其声明为 null。在期望某些值的地方,但发现什么也没有时,可以预期会出现 null。
注意
null 和 undefined 类型之间有很大的区别。null 的数据类型是对象,而 undefined 的数据类型是 undefined。在 identity 操作符中,null 不能是 undefined,但在 equality 操作符中,null 可以是 undefined。这是因为 equality 操作符在比较之前会将左侧的值转换为相同的类型。
undefined 表示变量已声明但未赋值。例如,var abc:
console.log(abc); //undefined
console.log(typeof abc); //undefinednull is an empty value. It can be assigned to a variable which means variable is defined and an empty value has been assigned to it. For instance,var abc = null;
console.log(abc); //null
console.log(typeof abc); //returns object
考虑以下示例:
Null===undefined;
//It's a false because identity operator always verify data type //equality
Null==undefined; //It's true because of equality operator
"你可能想知道为什么 typeof 操作符对于值为 null 的值返回 object。这实际上是原始 JavaScript 实现中的一个错误,后来被 ECMAScript 复制。今天,人们认为 null 被视为对象的占位符,尽管技术上它是一个原始值。"
- 专业 JavaScript 网页开发者指南,Wrox 出版社
数值类型
在 JavaScript 中只有一种数字类型。数字可以带小数或不带小数书写。可以用科学记数法书写更大的或更小的数字。
描述
与其他编程语言不同,我们有许多数值数据类型,如整数、浮点数、双精度浮点数等。JavaScript 有一个名为 Number 的数据类型来表示所有数值。JavaScript 为此类型提供了三个符号值:无穷大、NaN(不是一个有效的数字)。在 JavaScript 的数值类型中定义的 NaN 显示它是一个保留字,实际上它的值在现实中不是一个数字。
注意
在 JavaScript 中,整数和浮点值之间没有区别。
整数可以是正数、0 或负数。它们可以是任何基数,如十进制、十六进制或八进制。但在 JavaScript 中,数字通常以十进制书写。要检查 JavaScript 中可表示或可用的最大或最小数字,可以使用最大和最小值常量:
Number.maxValue
Number.minValue
注意
在 Firefox 或 Chrome 中,它是 Number.MAX_VALUE。
在数字类型中,你只需检查具有两种表示形式的数字,例如,如果你有数字 0,那么它有两种表示形式——一个是-0,另一个是+0。JavaScript 数字可以带小数点或不带小数点书写;例如:
A non- decimal number
var a=10
A number with decimal
var b=10.0123
如果数字太大或太小,我们则使用科学记数法的指数来表示它。考虑以下示例:
If we have a number 100000000
var a=1000e5
And 0.00111
var b=111e-5
限制为1e+21(控制台从 10 的幂次方显示科学记数法)。
注意
在其他编程语言中,我们可以将数字定义为float、integer、long和short。但在 JavaScript 中,数字只有一个数据类型,即numbers。这些数字遵循 IEEE 标准,并且这些数字是双精度。
Boolean类型
在编程语言中,Boolean类型基于布尔逻辑工作,其中变量返回true或false的结果。这些true和false基本上是字面量。布尔逻辑通常用于比较运算符,例如小于或大于等。
任何变量都可以被赋予一个以小写true或false书写的Boolean值。
描述
在 JavaScript 中,当你将Boolean数据类型声明给一个变量时,该变量不应有任何引号。以下是如何使用布尔赋值:var abc = "true"; //字符串赋值和var abc = true; //布尔赋值。Boolean变量也用于if、if...else和while循环中。
下面是一个展示如何使用布尔变量的示例:
var x=true;
if(x==true) {
document.write("this true");
}
当存在或不存在值时,也会使用Boolean运算符。例如,如果我们脚本中有一个复选框,那么它的值取决于它是否被选中。
在其他数据类型中,变量的值可以有无限多种,但对于Boolean数据类型,只有两种——true和false。这种数据类型通常用于我们有一个受控结构,如比较、if...else循环和while循环。这些都是受控结构。If和else语句在值为true时执行一个动作;否则,将执行另一个动作,即false。
你还可以将Boolean数据类型用作比较表达式。比较表达式是一个评估0、null和undefined为false,其他值为true的表达式。考虑以下示例:
C=A+B
在这个例子中,A+B的结果首先存储在C中,然后评估这个表达式。如果你想检查C的值是否等于A+B,你必须使用比较运算符来完成,如下所示:
C==A+B
字符串类型
在 JavaScript 中,任何在引号之间书写的都被视为字符串。可以使用双引号或单引号。
字符串字面量可以通过两种方式定义。一种方式是使用双引号编写字符串,另一种方式是使用单引号编写字符串。
注意
在 JavaScript 中,没有特殊类型来表示单个字符。如果你想用 JavaScript 表示单个字符,你必须定义一个单字符字符串,例如,字符a。空字符串是一个零长度的字符串,例如""。
描述
在 JavaScript 中,文本数据以string数据类型的形式表示。在编程语言中,字符串是字符和数字的组合。JavaScript 字符串是零个或多个字符的有序序列。
编写这些字符串的限制是,你必须使用相同的引号在开头和结尾。这意味着以单引号开始的字符串必须以单引号结束,双引号也是如此。考虑以下示例:
var x="xyz" //double quotes
var y='xyz' //single quotes
var z="" //empty string
如果字符串中存在问题,它无法显示某些字符。对于这些字符的表示,JavaScript 中有一个技术——我们定义转义序列来表示。这意味着我们无法直接写入的字符,可以使用转义序列来表示。例如,如果我们想在字符串中插入一个引号,我们可以通过在引号前加上反斜杠来实现。这被称为转义引号。同样,字符串字面量无法表示非打印字符,如制表符、换行符等。
转义序列是以反斜杠开始的字符组合。以下是一些转义序列:
-
\b: 退格删除前一个字符并将光标向后移动一个空格。
-
\n: 换行符结束当前行并将光标移动到新行。如果在字符串中间使用,它将把
\n后面的文本移动到新行。 -
\f: 表格馈送它是一个页面换行 ASCII 控制字符。它告诉打印机在新页面上继续打印。
-
\v: 垂直制表符它曾用于控制页面上的垂直移动。现在很少使用。
-
\t: 水平制表符控制页面上的文本水平插入。通常使用键盘上的Tab键插入。
-
" : 双引号双引号前面需要加上反斜杠才能在字符串中插入。
-
' : 单引号单引号前面需要加上反斜杠才能在字符串中插入。
-
\: 反斜杠在字符串中插入反斜杠时,我们用另一个反斜杠来转义它。
这里是这个示例:
var abc = "hello \n Morning"
其输出将如下所示:
Hello
Morning
对象类型
对象是原始数据类型和有时是引用数据类型的序列,存储为名称-值对。
语法如下:
varsomeObj= {property:value};
描述
在 JavaScript 中,对象是用花括号书写的。对象中的每个项目被称为属性。属性值可以是任何有效的数据类型,也可以是函数或方法。考虑以下示例:
varobj= {book_name:"xyz", Author:"abc"};
我们可以说对象是项的列表,列表中的每个项都存储了一些作为其名称-值对的函数和方法:
在 JavaScript 中,一切都是对象,例如:
-
正则表达式是对象
-
数字是对象
-
字符串是对象
-
数学符号是对象
-
数组和函数是对象
-
对象就是对象
任何项的属性名可以是字符串或数字。当一个属性是数字时,写这个属性的方式就不同;我们将这样写:
var age = {"30": "abc"};
在 JavaScript 中,对象用于存储数据和编写自定义方法和函数。原始值例如 null、undefined、true 和 false。
对象属性基本上是用于方法和函数内部的变量。它们也可以是整个页面的全局变量。方法和函数之间有一个区别。函数是对象的一个独立单元,而方法则附加到对象上,并使用 this 关键字:
Document.write ("hello world");
变量、作用域和内存
当我们在 JavaScript 中描述一个变量时,这个变量可以存储的数据量没有限制。最大值由浏览器的容量决定,这取决于它可以存储多少数据。让我们看看以下代码:
var abc="xyz";
我们可以使用 var 关键字在 JavaScript 中定义一个变量。我们可以立即定义变量的值,或者稍后定义。我们定义在函数边界之外的变量是全局变量。
提示
在 JavaScript 中创建过多的全局变量是一个非常糟糕的方法。JavaScript 中不建议使用全局变量的主要原因是因为在 JavaScript 中,所有代码共享一个单一的全球命名空间,而且 JavaScript 有隐式全局变量,即未在局部作用域中显式声明的变量会自动包含在全局命名空间中。过度依赖全局变量可能导致同一页面上的各种脚本之间发生冲突。
脚本中的每个函数都可以访问全局变量。当你在函数中定义一个变量时,其作用域就在该函数内部。让我们看看以下代码片段:
Function abc() {
var xyz="abc";
}
注意
全局变量的作用域在整个页面的执行过程中永远不会停止,即使它不再需要。
如果你没有在函数内部写 var,那么这个变量被认为是全局变量。如果你用相同的全局变量名定义了一个变量,那么它将被认为是全局变量。
JavaScript 动态为变量分配内存。当这些变量的作用域被取消引用或完成时,垃圾回收器会自动将其从内存中移除。因此,其缺点是不需要的变量仍然留在内存中。
保存内存有两种方法:
-
使用函数作用域
-
手动取消引用这些变量
使用函数作用域更为合适,因为当函数结束时,变量会被取消引用,从而节省内存:
(Function (window, document, undefined) {
varabc="abc";
}
(window, document);
变量声明
JavaScript 变量可以通过唯一名称识别。这些唯一名称被称为 标识符。JavaScript 中的变量用于存储信息。标识符可以是任何长度和大小,例如,a、b、myName。
当你在 JavaScript 中声明一个变量时,机器会将其保存在内存中,以便你可以在需要时从内存中存储或检索数据。变量名在脚本中应该是唯一的。
在 JavaScript 中声明变量名的规则与之前讨论的标识符规则相同。
当代码开始执行时,它首先处理变量声明。这些变量可以全局声明,也可以在函数内部声明。我们可以声明多个以逗号分隔的变量,例如:
var myName,myAddress,myContact;
当我们将数据存储到变量中时,这个过程称为变量初始化。我们可以在创建变量时或稍后当我们想要使用它时初始化变量,例如:
var a=1;
var b=2;
var c;
c=a+b;
在这个例子中,变量a存储了值1,而b存储了2,然后我们创建了变量c并在稍后定义其值。
变量作用域
变量作用域是变量在程序中存在的框架。我们可以在程序中定义变量的作用域。基本上,作用域是我们能够访问的方法、函数和对象集合。
在 JavaScript 中,变量有两种作用域:
-
局部作用域变量
-
全局作用域变量
局部作用域变量
在函数内部定义的变量称为局部作用域变量,因为这个变量只能在这个函数内部访问。函数变量将只对这个变量是局部的。
描述
对于在局部作用域中定义的变量,可以在不同的函数中使用具有相同名称的变量。当函数开始时,局部变量被创建,当函数结束时,局部变量被删除。在 JavaScript 中,始终在使用变量之前声明它们;未能这样做将抛出一些异常。在一个函数中,如果你有一个与全局变量具有相同名称的局部变量,那么局部变量将具有优先权。因此,避免使用相同的变量名。让我们看一下以下代码片段:
function xyz() {
varabc="xyz";
document.write(abc);
}
全局作用域变量
全局变量可以在 JavaScript 程序的任何地方声明。它们可以从任何地方访问。全局作用域变量在整个页面上脚本执行期间都保留在内存中。这会导致内存耗尽。
描述
基本上,全局变量是窗口对象。全局变量通常在函数外部定义,并且网页中的所有函数都可以访问这个全局变量。如果你给一个未声明的变量赋值,那么这个变量将被视为全局变量。当你关闭网页时,全局变量将被删除。对于 HTML 的前端开发者来说,窗口对象是一个全局变量。
var abc="xyx";
functionmy Function() {
//some code
}
原始类型值和引用类型值
变量可以有两种类型的值:
-
原始类型值
-
引用类型值
原始类型值
通常对象是从属性中聚合的,这些属性可以用来引用对象。原始类型(值,数据类型)不是对象,并且没有与之关联的方法。
描述
在 JavaScript 中,有五种原始类型:string、number、null、undefined 和 Boolean。原始值直接存储在栈上。这些值存储在它们被访问的相同位置。由于其固定大小,它可以很容易地进行操作。
引用类型值
引用类型值是类似于数组和函数的特殊对象,存储在堆中。使用指针来定位它们在内存中的位置。
描述
在 JavaScript 中,存储引用类型值的变量存储在堆内存中。这些对象不能轻易操作,因为它们包含任意元素和属性。当引用值传递给函数时,函数会修改其值或内容,这种变化可以通过调用函数的对象以及有对象引用的其他函数看到。
执行上下文和范围
范围和上下文不是同一件事。JavaScript 中的每个函数都有一个范围和上下文。当我们用 JavaScript 声明一个函数时,这个函数可以在不同的上下文和范围内被访问。JavaScript 遵循范围和上下文的设计模式。
范围和上下文之间的主要区别在于,范围是基于函数的,而上下文是基于对象的。范围用于在调用时访问函数。而上下文与 this 关键字一起使用,因此它基本上是一个引用类型。
范围与执行上下文在执行上下文开始时相关联。与之相关联的是一个范围链,例如:
function first() {
second();
function second() {
third();
function third() {
fourth();
function fourth() {
// do something
}
}
}
}
first();
在 JavaScript 中,代码执行的 环境 被分类为以下几种:
-
全局代码
-
函数代码
-
eval代码
全局代码
全局代码是一个默认环境,代码首次执行时,即外部 .js 文件和本地内联代码被加载。
函数代码
函数代码是代码执行期间流程控制进入函数体的环境。每次函数返回都会退出当前执行上下文。
eval 代码
代码被提供给内置的 eval 函数。eval 代码调用上下文并创建一个执行上下文。
例如:
var eval_context = { a: 10, b: 20, c: 30 };
function test() {
console.log(this);
}
function evalInContext() {
console.log(this); // { a: 10, b: 20, c: 30 }
eval("test()"); // { a: 10, b: 20, c: 30 } inside test()
}
evalInContext.call(eval_context);
在这个例子中,你使用你想要的上下文调用函数,并在该函数内部运行 eval。
垃圾回收
JavaScript 中没有单独的内存管理。浏览器决定何时需要清理。垃圾回收基本上是知道变量在整个程序执行过程中是否仍在使用或将来会被使用,如果不使用则收集并删除它们。简单来说,对对象的引用跟踪是在后台进行的。一旦它变得空闲或达到零,就可以由 GC 收集。
我们可以手动清理内存,但在某些情况下,没有必要手动清理内存。我们无法强制 JavaScript 清理内存,因为这项任务是由垃圾回收器在运行时完成的。一些重型应用程序,如计算机游戏,需要大量内存并减慢你的系统;因此,在这种情况下,这完全取决于你的代码以及你如何结构化你的应用程序代码以使用计算机内存。
你可以通过以下步骤来结构化你的代码:
对象
当你声明一个对象时,尝试通过删除其属性并将其恢复为空对象(如{})来重用该对象。这个过程被称为对象的回收。当对象第一次创建时(new foo();),会为其分配内存。因此,如果已经声明了一个对象,我们可以在脚本中重用它。
数组
当你在脚本中使用数组时,使用完毕后请清除该数组。将[]分配给数组通常用作清除它的快捷方式,但实际上它会创建一个新的空数组并废弃旧的数组。你可以将数组长度设置为0(arr.length = 0;),这将清除数组,同时重用相同的数组对象。
函数
当你需要多次调用一个函数时,你可以通过将一个永久变量分配给该函数而不是反复调用它来优化我们的代码。
第九章。JavaScript 表达式、运算符、语句和数组
JavaScript 是最常用的网络编程语言,并且在全世界开发者中非常受欢迎。本章将涵盖该语言中使用的几乎所有表达式、运算符、语句和数组。
表达式
用来解析值的有效代码单元被称为表达式。它是一组字面量、运算符、变量和表达式,用于评估一个值。这个值可以是字符串或任何逻辑值。表达式产生一个值,可以在需要值的地方写入。表达式有两种类型:
-
将值分配给变量的表达式
-
具有值的表达式
考虑以下示例:
var A = 2;
在前面的例子中,一个值被分配给变量A,为了将这个值分配给变量,我们使用赋值运算符。现在考虑另一个例子:
2+3;
在这个例子中,没有值被分配给变量;然而,它评估2+3的结果为5。在这个表达式中使用的运算符被称为加法运算符。
JavaScript 中的表达式可以大致分为三种类型:
-
算术:这些评估数字。这意味着这些表达式在值之间执行数学计算。
-
逻辑:这些用于评估并以
true或false的形式给出结果。 -
字符串:这些用于评估字符串。
注意
另一种类型的表达式称为条件表达式。这些表达式通常用于if-else和loop条件中。这些条件表达式以true或false的形式评估结果,并且只有两个值True和False。如果第一个条件是true,则首先评估,否则将评估第二个,例如:
int age = 20;
var flag;
if (age<18) {
flag=true;
}
else {
flag=false;
}
主要表达式
在 JavaScript 中,主要表达式是基本关键字,它们是特殊对象、标识符和字面量,不需要进一步评估即可解析它们的值。它们也可能是另一个表达式的结果,该表达式被括号包围。
例如,this和function是关键字,这些是 JavaScript 中的主要表达式。this关键字在进入执行上下文时始终返回一个值。标识符也是主要表达式,它们指代一个函数或对象。
有四种字面量类型,作为主要表达式:
-
布尔字面量:这些包含
1/0或true/false -
空字面量:这些包含一个
null值 -
未定义字面量:这些包含任何类型的数据类型
-
字符串字面量:这些包含字符字符串
对象初始化器
在 JavaScript 中,对象初始化器用于初始化对象。它是一个称为对象初始化器的表达式。JavaScript 中的每个对象都是一个具有类型的实体。每个对象都与其一些属性相关联。与对象相关联的函数被称为方法。对象属性基本上是 JavaScript 变量。与对象相关联的属性会告诉你关于对象特性的信息。
对象属性可以属于原始数据类型,如int或其他数据类型,如char。对象也可以有一个空属性。我们可以创建一个具有空属性的对象,如下所示:
var xyz={};
在这些大括号中,你可以轻松快速地创建对象。这些是逗号分隔的名称-值对。对象初始化器基本上用于创建一个新的对象。这些对象初始化器被称为对象字面量。
小贴士
在 JavaScript 中,属性名和对象名是区分大小写的,所以当你创建一个对象时,应该记住这一点。
对象初始化器使用字面量表示法创建一个对象,例如:
var studentInfo = { age:24, Name:"Ali" };
这在第八章中有更详细的介绍,JavaScript 面向对象编程。
函数定义表达式
JavaScript 中的函数使用函数关键字定义。在这些函数上定义表达式。它们用于声明函数或函数表达式。你可以在脚本中的任何地方定义函数。函数使用表达式来定义它们的原型。
在 JavaScript 中定义函数有很多方法,例如,我们有以下几种:
-
函数声明
-
函数表达式
函数声明
当浏览器考虑执行脚本时,函数声明是一个预执行阶段。函数可以在你的代码的任何地方声明:
function greetings() {
alert("Happy New Year");
}
greetings();
函数表达式
当一个函数的形式是一个表达式时,它被称为函数表达式。这个表达式可以是一个大的表达式,这意味着函数声明需要多个表达式。使用函数表达式赋值的函数可以是有名字的,也可以是没有名字的。这通常被称为匿名函数。它是一个一等值,这意味着它允许将值作为参数传递给函数。
考虑以下示例:
var abc=function() {
return 1;
};
var xyz=function foo() {
return 2;
};
函数值也可以赋给另一个函数参数。这样,函数值作为值传递传递给另一个函数参数。
var f = function f ( function foo() );
JavaScript 中的函数也是一个常规值。如果你不希望你的变量在全局作用域中设置,那么将这些变量放入一个函数中。我们这样做是因为设置全局变量并不总是一个好的选择,因为它可以被程序中的任何函数在任何地方访问,这可能会改变变量的值并覆盖原本应该使用的原始值。函数通常在括号内编写,因为 JavaScript 允许表达式全部在同一空间中。
属性访问表达式
在 JavaScript 中,要访问对象或数组元素的值,我们使用属性访问操作。从这些表达式访问值有两种编写属性访问表达式的写法:
-
中括号表示法
-
点表示法
中括号表示法
中括号表示法也称为数组表示法。编写中括号表示法的语法如下:
get=abc[xyz];
abc[xyz]=set;
get = abc [1]; // get value at array abc index 1
点表示法
点表示法也称为对象表示法。编写点表示法的语法如下:
document.write ("hello world");
调用表达式
在 JavaScript 中,调用表达式用于执行或调用函数或表达式。当函数调用开始时,它首先评估其表达式,然后评估其参数。以下是调用表达式上的两个目标:
-
调用目标
-
可选参数列表
调用目标
一个调用目标后跟一个开括号,然后是一个目标列表,最后是一个闭括号目标列表,必须被分类为方法或对象。有两种类型的参数列表:
-
位置参数
-
命名参数
位置参数是表达式,命名参数是标识符。以下是一个调用表达式的示例:
Function.getvalue(5);
Math.max(2,3);
命名参数是带有其名称的参数。
可选参数列表
变量被分配一个作为函数参数传递的值。如果没有传递值,则变量将被分配一个默认值:
function add(a, b) {
b = typeof b !== 'undefined' ? b : 0; // if b not defined set it to 0
return a+b;
}
add(10); // returns 10
对象创建表达式
在 JavaScript 中,此表达式用于使用构造函数方法创建对象。此方法用于初始化对象的属性。此方法首先创建新对象,然后使用 JavaScript 中的对象初始化方法初始化对象。用于初始化对象的构造函数不返回任何值,此值成为对象的值。考虑以下示例:
New myObj();
评估表达式
评估表达式用于评估一个字符串。这是 JavaScript 中全局对象的一个属性。当它评估一个字符串时,它会给出一个值作为输出。
Eval()函数在 JavaScript 中用于获取值。在这个函数中,我们执行以下操作:
-
作为输入,我们传递一个参数
-
如果它没有返回值,那么意味着代码中存在错误,并且它会抛出异常
var x = 10; console.log(eval("x * 5")); //50
你有两种方式可以调用eval()函数:
-
直接:直接调用名为 'eval' 的函数。直接 eval() 在其局部作用域中执行代码。例如:
var abc = 'global scope'; function directEval() { 'use strict'; var abc = 'local scope'; console.log(eval('abc')); // local scope } -
间接:通过调用 call() 函数、window 的方法或通过不同的名称存储并从那里调用等方式调用它。间接 eval() 在其全局作用域中执行代码。例如:
var abc = 'global scope'; function indirectEval() { 'use strict'; var abc = 'local scope'; // eval via call() console.log(eval.call(null, 'abc')); // global scope console.log(window.eval('abc')); // global scope console.log((1, eval)('abc')); // global scope // eval with a different name var abceval = eval; console.log(abceval('abc')); // global scope var obj = { eval: eval }; console.log(obj.eval('abc')); // global scope }
运算符
在编程语言中,运算符是对操作数执行的操作。基本上,运算符是用于执行各种操作的符号。考虑以下示例:
9 + 11 = 20
在前面的示例中,9 和 11 是操作数,+ 是加法运算符。
概述
与其他语言一样,在 JavaScript 中,存在执行操作的各种运算符,例如加法、乘法、减法等。
在 JavaScript 中,存在不同的运算符,例如:
-
逻辑运算符
-
位运算符
-
条件运算符
-
算术运算符
-
赋值运算符
二元运算符
如其名所示,二元运算符需要两个操作数;例如:
A + B
在这里,A 和 B 是操作数,+ 是执行它们之间加法运算的运算符。
一元运算符
在编程语言中,一元运算符只有一个操作数和与之相关的运算符,例如:
A++;
这也可以写成:
++A;
注意
A++ 是一个后递增运算符。它将首先评估 A,然后递增它;而 ++A 是一个前递增运算符。它递增 A 的值,然后评估表达式。
三元运算符
三元运算符需要三个操作数来执行不同的操作;例如:
<condition> ? <true>: <false>;
在前面的语句中,? 是三元运算符。
算术运算符
在编程语言中,算术运算符用于对值和变量执行算术运算。基本的算术运算如下:
-
+:加法 -
-:减法 -
*:乘法 -
/:除法 -
%:取模运算符 -
++:递增运算符 -
--:递减运算符
这些运算符对数值操作数执行操作,并返回一个数值结果。
在 JavaScript 中,运算符与其他编程语言中的运算符相同;例如,如果你想对变量执行除法运算,那么你应该写成以下形式:
var a=2;
a=(2+a)*1/a;// a=2
console.log(a); // prints 2
注意
在 JavaScript 中,算术运算符是最有用且功能强大的运算符。
+ 运算符
+ 运算符执行两个或更多数字的加法。
返回值
+ 运算符返回数字的加法。
参数
+ 运算符没有参数。
描述
+ 运算符用于将两个数字或两个存储数字的变量相加。
例如:
var a = 3;
var b = 4;
var c = a + b;
Document.Write("The value of c is " + c);
Document.Write(3+1);
这个输出的结果将是:
The value of c is 7
4
注意
此运算符还可以用于连接或连接两个字符串;例如:
document.write("Apple "+"Banana");
输出结果如下:
Apple Banana
- 运算符
- 运算符在两个数字之间执行减法运算。
返回值
- 运算符的结果返回两个数字之间的减法。
参数
- 运算符没有参数。
描述
- 运算符用于减去两个数字或存储数字的两个变量。
考虑以下示例:
var a = 6;
var b = 4;
var c = a - b;
Document.Write("The value of c is " + c);
Document.Write(3-1);
此输出的结果如下:
The value of c is 2
2
* 运算符
* 运算符执行两个或更多数字之间的乘法。
返回值
数字之间乘法的结果。
参数
没有参数。
描述
此运算符用于乘以两个或更多数字或存储数字的两个或更多变量。
考虑以下示例:
var a = 3;
var b = 4;
var c = a * b;
Document.Write("The value of c is " + c);
Document.Write(3*1);
此输出的结果如下:
The value of c is 12
3
/ 运算符
/ 运算符在两个数字之间执行除法。
返回值
数字之间除法的结果。
参数
没有参数。
描述
这也被称为 余数运算符,因为返回的值不是绝对值(即,它保留第一个操作数的符号,而不是第二个操作数的符号)。
考虑以下示例:
var a = 5;
var b = 2;
var c = a % b;
Document.Write("The value of c is " + c);
Document.Write(10%3);
输出结果如下:
The value of c is 1
1
% 运算符
% 模数运算符用于计算余数。
返回值
数字之间乘法的结果。
参数
没有参数。
描述
此运算符用于乘以两个或更多数字或存储数字的两个或更多变量。
考虑以下示例:
var a = 3;
var b = 4;
var c = a * b;
Document.Write("The value of c is " + c);
Document.Write(3*1);
输出结果如下:
The value of c is 12
3
++ 运算符
++ 运算符用于增加一个值。
返回值
结果是递增的值。
参数
没有参数。
描述
增量。增加值并将值存储在自身中。
考虑以下示例:
I = 0; // I contains 0
I++; // this line is equivalent to I = I + 1
此输出的结果如下:
I = 1
-- 运算符
-- 运算符用于递减一个值。
返回值
结果是递减的值。
参数
没有参数。
描述
-- 运算符递减值并将值存储在自身中。
例如:
I = 0; // I contains 0
I--; // this line is equivalent to I = I - 1
输出结果如下:
I = - 1
逻辑运算符
在编程语言中,逻辑运算符是布尔运算符。这些运算符在布尔逻辑上工作。像其他语言一样,JavaScript 在布尔评估上工作。这些布尔运算符总是返回布尔值。任何逻辑运算符都有两种可能的结果:
-
True -
False
以下是在编程语言以及 JavaScript 中使用的逻辑运算符:
-
逻辑与 (
&&) -
逻辑或(
||) -
逻辑非(
!)
注意
算术运算符比逻辑运算符有更高的优先级。
假设,如果有一个表达式,并且其中包含逻辑和算术运算符,那么由于它们的优先级较高,算术运算符将首先被评估。逻辑运算符从左到右工作。
逻辑运算适用于所有内容。一个非布尔值在评估后可以产生一个布尔值。
&& 运算符
&& 运算符是英语单词 "and" 的翻译。例如,如果我们必须写苹果和橙子,我们写 apples && oranges。
返回值
这返回操作数上最具体的价值;如果使用非布尔值,则返回非布尔值。
参数
我们通常用 && 符号分隔要评估的表达式或条件。
描述
这被称为 AND 操作符。
这里是 && 操作符的一个示例:
var a= true && true; // it will be true
var b=true && false;//it will be false
|| 操作符
这个操作符是英语单词 "or" 的翻译。例如,如果我们必须写苹果或橙子,我们写 apples || oranges。
返回
这返回操作数上最具体的价值;如果使用非布尔值,则返回非布尔值。
参数
我们通常用 || 符号分隔要评估的表达式或条件。
描述
这被称为 OR 操作符。
这里是 || 操作符的一个示例:
var a= true || true; // it will be true
var b=true || false;// it will be true
! 操作符
这是 NOT 操作符。NOT 操作符评估值是否不相等。例如:
if(abc != 0){
//if abc is not equal to 0 run this block
}else{
//if abc = 0 then run this block
}
返回
布尔值。
参数
null
描述
这被称为 NOT 操作符。
这里是 ! 操作符的一个示例:
var a=!false //it will print true
var b=!true //it will print false
注意
在 JavaScript 中,这些逻辑操作符用于条件语句和 while 循环中。
赋值操作符
在 JavaScript 中,赋值操作符用于将值赋给变量。赋值操作符 = 将其右侧操作数的值赋给其左侧的操作数。例如,abc = xyz,在这里 xyz 是右侧操作数,其值被赋给 abc,即左侧操作数。赋值操作符可以将单个变量的值赋给多个变量。在以下各节中,我们将讨论 JavaScript 中的赋值操作符。
= 操作符
= 操作符用于将值赋给变量。
返回
没有参数,但它用于两个或多个操作数之间。
参数
没有参数。
描述
这是所有赋值操作符中最简单的一个,并且被广泛使用。它将右侧操作数的值赋给左侧操作数。
考虑以下示例:
var x=2;
console.log("The value of x is " + x);
这个输出的结果将是:
The value of x is 2
+= 操作符
这个操作符被称为加法赋值操作符。
返回
这将值加到变量上,并返回加法的结果。
参数
没有参数。
描述
加法赋值操作符用于在单个操作中将值加到变量上,并将值赋给另一个或相同的变量。
考虑以下示例:
var abc = 2;
abc += 10;
console.log(abc); //12
这是 abc = abc + 10 的简写。
-= 操作符
这个操作符被称为减法赋值操作符。
返回
这个操作符从变量中减去给定的值,并返回减法的结果。
参数
没有参数。
描述
-= 操作符用于从变量中减去一个值,并在同一操作中将给定的值赋给另一个或相同的变量。
考虑以下示例:
var abc = 10;
abc -= 2;
console.log(abc); //8
这是 abc = abc - 2 的简写。
*= 操作符
这个操作符被称为乘法赋值操作符。
返回
这将变量和值相乘,并返回乘法的结果。
参数
没有参数。
描述
此操作符用于将一个值与变量相乘,并在同一操作中将结果赋给另一个或相同的变量。
考虑以下示例:
var abc = 5;
abc *= 5;
console.log(abc); //25
这是一种简写形式,相当于 abc = abc * 5。
/= 操作符
这个操作符被称为除法赋值操作符。
返回值
它将变量除以右操作数的值,并将结果赋给变量。
参数
没有参数。
描述
此操作符用于将变量除以值,并将结果赋给变量。
考虑以下示例:
var abc = 5;
abc /= 5;
console.log(abc); //1
这是一种简写形式,相当于 abc = abc / 5。
%= 操作符
%= 操作符也称为余数赋值操作符。
参数
%= 操作符接受一个空参数。
返回值
%= 操作符返回余数。
描述
它将变量除以右操作数的值,并将余数赋给变量。例如:
var abc = 10;
abc %= 3;
console.log(abc); //1
这是一种简写形式,相当于 abc = abc % 3。
注意
这是一个实验性技术,是 ECMAScript 2016(ES7)提案的一部分。
幂赋值(=)
此操作符返回左操作数幂的值,其幂为第二个操作数的值。
var abc = 5;
abc **= 2;
console.log(abc); //25
这是一种简写形式,相当于 abc = abc ** 2。
关系操作符
在编程语言中,关系操作符也称为比较操作符。这些操作符显示两个值的相对顺序。以下各节将介绍这些比较操作符。
< 操作符
<(小于)操作符用于比较表达式两边的值,并检查操作符左边的值是否小于操作符右边的值。
返回值
如果前面的条件为真,则表达式返回 true,否则返回 false。
参数
在这里,两个操作数必须是数字或两者都必须是字符串。
描述
这也被称为小于操作符。
下面是一个使用此操作符的简单示例:
if(2<3) { //returns true
//block of code
}
<= 操作符
<= 操作符用于比较表达式两边的值,并检查操作符左边的值是否小于或等于操作符右边的值。
返回值
如果前面的条件为真,则它返回布尔值 true,否则返回 false。
参数
在这里,两个操作数必须是数字或两者都必须是字符串。
描述
这也被称为小于等于操作符。
下面是一个使用此操作符的简单示例:
if(2 <= 3) { //returns true
//block of code
}
> 操作符
> 操作符用于比较表达式两边的值,并检查操作符左边的值是否大于操作符右边的值。
返回值
如果前面的条件为真,则它返回布尔值 true,否则返回 false。
参数
在这里,两个操作数必须是数字或两者都必须是字符串。
描述
这也被称为大于操作符。
使用此操作符的一个简单示例如下:
if(2>3) { //returns false
//block of code
}
>= 操作符
>= 操作符用于比较表达式两边的值,并检查操作符左边的值是否大于或等于操作符右边的值。
返回值
如果前面的条件为真,则返回布尔值 true,否则返回 false。
参数
这里,两个操作数必须是数字或两者都必须是字符串。
描述
这也被称为大于或等于操作符。
使用此操作符的一个简单示例如下:
if(3 >= 3) { //returns true
//block of code
}
!= 操作符
!= 操作符用于比较表达式两边的值,并检查操作符左边的值是否不等于操作符右边的值。
返回值
如果前面的条件为真,则返回布尔值 true,否则返回 false。
参数
这里,两个操作数必须是数字或两者都必须是字符串。
描述
这也被称为不等于操作符。
使用此操作符的一个简单示例如下:
if(2!=3) { //returns true
//block of code
}
== 操作符
== 操作符用于比较表达式两边的值,并检查操作符左边的值是否等于操作符右边的值。
返回值
如果前面的条件为真,则返回布尔值 true,否则返回 false。
参数
这里,两个操作数必须是数字或两者都必须是字符串。
描述
这也被称为等于操作符。
使用此操作符的一个简单示例如下:
if(2==3) { //returns false
//block of code
}
=== 操作符
=== 操作符用于比较表达式两边的值,并查看操作符左边的值是否等于操作符右边的值,同时也要检查两个操作数是否为同一数据类型。
返回值
如果前面的条件为真,则返回布尔值 true,否则返回 false。
参数
=== 操作符接受参数 null。
描述
这也被称为值相等且类型相等操作符。
使用此操作符的一个简单示例如下:
if(3 === 3) { //returns true
//block of code
}
if(3 === "3") { //returns false
//block of code
}
语句
JavaScript 在一组语句上工作。这些语句具有适当的语法,语法取决于语句包含的内容。一个语句可以包含多行。基本上,一个语句是一组给计算机浏览器执行 JavaScript 代码的指令。一个语句可以用分号结束,并返回一个值。一个语句可以是一个对特定动作的调用,例如:
Document.Write("hello world");
前面的语句调用了内置的 Write() 函数,并在屏幕上打印了消息 hello world。
我们可以在一行中写多个语句,用分号分隔;例如:
var a=20; var b=2;var c=a*b; document.write(c);
语句也可以用换行符结束,例如:
var a=20;
Document.Write(a);
JavaScript 中的每个语句都按照 JavaScript 程序中给出的指令顺序依次执行。
表达式语句
在 JavaScript 中,语句和表达式之间有一个区别。每当在脚本或代码中期望一个值时,表达式通过语句产生这个值。
表达式由字面量、变量、运算符和方法组成。返回值的数据类型取决于表达式中使用的变量。我们可以根据数据类型从一组较小的表达式中创建一个复合表达式。
x = Math.PI;
cx = Math.cos(x);
alert("cos(" + x + ") = " + cx);
语句基本上是在脚本中执行的动作,例如循环和if-else在 JavaScript 中都是语句。无论 JavaScript 期望一个语句还是表达式,都可以称为表达式语句。它既满足语句的功能,也满足表达式的功能。但这是不可逆的。我们不能在 JavaScript 期望表达式的地方写一个语句。例如,if 语句不能用作函数的参数。
为了防止这种情况发生,JavaScript 不允许我们将函数表达式和对象字面量用作语句,也就是说,表达式语句不应该以下列方式开始:
-
大括号
-
关键字
function
复合空语句
复合语句是一组用大括号括起来的语句,所有这些语句都由分号分隔。它将程序中的多个语句组合成一个单一的语句。复合语句也称为块语句。
这种类型的语句通常与条件语句如if、else、for、while循环等一起使用。考虑以下例子:
if(x<10) // if x is less than 10 then x is incremented {
x++;
}
空语句是复合语句的反面。空语句中没有语句,只有一个分号。这个分号意味着不会执行任何语句。通常,空语句用于需要在代码中添加注释的情况。考虑以下例子:
for(i=0; i<10; i++)
{} /* Empty */
声明语句
这个语句用于在 JavaScript 中声明变量或函数。
function
在 JavaScript 中,function关键字用于在程序中声明一个函数。
这里有一个简单的例子,其中声明了myFunction函数:
function myFunction() {
//block of code
}
var
在 JavaScript 中,要声明一个变量,我们使用var关键字。在使用变量之前,我们需要声明它。
考虑以下例子:
var a =5;
var b = 23.5;
var c = "Good morning";
下面是一个同时使用var和function的例子:
var a=2;
var b=3;
function Addition(x,y) {
return x+y;
}
var c= Addition(a,b)
Document.Write("The value of c is " + c)
前述代码的输出将如下所示:
The value of c is 5
条件语句
在 JavaScript 中,当我们想要对不同的语句执行不同的操作时,我们使用条件语句。这些是一组根据不同条件执行不同操作的命令。在 JavaScript 中,有三种类型的条件语句,如下所示:
-
if -
else -
switch
基本上,这些语句显示了代码的流程。条件语句控制程序的流程,即根据哪个条件执行哪个操作。
考虑一个例子,假设你有一个电子商务网站,并且你想要在产品有特别优惠时显示一个优惠标签。在这种情况下,你可以在条件语句中放置适当的代码。
If 语句
在编程语言中,if 语句是一个控制语句。if 语句有两个重要的部分:
-
条件
-
执行动作的代码
在 JavaScript 和其他语言中,if 语句根据变量和数据类型做出决策。例如,如果你编写一个脚本要求在生日时通知你,那么当时间到来时,将显示消息 "今天是你的生日"。
只有当条件为 true 时,if 语句才会执行。如果表达式是 false,则不会执行。
语法
这里是 JavaScript 中 if 语句的语法:
if(condition) {
// block of code
}
示例
例如,在 JavaScript 中,我们可以这样编写一个 if 语句代码:
var cAge=25;
If (cAge>18) {
document.write ("You must have CNIC");
}// if age is above 18 it displays that you must have a CNIC
Else if 语句
在 JavaScript 中,可能会有一些情况,我们需要根据不同的可能性做出决定。else if 语句只有在前面的语句为 false 且其条件为 true 时才会执行。else if 语句有两个主要点,如下:
-
在任何
else if语句之前都应该有一个if语句 -
你可以使用任意数量的
else if语句,但最后必须有一个else语句。
语法
这里是 JavaScript 中简单 if 语句的语法:
if(condition 1) {
// block of code
}
else if(condition 2) {
//block of code
}
else {
// block of code
}
在前面的语法中,可以检查两个条件是否有效。
这里是 JavaScript 中稍微复杂一点的 else if 语句的语法:
if(condition 1) {
// block of code
}
else if(condition 2) {
// block of code
}
else if(condition 3) {
// block of code
}
else {
// block of code
}
在前面的语法中,可以检查三个条件是否有效。
示例
例如,如果你有一个网页,并且你想检查谁在访问该网页。你将在 Else if 语句的脚本中放置两个自定义消息。你将这样编写它们:
var person="Manager";
If(person=="Admin") {
Document.Write("I am visiting it");
}
Else if(person=="Manager") {
Document.Write("I am accessing it");
}
Else {
document.write("hello kitty");
}
Else if 语句是 JavaScript 中最先进的语句形式之一。它在检查所有 if 条件后做出决定。它是一种复杂的语句类型,其中每个 if 都是 else 语句的一部分。所有条件都必须在 else if 关键字后面的括号内为 true。如果任何条件为 false,则执行 else 部分。
Switch 语句
在编程语言中,switch语句的执行仅取决于表达式的值。有多个情况列表,对这些情况进行检查。检查是顺序进行的;JavaScript 解释器检查第一个情况及其条件,以检查它是否为true。同样,对所有的case语句进行检查,以检查它们的条件是否为true,并找到break语句。当解释器遇到break语句时,它退出switch循环。break语句的目的是确保一旦执行了一个case,switch语句就返回控制权给调用函数,解释器不会将控制权传递给下一个适用的case。
语法
这里是 JavaScript 中简单switch语句的语法:
switch(condition/expression)
case expression 1:
//block of code
break;
case expression 2:
//block of code
break;
case expression 3:
//block of code
break;
default:
//block of code
break;
示例
下面是一个有效的switch语句的示例:
Switch (personName)
case "Jack":
alert("my name is Jack");
Break;
case "Ahmed":
alert("my name is Ahmed");
break;
default:
alert("my name is Talha");
break;
如果前面的代码没有找到匹配的情况,则执行默认语句。基本上,switch语句是一个表达式,它根据某些条件评估不同的语句以执行某些代码。
循环
在编程语言中,循环用于根据条件执行代码块多次。例如,如果你有一个语句并且想要反复执行它,你只需将其放入循环中。循环基本上用于重复性任务。
另一个循环的特定例子是,如果你想遍历一个数组以找到特定的数字,你必须遍历数组元素。每次迭代将获取下一个数组索引。
JavaScript 中有四种类型的循环,如下所示:
-
for -
while -
do-WHILE -
for-in
对于重复性任务,我们将一系列指令放入循环中。为了控制循环执行的次数,我们使用循环中的控制变量来增加或减少迭代器或计数器的值,这将重复执行代码块。你还可以在循环中使用break和continue语句。
循环
for循环用于循环遍历或执行代码块,直到条件返回false结果。在for循环中,我们说明脚本应该执行多少次。例如,你可能想要执行你的脚本 12 次。
语法
JavaScript 中的for循环与其他语言(如 C、C++和 Python)中的for循环相同。for循环的语法有三个重要部分:
-
初始化:这是循环初始化计数器变量的地方。这是循环开始执行时的第一条语句。
-
条件:这是一个在每次循环迭代之前要评估的表达式。如果条件满足且为
true,我们进入循环;否则,如果条件不满足且返回false,则退出for循环。 -
增量/减量:这用于迭代和增加或减少计数器变量的值。这是一个更新语句,其中执行增量或减量。
for (initialization; condition; increment / decrement) { //code block }
示例
考虑以下 JavaScript 中基本计数器代码的示例:
var i; // declares the variable i
for(i=1; i < 5 ; i++) {
Document.Write("basic counter:"+i);
Document.Write("<br/>");
}
输出将如下所示:
Basic counter:1
Basic counter:2
Basic counter:3
Basic counter:4
while循环
这也是 JavaScript 中常用的一个循环。while循环在条件为true的情况下重复执行一系列语句,直到条件变为false。当条件变为false时,循环退出。
语法
下面是 JavaScript 中while循环的语法:
while (condition expression) {
// code block
}
while循环有两个部分:
-
条件语句
-
用大括号编写的
while循环代码
为了使循环工作,必须满足while循环的条件。如果条件中断,则循环中断。
示例
下面是while循环的一个示例,它将打印出从1到4的数字:
var count= 0;
While(count<5) {
Document.Write("count");
Document.Write("<br/>");
count++;
}
输出将如下所示:
1
2
3
4
do while循环
do while循环也称为后测试循环,因为它首先执行语句,然后检查条件。如果条件为true,则进入循环;如果条件为false,则跳出循环。
语法
下面是 JavaScript 中do while循环的语法:
Do {
//statement
}
While(condition);
do while循环有两个重要部分:
-
语句
-
条件
do while循环与while循环类似,但它是在循环的末尾检查条件。do while循环至少执行一次指定的语句,然后再检查条件。
示例
下面是一个do while循环的示例,它会打印出1到5的值:
var i=1;
Do {
document.write("The value of i is " + i + "</br>");
i++;
}
While(i<6);
输出将如下所示:
The value of i is 1
The value of i is 2
The value of i is 3
The value of i is 4
The value of i is 5
小贴士
do while循环可以在我们需要至少执行一次循环,无论条件是否满足的情况下使用。
for in循环
在 JavaScript 中,还有一种循环类型,称为for in循环。这个循环用于 JavaScript 中的对象属性。在这个循环中,对象的一个属性被分配给一个变量名。
语法
下面是 JavaScript 中for in循环的语法:
For (property in object) {
//code block
}
示例
下面是for in循环的一个示例:
var I;
For (I is navigator) {
Document.Write(i);
}
Document.Write("The loop ends here");
跳转和标签语句
在 JavaScript 中,jump语句用于强制执行流程跳转到脚本中的另一个条件。基本上,它用于终止迭代语句。JavaScript 中有两种jump语句:
-
Break -
继续
这些语句用于当你立即离开循环或因为代码中的条件而想要提前跳转到另一个条件时。
break语句
在 JavaScript 中,break语句与switch语句一起使用。它用于提前退出循环或条件。break语句也用于for循环和while循环中。
语法
下面是 JavaScript 中break语句的语法:
Any loop(condition) {
//block of code that will be executed
break;
//block of code that won't get executed
}
示例
考虑以下简单示例:
var i=1;
While(i<10) {
if(i==3) {
Document.Write("Breaking from if loop");
Break;
}
Document.Write("The value of i is " + i);
i+=2;
}
输出将如下所示:
The value of i is 1
Breaking from if loop
The value of i is 3
continue语句
关键字continue将跳过当前迭代。
语法
下面是 JavaScript 中continue语句的语法:
Any loop(condition) {
//block of code that will be executed
Any loop (condition) {
//block of code that will be executed
continue;
block of code that wont be executed
}
//block of code that will be executed
}
示例
考虑以下简单示例:
var i=1;
While(i<5) {
if(i==3) //skip the iteration {
Document.Write("Continue statement encountered");
continue;
}
Document.Write("The value of i is " + i);
i=i+2;
}
输出将如下所示:
The value of i is 1
Continue statement encountered
return语句
在 JavaScript 中,return 语句用于从函数中返回一个值。返回值后,它停止函数执行。每个函数和语句都返回一个值。如果没有提供 return 语句,则返回未定义值。
语法
下面是 JavaScript 中 return 语句的语法:
function myfunc(x, y) {
//some block of code
return x;
}
Document.Write("The result is " + myfunc(2, 3));
示例
考虑以下简单示例,展示 return 语句的工作原理:
Function multiply(a,b) {
return a*B;
}
var mul=multiply(2,3);
Document.Write("The result is "+ mul);
输出结果如下:
The result is 6
抛出语句
throw 语句用于为 try 和 catch 块创建用户定义的错误条件。这些错误也称为 异常。我们可以在代码脚本中创建自己的异常。
语法
下面是 JavaScript 中 throw 语句的语法:
try {
//block of code
throw "error";
//block of code
}
catch(error) {
//block of code
}
示例
让我们看看以下代码片段:
Try {
document.write( "hello world);//the code will throw an error due to the missing "
}
Catch(error) {
Error.messageTxt;
}
Try catch finally 语句
在 try 语句中,我们编写在执行时需要错误测试的代码。在 catch 块中,你编写处理 try 块中发生的错误的代码。当你将代码写入 try 块中时,你必须编写一个 catch 块来处理 try 块中可能发生的任何错误。当 try 和 catch 语句成功执行时,finally 语句执行。
语法
try、catch 和 finally 块的语法如下所示:
Try {//generate exception}
Catch {//error handling code}
Finally {//block of code which runs after try and catch}
数组
数组用于存储有序数据集合。如果我们有多个项目,则可以使用数组来存储这些值。数组原型方法用于在 JavaScript 中执行变异操作。数组没有固定长度。数组可以包含多个值类型,并且可以在初始化后任何时刻修改项目数量。
数组类型
在 JavaScript 中有两种数组类型:
-
名义类型:这种类型的数组具有唯一的标识。
-
结构类型:这种数组类型看起来像接口;它也被称为鸭子类型。它使用特定行为的具体实现。
注意
稀疏数组
在编程语言中,稀疏数组表示具有相同值(如 0 或 null)的数组。在数组存储中存在大量零,这在稀疏数组中发生。在稀疏数组中,索引不从 0 开始。在稀疏数组中,元素的长度小于属性的长度。
在 JavaScript 中,length 属性不是数组中实际元素的数量,而是最后一个 索引+1。因此,在稀疏数组的情况下,这一点至关重要,需要处理空白索引。考虑以下示例:
var person=[];
Person[1]="Ali";
Person[20]="Ahmed";
Alert(person.length);// it will be 21 length
数组类型对象
一些 JavaScript 对象看起来像数组,但实际上它们不是数组。它们被称为 类似数组 对象。
类似数组的对象:
-
具有:这告诉你对象有多少个元素
-
不具有:这些是数组方法,例如
indexOf、push和forEach
注意
字符串作为数组
在 JavaScript 中,有一些字符串表现得像数组。如果我们把一个字符串当作数组,那么它就只能被当作数组。数组中有些方法,如push()、reverse()等,在字符串上不起作用。
创建数组
在 JavaScript 中,有两种创建数组的方法:
-
使用数组初始化器
-
使用数组构造函数
您可以使用这两种方法中的任何一种。
数组初始化器中有一个用方括号括起来的逗号分隔的字符串;例如:
var students= ["Ali","Ahmed","Amina"];
在 JavaScript 中,您也可以使用数组构造函数通过使用 new 关键字来创建一个数组,这会创建一个数组并将值赋给它;例如:
var students=new Array ("Ali,"Ahmed","Amina");
提示
数组初始化器方法是一种快速且好的初始化数组的方法,因为它的执行速度比构造函数方法要高。如果您在数组构造函数中不传递任何参数,那么它将设置其长度为零。
数组初始化器
数组用于在单个变量中存储有序数据集合。这意味着当您想要存储一个项目列表时,应该使用数组。在您的程序中使用数组之前,您需要首先初始化它。
在数组初始化器中,有一个变量中存储的项目逗号分隔列表,例如:
var a1=[];
var a2=[2];
var a3=[1,2,3];
var a4=['hi', [2]];
提示
当您使用数组初始化器初始化数组时,所有项的类型不必相同。此外,数组可以有零长度。
数组构造函数
您可以使用数组构造函数的以下三种不同方式。它们的语法如下:
var a1=new array(); // new empty array
var a2=new array(2); // new array of size 2
var a3= new array(1,2,3); // new array containing 1, 2, 3
如果您不带参数调用数组构造函数,它将设置其长度为零。
如果数组构造函数只有一个参数,则此参数将初始化其新长度。
如果您调用一个包含两个或更多元素的数组,参数将初始化一个大小等于参数数量的数组。
读取和写入数组元素
要从数组中读取和写入元素,我们使用方括号[]。它就像访问对象属性一样工作。在括号内应该是一个非负数。在数组中读取和写入的语法是相同的。值也在数组中索引。您通过索引读取值。数组的引用应该在括号的左侧。
考虑以下示例:
var obj=["abc"];
var start=obj[0]; //its is for reading
Document.Write(start);
var obj[1]="hello";
i="world";
Obj[i]="hello world";//writing
Document.Write(obj[i]);
此输出的结果如下:
Hello world
JavaScript 中的多维数组
与其他编程语言一样,您也可以在 JavaScript 中创建多维数组。它们的语法与其他语言相同。在多维数组中,您在嵌套数组循环中创建数组内的数组。
您可以通过为每个需要的维度添加更多数组来创建一个数组。当您需要用信息覆盖整个存储空间时,创建多维数组很有用。如果大部分数据是稀疏的,也就是说数组是空的,那么使用关联数组来存储信息是一种更好的技术。以下是在 JavaScript 中创建多维数组的示例:
var a=5;
var b=2;
var c=new array();
For(i=0;i<5;i++) {
C[i]=new array();
for For(j=0;j<5;j++)
c[i][j]; }}
}
数组中的属性
数组具有原型、长度和构造器作为其属性。
长度
在 JavaScript 中,数组长度属性返回数组中的元素数量。
返回值
这返回一个 32 位整数值。
描述
我们还可以在需要时使用数组长度属性来清空数组。当你增加任何数组的长度时,它不会增加其中的元素数量。我们可以使用数组长度属性设置或返回任何数组的长度。
考虑以下示例:
var num=new Array[1,2,3];
Document. write (num.length);
输出将如下所示:
3
构造器
数组构造器用于初始化一个数组。一个数组可以包含零个或多个元素,其语法如下,其中数组元素由方括号内的逗号分隔。
var fruits = ["Apple", "Banana"];
原型
所有数组实例都从 Array.prototype 继承。数组的原型构造器允许向 Array() 对象添加新方法和属性。
Array.prototype is an array itself.
Array.isArray(Array.prototype); // true
你可以在 MDN 上找到有关如何进行这些更改的详细信息(developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype)。
数组方法
有几种方法可以对数组执行以获得不同的结果。其中一些方法在以下章节中定义。
concat()
concat() 方法在两个数组之间执行连接操作。
返回值
concat() 方法返回连接后的数组。
参数
concat() 方法接受一个要连接的字符串。
描述
这需要两个数组并将它们连接起来。
var alpha = ['a', 'b', 'c'],
var numeric = [1, 2, 3];
var alphaNumeric = alpha.concat(numeric);
console.log(alphaNumeric); // Result: ['a', 'b', 'c', 1, 2, 3]
every()
every() 方法对每个数组元素测试一个函数。
返回值
every() 方法返回布尔值 true 或 false。
参数
在数组的每个元素上应用的一个回调函数。
描述
如果数组中的每个元素都提供了测试函数,则它返回 true。
function isBigEnough(element, index, array) {
return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough); // false
[12, 54, 18, 130, 44].every(isBigEnough); // true
foreach()
foreach() 方法对数组中的每个元素执行一个作为参数传递的函数。
返回值
每个函数的输出。
参数
一个回调函数,用于调用数组的每个元素。
描述
foreach() 方法调用每个元素的函数:
function logArrayElements(element, index, array) {
console.log('a[' + index + '] = ' + element);
}
// Note elision, there is no member at 2 so it isn't visited
[2, 5, , 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[3] = 9
join()
这将所有元素连接成一个字符串。
返回值
一个连接的字符串。
参数
Null 或一个分隔符,用于在数组元素之间放置。
描述
它将所有元素连接成一个字符串。
var a = ['One', 'Two', 'Three'];
var var1 = a.join(); // assigns 'One,Two,Three' to var1
var var2 = a.join(', '); // assigns 'One, Two, Three' to var2
var var3 = a.join(' + '); // assigns 'One + Two + Three' to var3
var var4 = a.join(''); // assigns 'OneTwoThree' to var4
pop()
pop() 方法移除数组的最后一个元素,就像一个栈。
返回值
pop() 方法返回一个 null 参数。
参数
pop() 方法接受 null 参数。
描述
它移除数组的最后一个元素,就像一个栈。
var myColours = ['Yellow', 'Black', 'Blue', 'Green'];
console.log(myColours); // ['Yellow', 'Black', 'Blue', 'Green']
var popped = myColours.pop();
console.log(myColours); // ['Yellow', 'Black', 'Blue' ]
console.log(popped); // 'Green'
push()
它在数组的最后一个索引上添加元素。
返回值
null。
参数
null。
描述
这在数组的最后一个索引上添加元素。
var sports = ['cricket', 'baseball'];
var total = sports.push('football');
console.log(sports); // ['cricket', 'baseball', 'football']
console.log(total); // 3
indexOf()
indexOf() 方法返回数组的第一个索引。
返回值
indexOf() 方法返回一个索引。
参数
indexOf() 方法接受一个数组元素作为参数。
描述
它返回数组的第一个索引。
var array = [2, 5, 9];
array.indexOf(9); // 2
array.indexOf(7); // -1 if not found
lastIndexOf()
lastIndexOf() 方法返回给定元素在数组中最后一次出现的位置索引。
返回值
它返回数组的最后一个索引。
参数
数组元素。
描述
var array = [2, 5, 9, 2];
array.indexOf(2); // 3
array.indexOf(7); // -1 if not found
reverse()
reverse() 方法反转数组中所有元素的顺序。
返回值
数组。
参数
null。
描述
reverse() 方法反转数组中元素的顺序。第一个元素变为最后一个元素,依此类推。
var myArray = ['one', 'two', 'three'];
myArray.reverse();
console.log(myArray) // ['three', 'two', 'one']
shift()
在数组中,shift() 方法移除并返回第一个元素。
返回值
null。
参数
null。
描述
在数组中,它移除并返回第一个元素。
var myColours = ['Yellow', 'Black', 'Blue', 'Green'];
console.log(myColours); // ['Yellow', 'Black', 'Blue', 'Green']
var shifted = myColours.shift();
console.log(myColours); // ['Black', 'Blue', 'Green']
console.log(shifted); // 'Green'
unshift()
此方法在数组的开头添加一个新元素,并返回新的数组长度。
返回值
数组的新长度。
参数
要添加到数组中的元素。
描述
此方法在数组的开头添加一个新元素,并返回新的数组长度:
var arr = [1, 2, 3];
arr.unshift(0); // arr is [0, 1, 2, 3]
slice()
slice() 方法将数组切片到一个新数组。
返回值
新的切片数组。
参数
要切片的元素索引。
描述
此方法将数组切片到一个新数组:
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);
// citrus contains ['Orange','Lemon']
splice()
splice() 方法也通过移除现有元素来向数组中添加新元素。
返回值
新的切片数组。
参数
要移除的元素索引和要添加的元素。
描述
此方法也通过移除现有元素来向数组中添加新元素:
var myCars = ['Audi', 'BMW', 'Ferrari', 'Volkswagen'];
// removes 0 elements from index 2, and inserts 'Toyota'
var removed = myCars.splice(2, 0, 'Toyota');
// myCars is ['Audi', 'BMW', 'Toyota', 'Volkswagen']
// removed is [], no elements removed
sort()
此方法按字母顺序对数组进行排序。
返回值
null。
参数
null。
描述
作为数组方法调用,此方法按字母顺序(Unicode 字符)对数组进行排序,并且与数字不兼容:
var fruit = ['cherries', 'apples', 'bananas'];
fruit.sort(); // ['apples', 'bananas', 'cherries']
toString()
toString() 方法将对象转换为字符串。
返回值
toString() 方法返回一个字符串。
参数
toString() 方法接受一个 null 参数。
描述
将数组对象转换为以逗号分隔的字符串。
var monthNames = ['Jan', 'Feb', 'Mar', 'Apr'];
var myVar = monthNames.toString(); // 'Jan,Feb,Mar,Apr' to myVar.
ECMA5 数组方法
新增的数组方法被添加到 ECMA5 脚本中,也称为 数组扩展。这些是九个新方法。这些方法执行与数组相关的常见操作。这些新方法将在以下章节中介绍。
array.prototype.map()
map() 方法根据每次迭代的返回值创建一个新数组。
返回值
修改后的数组。
参数
回调函数。
描述
它遍历数组,运行一个函数,并根据每次迭代的返回值创建一个新数组。它接受与 forEach() 方法相同的参数。
这里有一个简单的例子:
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
根现在如下所示:
[1, 2, 3]
array.prototype.filter()
filter() 函数创建一个新数组或修改后的数组,该数组包含通过函数处理的值。
返回值
修改后的数组。
参数
回调函数。
描述
它创建一个新数组,仅包含那些回调返回 true 的元素。
以下是一个简单的示例:
function isBigEnough(value) {
return value >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
输出如下:
[12, 130, 44]
array.prototype.reduce()
reduce() 函数同时将一个函数应用于数组的两个值,以将它们减少到一个单一值。值的选取方向是从左到右。
返回值
修改后的数组。
参数
一个回调函数。
描述
array.prototype.reduce() 方法通过在回调函数中执行的操作,将数组的所有值累积到一个单一值。
以下是一个简单的示例:
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
});
回调的执行方式如下:
| previousValue | currentValue | index | array | return value | |
|---|---|---|---|---|---|
| 第一次调用 | 0 |
1 |
1 |
[0, 1, 2, 3, 4] |
1 |
| 第二次调用 | 1 |
2 |
2 |
[0, 1, 2, 3, 4] |
3 |
| 第三次调用 | 3 |
3 |
3 |
[0, 1, 2, 3, 4] |
6 |
| 第四次调用 | 6 |
4 |
4 |
[0, 1, 2, 3, 4] |
10 |
array.prototype.forEach()
array.prototype.forEach() 方法对数组中的每个元素执行一个作为参数传递的函数。
返回值
每个函数的输出。
参数
一个要为数组每个元素调用的回调函数。
描述
array.prototype.forEach() 方法调用每个元素的函数。以下是一个简单的示例:
function logArrayElements(element, index, array) {
console.log('a[' + index + '] = ' + element);
}
// Note elision, there is no member at 2 so it isn't visited
[2, 5, , 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[3] = 9
array.prototype.indexOf()
array.prototype.indexOf() 方法返回数组的第一个索引。
返回值
一个索引。
参数
一个数组元素。
描述
array.prototype.indexOf() 方法返回数组的第一个索引。以下是一个简单的示例:
var array = [2, 5, 9];
array.indexOf(9); // 2
array.indexOf(7); // -1 if not found
array.prototype.lastIndexOf()
array.prototype.lastIndexOf() 方法返回给定元素在数组中找到的最后一个索引。
返回值
它返回数组的最后一个索引。
参数
一个数组元素。
描述
如前所述,如果数组中存在指定的元素,array.prototype.lastIndexOf() 函数将返回该元素的最后一个索引。以下是一个简单的示例:
var array = [2, 5, 9, 2];
array.indexOf(2); // 3
array.indexOf(7); // -1 if not found
array.prototype.every()
array.prototype.every() 方法对每个数组元素进行函数测试。
返回值
一个布尔值 true 或 false。
参数
一个要应用于数组每个元素的回调函数。
描述
如果数组中的每个元素都提供了测试函数,则返回 true。以下是一个简单的示例:
function isBigEnough(element, index, array) {
return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough); // false
[12, 54, 18, 130, 44].every(isBigEnough); // true
array.prototype.some()
此方法测试是否有任何元素通过了由提供的函数实现的测试。
返回值
一个布尔值 True 或 False。
参数
一个回调函数。
描述
array.prototype.some() 方法与 Array.prototype.every() 类似,但这里的条件是至少有一个回调应该返回 true。
一个简单的示例如下:
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
array.prototype.reduceRight()
array.prototype.reduceRight() 方法从右到左同时应用一个函数到数组的两个值(值),以便将它们减少到一个单一值。
返回值
修改后的数组。
参数
一个回调函数。
描述
这与 reduce 操作完全相同,但它从右侧开始,向左侧移动,同时累积值。
这里有一个简单的例子:
var total = [0, 1, 2, 3].reduceRight(function(a, b) {
return a + b;
});
这返回总和为6。
第十章。JavaScript 面向对象编程
JavaScript 是一种面向对象的编程语言。在面向对象编程(OOP)语言中,我们使用对象的概念而不是动作来开发应用程序。在过去,JavaScript 没有真正的基础,仅仅是一种基本语言。JavaScript 不是像 JAVA、C#和其他编程语言那样完全基于 OOP 的语言,但它仍然具有许多 OOP 特性。
在 JavaScript 中有许多代码重用的特性。因此,而不是在 JavaScript 中使用过程式概念,我们使用面向对象编程技术。面向对象编程有四个基本原则。
多态性
由于 JavaScript 是一种动态语言,它支持多态性。多态性可以理解为对象在不同时间可以表现出不同的能力。例如,一个形状可以是正方形、长方形或圆形。
封装
这个特性在 JavaScript 中也得到了支持。这意味着保护代码的一部分不被外部使用。它保护了与最终用户无关但运行应用程序很重要的代码部分,例如在存储密码的应用程序中。用户不需要知道他们的密码是如何加密的。因此,这段代码被封装起来。
继承
在 JavaScript 中,继承可以用来从父对象推导出属性到子对象,并且它们自己也有一些独特的属性。例如,一个正方形和一个三角形可能从shape对象继承它们的边框或填充,同时拥有自己独特的顶点数。
抽象
抽象在 JavaScript 中不是原生支持的,但有一些方法可以通过组合多态性和继承来实现这一点。
对象
对象是理解面向对象编程的基本关键。编程对象就像现实世界中的对象一样。看看周围,你会看到很多对象。你的汽车、手机、桌子、笔记本电脑、宠物狗和 DVD 播放器都是对象。
所有对象都有两个特性:属性和方法。
一部手机有属性(颜色、屏幕尺寸、高度和重量)和方法(打电话、发送短信、接收电话和传输文件)。
一辆车有属性(颜色、高度、变速箱、车轮、引擎、刹车和方向盘)和方法(启动引擎、转向、换挡、刹车、停止和碰撞)。
正如这些现实世界的例子一样,OOP 中的对象具有相同的特性。因此,从编程的角度来看,一个对象可以具有属性(任何编程语言中的变量)和方法(任何编程语言中的函数)。因此,我们可以将对象定义为“一个具有一些属性和与之关联的方法的实体或事物。对象可以被单独选择和处理”。
所有通用属性和方法都被组合到一个称为类的模板中。然后,这个类被用作模板来实例化单个或多个对象。在 JavaScript 中,有许多内置对象,例如 Maths、Dates、正则表达式、数组等等。
创建对象
在 JavaScript 中,我们可以以三种不同的方式创建对象:
-
使用对象字面量
-
使用
new关键字 -
使用
object.create()方法(ECMAScript 5)
对象字面量
这是创建对象的最简单方式。可以使用对象字面量在一个语句中创建和定义一个对象。对象字面量是一个逗号分隔的name:value(如 year:1990, age:25)对列表,这些对被大括号包围。
下面是一个例子:
var car= {
model:"2014",
company:"Honda",
color:"White"
};
在前面的例子中,我们创建了一个具有四个属性或属性的car对象。
var empty = {}
另一方面,这段代码创建了一个没有任何属性的空对象。
new关键字
new关键字用于创建和初始化一个新对象。new关键字总是跟在一个函数调用之后。这个函数被称为构造函数,它初始化新创建的对象。JavaScript 包含用于原生类型的内置构造函数。
下面是一个例子:
var car = new Object();
car.model = "2014";
car.company = "Honda";
car.colour = "White";
前面的例子也创建了一个具有四个属性的新的car对象:
varempty = new Object(); // An empty object, same as {}.
vararr = new Array(); // An empty array, same as [].
varcurrdate = new Date(); // Current Date.
varregex = new RegExp("JavaScript"); // A pattern matching object.
object.create()方法
object.create()方法最初是在 ECMAScript 5 中定义的。它也被用来创建对象。传递给这个方法的第一个参数是那个对象的原型。第二个参数是可选的。它描述了对象的属性。
下面是一个例子:
// obj1 inherits properties model, company and colour.
varcar = Object.create({model:"2014",company:"Honda",colour:"White"});
// car inherits no properties or methods.
varcar = Object.create(null);
如果对象没有原型,可以传递Null。然而,这个对象将不会继承任何内容:
// car is same as {} or new Object().
varcar = Object.create(Object.prototype);
设计模式
要编写可扩展的代码,我们需要追踪代码中的重复部分,并以一种易于维护的方式优化它们。设计模式帮助我们做到这一点。
在由艾瑞克·伽玛(Erich Gamma)、约翰·弗利斯(John Vlissides)、拉尔夫·约翰逊(Ralph Johnson)和理查德·赫尔姆(Richard Helm)所著的《Addison-Wesley Professional》一书中;第一版(1994 年 11 月 10 日),设计模式被定义为:
设计模式命名、抽象和识别一个常见设计结构的关键方面,使其对创建可重用的面向对象设计有用。设计模式识别参与类及其实例、它们的作用和协作,以及责任分配。
每个设计模式都专注于特定的面向对象设计问题或问题。它描述了何时适用,是否可以在其他设计约束的背景下应用,以及其使用的后果和权衡。由于我们必须最终实现我们的设计,设计模式还提供了示例代码来展示实现。
虽然设计模式描述的是面向对象的设计,但它们基于已经在主流面向对象编程语言中实现过的实用解决方案。
开发者通常会质疑是否有一个最佳的设计模式可以实施到他们的工作流程中。
实际上,没有单一的设计模式适合所有场景。每个开发出的 Web 应用程序都有其自身的需求。我们必须看看如果实施,哪种模式将给我们的应用程序增加价值,因为所有设计模式都服务于不同的解决方案。
因此,一旦我们对设计模式有了良好的理解,将模式集成到我们的应用程序架构中就会更容易。设计模式被分为三类:创建型、结构型和行为型。
-
创建型设计模式:构造函数、工厂、原型和单例是创建型设计模式的例子
-
结构型设计模式:装饰者、外观和享元是结构型设计模式的例子
-
行为型设计模式:观察者和调解者是此类模式的例子
构造函数模式
构造函数是用于初始化对象的特殊方法。它们可以接受参数,这些参数随后用于在对象创建时设置成员属性和方法。原生构造函数,如数组和对象,在 JavaScript 中作为原生函数存在。我们还可以创建自定义构造函数,为我们的自定义对象定义属性和方法。
描述
在 constructor 方法中,我们使用 new 关键字创建一个对象。在这个方法中,我们使用 this 关键字定义属性和方法。属性在 = 符号之后定义。当你定义每个属性时,必须在末尾放置一个分号。当你需要在你的脚本中使用 this 方法时,你需要首先初始化对象,然后在使用代码中使用它:
简单构造函数
构造函数被认为是实现实例的最合适方式。new 关键字告诉 JavaScript 我们希望该函数表现得像构造函数,并创建一个实例,也称为 object。在构造函数内部,this 关键字用于引用新对象。
原型构造函数
原型是 JavaScript 中函数的一个属性。每当一个 constructor 函数被调用以创建一个新对象时,该构造函数的原型中所有的特性都会与新对象关联。
模块模式
模块是任何良好构建的 Web 应用程序的基本组成部分。它们以整洁、可理解和组织良好的方式相互独立地链接。换句话说,它们为程序提供了结构,同时也提供了封装。
描述
在 JavaScript 中,模块可以通过几种方式实现。我们在这里将讨论其中的两种:
-
对象字面量表示法
-
模块模式
对象字面量表示法
如我们之前所读,对象字面量是一系列用逗号分隔的name:value对,这些对被括号{}包围。名称可以是标识符或字符串后跟冒号。确保在最后一个name:value对之后没有逗号;否则,可能会导致一些意外的错误:
varObjectLiteral = {
variableKey: Value,
functionKey: function() {
//...
}
};
我们不必使用new关键字实例化对象字面量。
应注意确保在语句开头不使用关键字new。这是因为开括号可能被解释为代码块的开始。
我们可以从外部对象添加新成员,如下所示:
myModule.property = 'someValue';
使用模块可以帮助隐藏数据成员(封装)并以有组织的方式管理代码。
模块模式
在传统的软件工程中,模块模式提供了对类、方法和变量的公共和私有访问。模块模式的重点是减少全局变量的使用,以最小化整个应用程序内部代码中的冲突。
这是实现在大型的 JavaScript 框架和扩展库(如jQuery、ExtJS、YUI和DoJo)中最著名且最常用的设计模式。
下面是一个使用共享私有缓存的模块模式示例。这种方法使我们能够使用共享存储来创建对象,从而优化性能,因为函数只会在启动时创建一次。混入使用函数引用来调用它们,而不是每次需要时都创建该函数的新实例。
下面是模块模式的一些优缺点:
优点:
-
这种模式为开发者提供了一种更清晰的方法
-
它支持封装
-
减少了全局命名空间混乱
-
这支持具有闭包的本地函数和变量
缺点:
-
由于公共和私有成员的访问方式不同,当需要更改特定成员的可见性时,我们不得不在对象被使用的每个地方都进行更改
-
后添加到对象中的新方法无法访问私有成员
-
私有成员不能轻松扩展
揭示模块模式
这种模式几乎与模块模式相同。唯一的区别是,在这个模式中,所有成员都保持私有,直到它们被显式调用,通常是通过返回对象字面量的闭包来定义的。
描述
克里斯蒂安·海利曼设计了这种模式。他不喜欢我们不得不切换到对象字面量表示法来表示我们希望保持公开的对象。还有一个缺点:如果我们需要从一个方法访问另一个方法中的公共变量或调用公共方法,我们必须重复主对象的名字。
在这个模式中,我们将所有函数和变量定义为私有,并在模块末尾返回一个匿名对象,以及指向我们希望公开的私有函数和变量的指针。
下面是揭示模块模式的几个优缺点:
优点:
-
对开发者来说是一种更干净的方法
-
支持封装
-
减少全局命名空间混乱
-
带闭包的局部函数和变量
-
更一致的脚本语法
-
显式定义公共函数和变量
-
提高可读性
缺点:
-
私有成员不可访问
-
修改被某些私有成员引用的公共函数和变量很困难
单例模式
这个模式确保只创建一个类的实例,并提供一个全局访问点到该对象。
描述
单例模式通过创建一个方法的对象来实现,该方法的对象只能在它不存在时创建。如果对象已经存在,将返回对该对象的引用。
在需要一些可能不在初始化时可用信息的情况下,建议延迟单例的初始化。因此,它们与静态类或对象不同。
下面是单例模式的几个优缺点:
优点:
-
优化内存使用
-
单一的全局访问点
-
延迟初始化,直到需要时才实例化
缺点:
-
一旦实例化,就没有重置选项。
-
单元测试困难,因为当我们引用一个存在于测试类之外的单一类时,我们就无法进行真正的单元测试。我们最终测试的是目标类和单例一起,而不是应该是一个单一的目标类单元测试。
-
可能会引入隐藏的依赖。
观察者模式
观察者模式是这样的,如果一个对象的状态发生变化,所有其他对象都会收到通知并可以自动更新。因此,这个模式定义了对象之间的一对多依赖关系。
描述
在观察者模式中,一个对象(也称为主题/发布者)连接到多个其他对象,这些对象依赖于我们的主题。这些依赖对象被称为观察者/订阅者。
当状态发生变化时,主题会广播一个通知。所有观察者都会收到通知并相应地更新。
书籍《设计模式:可复用面向对象软件元素》将观察者模式描述如下:
"一个或多个观察者对主题的状态感兴趣,并通过将自己附加到主题上来注册他们的兴趣。当我们的主题发生变化,观察者可能感兴趣时,会发送一个通知消息,该消息调用每个观察者的更新方法。当观察者不再对主题的状态感兴趣时,他们可以简单地断开连接。"
这里有一些观察者模式的优点和缺点:
优点:
-
需要更深入地了解系统中的各种组件及其相互关系
-
有助于指出依赖关系
-
有助于将对象分解成更小的可重用组件
缺点:
-
应用程序完整性检查可能变得困难
-
将观察者从一个主题切换到另一个主题可能很困难
中介者模式
如其名所示,中介者是一个在两个或更多冲突方之间协助谈判的人。
在软件工程中,中介者属于行为设计模式类别。该模式使我们能够通过一个对象实现应用程序不同组件之间的通信。
描述
中介者模式通过确保对象不是直接相互交互,而是通过一个中心点进行通信,从而通过确保松散耦合来促进。
让我们通过一个现实世界的例子来更好地理解它。考虑一个机场交通控制系统。控制塔充当中介者,而所有其他飞机都在与控制塔通信,等待着陆或起飞的通知。它们不相互联系,只与控制塔联系。控制塔的作用非常关键和核心。因此,它是这个系统的重要关键。
类似地,中介者在这个模式中同样重要。
当我们调用中介者的订阅方法时,我们传递一个回调,中介者将这些回调排队,以便在给定事件触发时以及随后解耦对象的回调被触发。中介者触发信号以使对象能够触发,从而允许对象与任何其他对象解耦。
这里有一些中介者模式的优点和缺点:
优点:
-
移除多对多关系
-
建立多对一关系
-
帮助我们找出依赖关系
-
有助于将对象分解以促进更小的可重用组件
缺点:
-
引入了一个单点故障
-
当太多模块试图来回通信时,可能会出现性能问题
原型模式
在原型模式中,对象是通过克隆现有对象的模板创建的。
描述
这个模式侧重于创建一个可以通过原型继承用作其他对象模板/蓝图的对象。JavaScript 本身支持原型继承。因此,在这个模式中工作很容易。
这里有一些原型模式的优点和缺点:
优点:
-
适用于关注对象创建的应用程序
-
由于新对象从原型继承特性,性能更好
缺点:
- 对于具有非常少对象或原型的应用程序来说,过度设计
命令模式
在这个模式中,命令被封装为对象。
描述
命令对象允许松散耦合的系统将发出请求的对象与处理请求的对象分离。这些请求被称为事件,处理这些请求的代码称为事件处理器。
简单来说,我们可以这样说,命令模式的主要目的是将发出命令的功能与执行命令的功能分离,并将此功能委托给不同的对象。实际上,命令对象将一个动作绑定到将调用该动作的对象。它们通常包括一个如 run() 或 execute() 的函数。这种模式最大的优点之一是,具有相同接口的命令对象可以在需要时轻松互换。
优点:
-
命令模式使得构建必须执行/委托/排序方法调用的通用组件变得更加容易
-
具有相同接口的命令对象可以在需要时进行互换
-
它允许对命令执行进行记录,而不会受到客户端的干扰
缺点:
- 它显著增加了每个命令的类数量
当创建结构时,请求的生成和执行不依赖于彼此时很有用。我们可以这样说,命令实例可以由客户端实例化,并由调用者稍后运行。客户端和调用者可能对彼此一无所知。
这种模式是可扩展的,因为我们可以在不更改任何现有代码的情况下添加新命令。
门面模式
门面是一个面向世界展示并可见的前端层。在其背后隐藏着所有复杂性和不可展示的对象。
描述
门面模式是一种结构模式,它使我们能够在接口下隐藏后端复杂性。这种模式提高了应用程序模块的可用性。内部特性和方法不会直接暴露给开发者,但它们可以通过这个门面与之交互。这种模式使您的应用程序更加安全。
jQuery 是一个使用门面模式的 JavaScript 库的例子。
每当我们使用 jQuery 的 $(this).animate() 或 $(this).css() 函数时,我们都在使用一个门面。同样,$(document).ready() 实现了一个门面。
核心 jQuery 属性应被视为中间抽象。对开发者来说,更直接的负担是 DOM API,而门面使得 jQuery 库如此易于使用。
ready() 函数在后台有很多复杂性。jQuery 简化了浏览器的不一致性,以确保 ready() 在适当的时间被调用。
然而,我们只看到了一个门面或一个简单的接口层。
这里有一些门面模式的优点和缺点:
优点:
-
提高了 Web 应用程序的安全性
-
与其他模式兼容
-
更容易修补内部模块
-
实现起来更简单
-
提供了一个更简单的公共接口
-
被用于其他 JavaScript 框架,如 jQuery
缺点:
- 没有已证实的缺点
工厂模式
就像其他创建型设计模式一样,工厂模式也关注对象创建。然而,它不同之处在于它不需要构造函数来创建对象。
描述
工厂模式提供了一个对象创建的接口,其中我们指定需要创建的工厂对象的类型。子类允许决定哪个类将被实例化,以便它们可以指定将创建哪种类型的工厂对象。工厂模式非常易于扩展。当维护对象集合时使用工厂方法。这些对象集合不同,但仍然有许多共同的方法和属性。
在这个模式中,我们不会使用new关键字来创建对象。
让我们用一个实时例子来说明这个模式:
假设有一个服装工厂。我们需要创建一种服装类型。而不是直接使用new关键字创建这个对象,我们将请求一个用于新服装的工厂对象。我们告诉工厂需要哪种类型的对象(衬衫、牛仔裤、外套、围巾等)。它实例化那个类并返回对象供我们进一步使用。
ExtJS 是一个使用此模式的 JavaScript 库。创建对象的函数可以被分类并进一步子类化。
这里列出了工厂模式的一些优缺点:
优点:
-
通过一个接口类创建对象要容易得多,这个接口类为我们处理这个过程
-
适用于根据不同场景创建对象
-
对于类似实例化的对象来说非常实用
-
通过一个实例创建对象被简化了
缺点:
- 由于它隐藏在工厂方法后面,因此很难测试对象创建过程
混入模式
在面向对象编程中,混入是可以被子类或一组子类继承以实现功能重用的类。
描述
子类化意味着从超类或基类对象继承新对象属性。
例如,有一个能够从另一个类fruit扩展的apple类。在这里,fruit是超类,而apple是fruit的子类。apple的所有对象都继承自fruit的属性。然而,apple能够定义自己的方法并覆盖由fruit定义的方法。
如果apple需要调用fruit中的重写方法,这被称为方法链式调用。
如果apple需要调用fruit的构造函数,这被称为构造函数链式调用。
混入允许其他对象以非常低的复杂性级别继承其功能。这种模式允许我们通过多继承从多个混入中共享功能。
这里列出了混入模式的一些优缺点:
优点:
这种模式有助于减少函数重复,并促进函数的重用。在功能在整个系统中共享的应用中,我们可以将共享的函数放入混入(mixins)中,并专注于我们系统中其余的独特功能。
缺点:
在对象原型中保持功能可能会导致原型污染,并可能混淆跟踪函数的来源。这可能在大型应用程序中引起问题。
示例:
// Detailed explanation of Mixin Design Pattern in JavaScript can be found here: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#mixinpatternjavascript
/* Car Class */
var Car = function(settings) {
this.model = settings.model || 'no model provided';
this.colour = settings.colour || 'no colour provided';
};
/* Mixin Class */
var Mixin = function(){};
Mixin.prototype = {
driveForward: function() {
console.log('drive forward');
},
driveBackward: function() {
console.log('drive backward');
}
};
/* Augment existing class with a method from another class */
function augment(receivingClass, givingClass) {
/* only provide certain methods */
if(arguments[2]) {
var i, len = arguments.length;
for (i=2; i<len; i++) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
}
/* provide all methods */
else {
var methodName;
for (methodName in givingClass.prototype) {
/* check to make sure the receiving class doesn't have a method of the same name as the one currently being processed */
if (!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
}
/* Augment the Car class to have the methods 'driveForward' and 'driveBackward' */
augment(Car, Mixin, 'driveForward', 'driveBackward');
/* Create a new Car */
var vehicle = new Car({model:'Ford Escort', colour:'blue'});
/* Test to make sure we now have access to the methods */
vehicle.driveForward();
vehicle.driveBackward();
属性获取器和设置器
在编程语言中,获取和设置属性用于get和set对象的值。getter方法用于获取属性的值,而setter方法用于设置属性的值。
JavaScript 中有两个属性访问器:
-
获取器
-
设置器
描述
-
getter和setter是帮助我们非常容易地访问和操作对象内部数据的函数。它们可以帮助我们建立访问隐藏信息的快捷方式。getter和setter方法以这种方式工作,即它们将对象与一个函数绑定,使其看起来像正常的对象属性。 -
getter:此方法是一种特殊的属性访问器。当您想要访问一个属性时,值是动态生成的。以下是一个例子:Obj.getButtonColor(); -
setter:此方法用于设置属性。它传递一个值作为参数,并将函数的返回值设置为属性。以下是一个例子:Obj.setButtonColor(value);
删除属性
就像我们可以向对象添加属性一样,JavaScript 也允许我们删除对象属性。
描述
delete运算符用于删除对象的属性。它从本地版本中删除属性。属性的范畴可以被重新分配到同一作用域内的另一个变量。在 JavaScript 中,delete运算符始终返回一个布尔值。使用此关键字,您不能删除用var关键字声明的对象。
假设我们有一个这样的对象:
varauthor = {
"name":"talha",
"age":"24"
};
我们希望删除age属性,以便我们可以有一个看起来像这样的最终对象:
{
"name":"talha"
};
输入以下命令:
deleteauthor.age;
您也可以使用此命令达到相同的结果:
delete author["age"];
测试属性
开发者在对象上执行的一种常见测试是检查对象是否具有特定的属性。有不同方法来检查对象是否具有给定的属性。
描述
在 JavaScript 中,有两种属性测试方法:
-
hasOwnProperty:此方法用于检查对象是否具有自己的属性。如果属性是从任何地方继承的,则它将返回false:For example: samantha = new girls(); samantha.eyecolor = 'brown'; o.hasOwnProperty('eyecolor'); // returns true -
propertyIsEnumerable:此方法仅在hasOwnProperty返回true且该属性是可枚举的情况下返回true。
要在 JavaScript 中检查属性,我们可以使用in关键字。如果一个对象属性有它自己的值,它将返回true。
这里有一个例子:
var girls = {
name: 'Samantha',
height: 'Tall',
eyecolor: 'brown',
address: null
};
'name' in girls; // true
'age' in girls; // false
列出属性
在 JavaScript 中,使用for-in循环来枚举对象的属性。
描述
在 JavaScript 中,枚举属性在for-in循环中使用,因为这个循环访问了对象的所有属性。当我们想要检查对象的属性列表时,我们使用for-in循环来迭代属性。它将属性的名称分配给循环变量。
继承对象不可枚举,但使用这些对象添加的属性是可枚举的。
这里是一个示例:
var student = {
Name:"Ali",
Age:"24",
Edu:"Engineering"
}
Sudent.propertyIsEnumerable('Name');
// will return true since object's properties are enumerable
for(var property in student) {
Console.log(property); //will log all properties
}
属性属性
与每个 JavaScript 属性相关的信息称为属性。这里解释了不同类型的属性属性。
描述
JavaScript 属性有两种类型:
-
数据属性
-
访问器属性(
getter和setter属性)
属性具有四个属性:
-
可枚举性:这检查属性是否在循环结构中
-
可配置性:这检查我们是否可以删除或修改属性
-
可写性:这检查我们是否可以设置属性的值
-
值:这是属性的值,可以是 JavaScript 中的任何数据类型
注意
数据属性具有所有前面的属性,而访问器属性没有值或可写属性。
对象属性
JavaScript 中有三种类型的对象属性:
-
命名数据属性:这些是正常对象属性,其中对象将字符串名称映射到值。以下是一个示例:
Var x={ prop:555 }; console.log(x.prop); //its get method c.prop="xyz"; //its set method -
命名访问器属性:用于获取和设置属性的函数被称为命名访问器 属性。以下是一个示例:
Var x = { get name() { return getter; } }这里还有一个示例:
var x = { set name(val) { console.log(val); } } -
内部属性:在语言中不可访问的一些属性在 JavaScript 中被称为内部 属性。这些属性纯粹是为了规范目的。这些属性具有特殊名称,并写在大括号内。所有对象都有一个称为
[[Prototype]]的内部属性。该属性的值要么是 null,要么是一个对象,用于实现继承。它有两个部分:
-
原型:这告诉对象的原型
-
可扩展性:这告诉我们是否可以向对象添加属性
-
序列化对象
序列化对象意味着将对象转换为字节,以便它可以持久地存储在内存中,或者可以发送到网络上。然后,这些字节可以反序列化为原始对象。
描述
序列化用于存储或保留对象的内部状态。在序列化过程中,一个对象可以被传输或稍后检索。JavaScript 中有两种序列化方法:
-
JSON.stringify -
JSON.parse
这里是一个示例:
Obj={a:1}
A=json.stringify(obj);
// creates a JSON String from an array or object
B=json.parse(A);
// parses a JSON Object 'A' in an object.
这些方法也可以检索和存储对象、数组、字符串、true和false。可枚举值通过JSON.stringify()方法保留或恢复。
对象方法
对象方法是存储为对象属性的函数。这些方法可以通过直接调用它们来执行,调用时跟在要调用函数的变量后面,后面跟着一个点(.)。
描述
每个对象都有方法,这些方法基本上是在其上执行的操作。方法是一个对象的属性。
toLowerCase()、toUpperCase()、substr()、trim()、charAt()和indexOf()方法是字符串对象原生(核心语言的一部分)方法的示例。
这里是一个使用toUpperCase()方法的示例:
var book = "JavaScript Reference!";
var result = book.toUpperCase();
结果的值将是:
JAVASCRIPT REFERENCE!
函数和方法
函数是用户编写的执行特定操作的代码部分,可以独立通过名称调用。函数可以传递一些数据,也可以返回一些数据。另一方面,你可以将方法视为对象的定义属性,只能通过类对象来调用。与方法相关联的对象基本上是窗口对象。在 JavaScript 中,定义方法和函数的语法不同。方法仅用于定义窗口对象。在 JavaScript 中定义方法的语法与定义函数的语法不同。
调用函数
调用函数的四种不同方式如下:
-
将函数作为函数调用
-
将函数作为方法调用
-
将函数作为构造函数调用
-
使用函数方法调用函数
所有这些方法都在上一章中详细讨论过。初始化this关键字有不同的方式。当你调用一个函数时,它启动一个函数。然而,当你调用一个函数时,它执行它。
定义函数
当你定义一个函数时,你的脚本不会执行,但是当你调用一个函数时,脚本会执行。JavaScript 函数执行特定的任务。当任何对象调用此函数时,它开始工作。在 JavaScript 中定义函数,我们使用function关键字。一个函数可以有多个参数,这取决于任务。你可以在第八章中找到更多详细信息,JavaScript 实现、语法基础和变量类型。
函数参数和参数
在 JavaScript 中,一个函数可以有多个参数。一个函数可以用多个参数调用。如果你在函数中不提供任何参数,那么它将变为未定义。在 JavaScript 函数中,参数是可选的。如果你在函数中不传递任何参数,那么它将设置为默认值。以下是一个示例:
Function arg(x,y) {
Console.log(x+y);
Arg(2);
Arg(2,1);
}
在这个例子中,我们在函数中传递了两个参数:参数x和y。当第一次调用函数arg(2)时,a=2而b将是未定义的。当第二次调用函数时,a=2且b=1。
参数和返回值
我们知道我们可以在函数中传递参数。函数返回一个值以在脚本中执行不同的操作。有两种方法可以将值传递到函数中:
-
按值传递:当我们把任何变量(原始数据类型)作为函数的参数传递时,我们按值传递它。例如,首先,值是
2。传递之后,它变为3:var a=2; console.log(a); // shows 2 functionpassVal(a);{ a=3; } console.log(a); // shows 3 -
按引用传递:当你将一个值传递给对象时,它是通过引用传递的:
functionpassingVariables(a, b, c) { a = a + 10; b.value = "changed"; c = {value: "changed"}; } varnum = 10; varvar1 = {value: "unaffected"}; varvar2 = {value: "unaffected"}; passingVariables (num, var1, var2); console.log(num); // 20 console.log(var1.value); // changed console.log(var2.value); // unaffected
函数作为命名空间
命名空间是一组逻辑标识符的组合。JavaScript 默认不提供命名空间功能。因此,为了在 JavaScript 中创建命名空间,我们声明一个全局对象,并将所有函数和属性都放入该全局对象中,例如:
var stud=student || {};
stud.student=function(name) {
this.name ;
}
var s=new stud.student("Ali");
闭包
为了编写更好的代码,我们在 JavaScript 中使用闭包。更好的代码意味着具有创造性和表现力的代码。在 JavaScript 中,无论你是否是一个好的 JavaScript 程序员,你都会反复遇到闭包。根据你在代码中使用闭包的方式,它可能是复杂的或简单的。
基本上,闭包是 JavaScript 中的内部函数,用于访问外部函数的作用域。闭包有三个作用域:
-
访问外部函数变量
-
访问其自己的作用域变量
-
访问其全局变量
内部函数也可以访问外部函数的变量和参数。在其自己的作用域中,变量在花括号中定义。以下是一个示例:
functionstudentName(name) {
varstdName="Student Name";
functionstdLastName(){
returnstdName+name; }
returnstdntLastName();
}
函数属性
在 JavaScript 中定义一个函数,我们使用 function 变量。这个函数可以在你的脚本中的任何地方调用。它也可以是一个函数构造器。属性及其描述如下:
-
arguments:这是一个作为参数传递给函数的数组 -
argument.length:这告诉我们函数中有多少个参数 -
constructor:这用于创建对象 -
length:这定义了参数上的数字 -
prototype:这允许一个函数添加对象属性 -
arguments.callee:这告诉我们当前正在执行哪个函数
方法
在 JavaScript 中,对对象执行的操作称为方法。它们包含函数定义。它们作为脚本中的对象属性存储。例如,你可以在 JavaScript 中创建一个类似的方法:
Student.FullName = function() {
// define your code here
}
在这里,FullName 既是属性(Student.FullName)也是方法(Student.FullName())。当你不使用括号访问对象属性时,这将返回一个函数定义。以下是一个示例:
Name=Student.FullName;
函数构造器
函数构造器用于动态定义函数。使用构造器方法定义函数时使用 new 操作符。你还可以将你想要在脚本中使用的大量参数传递给构造器。最后一个参数将是函数的主体。它也可以包含由逗号分隔的语句。以下是一个示例:
varobj = new Function('a', 'b', 'return a*b;');
我们不能在构造器中将相同的函数名作为参数传递,因为这将在脚本中创建错误。它还可以创建一个无名的函数,称为匿名函数。
类和模块
在 JavaScript 中,我们没有创建类的任何原生方法,但我们可以使用原型继承和构造函数创建一个类。
类是对象的容器。我们使用类来封装命名空间和逻辑。
要实例化一个类,我们可以使用new关键字。类类似于构造函数。以下是一个例子:
function student(nameI) {
This.name=name;
this.age='18';
}
student.prototype.std=function() {
//define some code
};
module.export=student;
注意
模块用于轻松包含和扩展类和属性。模块将属性附加到全局对象以导出模块值。
类及其模块是 JavaScript 中极其重要和关键的部分。在接下来的章节中,我们将涵盖以下主题:
-
类和原型
-
构造函数
-
JavaScript 中的 Java 风格类
-
扩展的 JavaScript
-
类的类型
-
子类
-
ECMA5 脚本中的类
-
模块
类和原型
在 JavaScript 中,类是一个具有特殊类型属性和方法的对象。它用于创建实例并定义实例的行为。实例的行为会动态变化,我们在 JavaScript 中有特殊的语法来编写它。当在类上调用特殊方法时,会创建实例。
在 JavaScript 中,原型和函数是两回事。构造函数可以是任何函数,但原型是一种特殊的对象。为了定义任何实例的行为,我们使用原型。原型没有特殊的属性或方法。当我们修改原型时,我们就有实例了。
简单来说,我们可以说在 JavaScript 中,构造函数可以是任何负责创建实例的函数。另一方面,原型可以是任何没有特殊方法或属性的对象。原型负责实例的行为。
在 JavaScript 中,原型和构造函数函数像类一样工作,因为类有一个构造函数,要定义方法,你有原型:
这里是一个例子:
//Constructor Function
var Cat = function(name) {
this.Name = name;
this.Meow = function() {
console.log(this.Name + " meow");
};
}
//Prototype object method
var Cat = function(name) {
this.Name = name;
}
Cat.prototype.Meow = function() {
console.log(this.Name + " meow");
};
//Both gives same results
var cat = new Cat("Capri");
cat.Meow();
与原型相关联的没有特殊的属性或对象。你脚本中的对象可以是空项目或原型。当我们说任何对象都可以是原型时,那么这个对象将具有函数和数据类型。原型不是特殊类型的对象,但在 JavaScript 中,类是特殊类型的对象。
构造函数
类包含一组对象,为了初始化对象,我们使用构造函数。在类中,我们可以使用new运算符创建对象。我们可以将类定义为子类来构造对象。
使用原型的一个属性,创建一个构造函数。如果我们覆盖原型属性,构造函数的引用可能会丢失。在 JavaScript 中,我们使用constructor属性从一个对象创建一个类。以下是一个例子:
var color = 'black';
function Cat() {
// public property
this.color = '';
// private constructor
var __construct = function(that) {
console.log("I have a Cat!");
that.color = 'brown';
}(this)
// getter
this.getColor = function() {
returnthis.color;
}
// setter
this.setColor = function(color) {
this.color = color;
}
}
var b = new Cat();
console.log(b.getColor()); // should be brown
b.setColor('white');
console.log(b.getColor()); // should be white
console.log(color); // should be black
定义一个类
在 JavaScript 中定义类有三种方式:
-
使用函数
-
使用对象字面量
-
使用函数创建单例
使用函数
你可以使用函数中的new关键字创建一个对象。要访问方法和属性,请使用this关键字。如果在类中定义了具有相同名称的函数,将会有冲突。
使用对象字面量
要在 JavaScript 中定义一个对象或数组,我们使用字面量。以下是一个例子:
Varobj= {};
Varobj=[];
ECMA5 脚本中的类
对于特定对象的属性,ECMA5 脚本添加了五种方法。这些方法用于确保和限制脚本中对象的扩展性。这些方法包括:
-
可枚举
-
可写
-
获取器
-
设置器
-
可配置
当我们在 JavaScript 中定义一个类时,这些方法非常有用。当你存储一个对象时,它会为这些方法设置一个对象 ID。当我们使用循环语句时,它会返回这个对象 ID。所有对象都继承了这个对象 ID,它是可枚举的。要读取一个属性,它会调用getter函数,而不会有setter函数。因此,它是只读的。我们无法修改它,所以它不能被删除。
模块
模块的两个非常重要的方面是:
-
它们有依赖:这意味着当你在一个系统中编写模块时,它是完全依赖于函数的。我们在创建应用程序时从函数中导入依赖项。
-
它们有导出:如果你在系统中公开一些函数和变量,任何东西都可以导出这些。例如,你导出了一个函数
$function,依赖于这个函数的模块也将能够访问这个函数。
一个模块可以导出多个变量和函数。要导出这些函数和变量,我们使用export关键字。以下是一个示例:
Export function sub(a,b) {
Return a+b;
}
我们也可以在导出后存储一个变量。以下是一个示例:
Var string=function(a,b) {
Return a+b;
}
继承
JavaScript 支持原型继承。在其他编程语言中,对象和类通过继承彼此来使用对方的属性和函数。然而,在 JavaScript 中,你有一个基于对象的继承,这被称为原型,其中对象使用其他对象的属性。例如,如果你有一个Person对象,那么你可以使用该对象上的_proto_属性来创建另一个Student对象:

原型链式连接
在 JavaScript 中,你从现有对象创建新对象。这个过程被称为原型链式连接。它与面向对象系统中的继承类似。
描述
原型是constructor函数的一个属性。当你向原型添加任何对象属性时,它将把这个属性或方法添加到由构造函数创建的对象中。在原型链式连接中,我们使用constructor函数的属性创建一个函数原型。通过这种方式,所有方法或属性都从构造函数转移到原型对象。这种方法非常简单且非常有用,可以用来创建构造函数以创建对象。以下是一个示例:
function person(name) {
this.name=name;
}
person.prototype= {
sayHi:function() {
console.log("something");
}
Function student(name) {
This.name=name;
}
}
Student.prototype=new Person();
Varstd=new student("Ali");
Std.sayHi();
在方法解析中,JavaScript 首先检查对象是否有方法。当你使用原型链式连接时,它可以覆盖对象原型的某些方法。因此,JavaScript 构造函数为对象设置方法。
构造函数窃取
在 JavaScript 中,构造函数窃取也被称为经典继承。这种方法用于继承原型引用值的问题。
描述
在构造函数窃取中,我们在子类型构造函数中调用超构造函数。这个想法非常简单易懂。我们使用call()和apply()方法进行函数调用。以下是一个例子:
function super() {
this.name=["Ali"];
}
function sub() {
super.call(this);
}
varstd=new sub();
std.name.push("Ali");
varstd1= new sub();
console.log(std1.name);
在这个例子中,我们使用了call()方法来调用新创建的子类的一个超构造函数,而不是子构造函数。这将初始化sub()函数上的super()函数中的所有对象。
注意
当我们使用原型链式连接时,constructor函数将允许我们从超构造函数传递参数到子构造函数内部。
组合继承
组合继承也称为伪经典继承。这是构造函数窃取和原型链式连接的组合。
描述
在组合继承中,原型链继承从原型继承属性和方法,构造函数窃取继承实例。这样,我们可以通过允许方法有自己的属性来在原型上重用方法。以下是一个例子:
functionSuperType(name) {
this.name = name;
this.colors = ['yellow', 'purple', 'indigo'];
}
SuperType.prototype.sayName = function() {
//console.log(this.name);
};
functionSubType(name, age) {
//inherit properties
SuperType.call(this, name);
this.age = age;
}
//inherit methods
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function() {
//console.log(this.age);
};
varinstance1 = new SubType('John Doe', 26);
instance1.colors.push('white');
//console.log(instance1.colors); //'yellow,purple,indigo,white'
instance1.sayName(); //'John Doe';
instance1.sayAge(); //26
varinstance2 = new SubType('Kate', 21); //console.log(instance2.colors); //'yellow,purple,indigo'
instance2.sayName(); //'Kate';
instance2.sayAge(); //21
在这个例子中,SuperType构造函数定义了两个属性:name和colors。SuperType原型有一个名为sayName()的方法。SubType构造函数调用SuperType构造函数,传入name参数,并定义自己的属性age。此外,SubType原型被分配为SuperType的一个实例,然后定义了一个名为sayAge()的新方法。使用这段代码,就可以创建两个独立的SubType实例,它们都有自己的属性,包括colors属性,但都使用相同的方法。解决原型链式连接和构造函数窃取的缺点,组合继承是 JavaScript 中最常用的继承模式。它还保留了instanceof和isPrototypeOf()的行为,以识别对象的结构。
原型继承
在原型继承中,我们使用一个对象作为另一个对象的基础。
描述
在原型继承中,没有类,只有对象。要创建一个对象,你可以创建一个全新的对象,或者克隆一个现有的对象。然后,新对象可以通过添加新属性进行扩展。
这里有一个例子:
varobject=Object.create(null);
前一个对象没有原型,是null的克隆:
var rectangle = {
area: function () {
returnthis.width * this.height;
}
};
varrect = Object.create(rectangle);
在前面的例子中,rect从rectangle继承了area函数。这里,rectangle是一个对象字面量,对象字面量是创建Object.prototype克隆的一种方式。
它也可以写成如下形式:
var rectangle = Object.create(Object.prototype);
rectangle.area = function () {
returnthis.width * this.height;
};
我们可以按照以下方式扩展新创建的对象:
rect.width=50;
rect.height=100;
console.log(rect.area());
我们可以创建一个constructor函数,它会为我们克隆rectangle并扩展其height和width属性:
var rectangle = {
create: function (width, height) {
var self = Object.create(this);
self.height = height;
self.width = width;
return self;
},
area: function () {
returnthis.width * this.height;
}
};
varrect = rectangle.create(50, 100);
console.log(rect.area());
寄生继承
寄生继承类似于原型继承。
描述
它通过创建一个执行继承、对象增强并在每个任务完成后返回对象的函数来简单地工作:
Function abc(x) {
Var clone=obj(abc);
Clone.sayHi=function() {
};
return clone;
}
Var student= {
Name="Ali";
};
Varstd=new abc(student);
Std.sayHi();
在这个例子中,我们有一个 abc() 函数,它有一个参数,这个参数是基于新对象的。这个对象被传递给 object 函数,并将结果对象保存到 clone 变量中。现在,clone 对象将有一个新的对象属性,最后,我们返回这个对象。
寄生组合继承
寄生生物被定义为生活在另一种生物体内并依赖其资源的生物。同样,在这个继承中,子对象依赖于父对象并从它扩展其属性。
描述
第一个构造函数调用子类型的 prototype,然后调用子类型的 constructor。这是在 JavaScript 中创建新对象的一种非常有效的方法。最后,子类型将具有超类型的所有属性。以下是一个例子:
function super(name) {
this.name=["Ali"];
}
super.prototype.sayHi=function() {
console.log("something");
}
function sub(age) {
this.age=age;
super.call(this,name);
}
sub.prototype=new super();
sub.prototype.sayHi();
寄生组合继承和组合继承之间的唯一区别在于,在前者中,基构造函数只调用一次,而在后者中,基构造函数调用两次。
子类
在每种编程语言中,每个子类都有一个超类,它继承其属性和方法。JavaScript 不是一个纯面向对象编程语言,但它遵循一些面向对象的规则。我们使用对象表示法在 JavaScript 中创建类。
在 JavaScript 中,你只能使用 constructor 函数或原型来执行继承。这种继承仅在运行时进行,这意味着它是动态的。以下是一个例子:
// super class
functionsuperClass() {
this.bye = superBye; //method 1
this.hello = superHello; //method 2
}
//sub class
functionsubClass() {
this.inheritFrom = superClass; //inherit-from method defines superclass
this.inheritFrom(); //inherit from method called
this.bye = subBye; method 1 overridden in subclass
}
functionsuperHello() {
return "Hello from superClass";
}
functionsuperBye() {
return "Bye from superClass";
}
functionsubBye() {
return "Bye from subClass";
}
要运行前面的代码,请执行以下方法:
functionprintSub() {
varnewClass = new subClass();
console.log(newClass.bye());
console.log(newClass.hello());
}
内置对象
为了在语言中增加灵活性,JavaScript 支持许多内置对象。最常用的对象包括:
-
全局
-
日期
-
Math
-
RegExp(正则表达式)
-
数组
这些内置对象的实现复杂且不同。
全局对象
全局对象是在函数外部定义的对象。每个函数都可以访问这些变量,因为它们的范围是全局的。
当你没有声明变量并给它赋值时,它将自动成为全局的。
描述
当你的代码开始执行时,函数和常量立即可用。全局变量不使用 new 关键字初始化。基本上,全局对象用于共享相同的数据以添加属性。你可以在脚本中将方法存储在全局对象中。
你不能直接访问的对象,为了访问这些对象,我们使用全局对象。在声明全局变量后,我们直接将这些对象作为参数传递。你可以在脚本中创建多个实例和多个全局对象。
全局对象具有固定数量的属性。多个对象实例可以访问这个全局对象。以下是一个例子:
varstudentName="Ali"
functionmyStd(){ }
student=new Global("name");
student.age=18;
person=new Global("name");
post(person.age);
日期对象
JavaScript 中的日期对象处理日期和时间对象。例如,如果我们正在编写脚本并且需要日期和时间的某些功能,那么我们可以简单地使用这个内置对象。
getTime()
此函数用于获取自 1970 年 1 月 1 日以来的毫秒数。
参数
没有传递参数。
返回值
自 1970 年 1 月 1 日以来的毫秒数。
描述
如其名所示,此函数用于获取当前时间,以毫秒为单位。我们首先需要创建一个日期对象。
var time = new Date();
time.getTime(); // This will output time as 1454905019871
getMilliseconds()
此函数用于获取相对于毫秒数的当前时间。
参数
没有传递参数。
返回值
一个从 0 到 999 的数字。
描述
如其名所示,此函数用于获取当前时间,以毫秒为单位。我们首先需要创建一个日期对象。
var time = new Date();
time.getMilliseconds();
getMinutes()
此函数用于获取相对于分钟的当前时间。我们首先需要创建一个日期对象。
参数
没有传递参数。
返回值
一个从 0 到 59 的数字。
描述
此函数用于获取当前时间,以分钟为单位。我们首先需要创建一个日期对象。
var time = new Date();
time.getMinutes();
getHours()
此函数用于获取相对于小时的当前时间。我们首先需要创建一个日期对象。
参数
没有传递参数。
返回值
一个从 0 到 23 的数字,0 代表午夜。
描述
此函数用于获取相对于小时的当前时间。我们首先需要创建一个日期对象。
var time = new Date();
time.getHours();
getDate()
此函数用于获取当前天。
参数
没有传递参数。
返回值
一个从 1 到 31 的数字。
描述
此函数用于获取当前天。我们首先需要创建一个日期对象。
var time = new Date();
time.getDate();
getDay()
此函数用于获取当前周中的当前天。
参数
没有传递参数。
返回值
一个从 0 到 6 的数字,0 代表星期日。
描述
此函数用于获取当前周中的当前天。我们首先需要创建一个日期对象。
var time = new Date();
time.getDay();
getMonth()
此函数用于获取当前月份。
参数
没有传递参数。
返回值
一个从 0 到 11 的数字。
描述
此函数用于获取年份中的当前月份。我们首先需要创建一个日期对象。
var time = new Date();
time.getMonth();
getFullYear()
此函数用于获取当前年份。
参数
没有传递参数。
返回值
年份,格式为 YYYY。
描述
此函数用于获取当前年份。我们首先需要创建一个日期对象。
var time = new Date();
time.getYear();
设置日期方法
日期对象中提供了可用于操作日期的方法。我们还可以动态调整日期。以下是一个示例:
var dob=new date();
dob.setDate(19.03.1990);
我们也可以通过此函数设置未来的日期和当前日期,例如:
var dob=new date();
dob.setDate(dob.getDate + 7);
日期设置方法有:
-
setTime() -
setMilliseconds() -
setMinutes() -
setMinutes() -
setHours() -
setDate() -
setDay() -
setMonth() -
setFullYear()
这些方法与前面术语列表中描述的日期获取方法非常相似。
我们也可以使用日期对象来比较日期。
数学对象
在 JavaScript 中,数学对象用于执行数学运算。
此对象有多个数学函数。以下是一个示例:
-
Math.E -
Math.PI -
Math.sqrt -
Math.Ln2 -
Math.ln10
math对象有不同的方法。例如,我们有pow方法,它计算第一个变量的幂乘以第二个变量。
Math.pow(base, exponent);
document.write(Math.pow(2,4)); // 16 here 2 is base and 4 is exponent.
min()
此函数用于找出具有最小值的参数。
参数
需要评估的值作为参数传递。
返回
具有最小值的参数。
描述
如其名所示,此函数简单地用于从参数中的所有值中获取最小值
例如:
min(10, 56, 3, 26, -6, 4); //The value returned is -6
max()
此函数用于找出具有最大值的参数。
参数
需要评估的值作为参数传递。
返回
具有最大值的参数。
描述
如其名所示,此函数简单地用于从参数中的所有值中获取最大值。
例如:
max(10, 56, 3, 26, -6, 4); //The value returned is 56
random()
此函数用于生成介于 0 和 1 之间的随机数。
参数
无参数。
返回
一个介于 0 和 1 之间的随机数。
描述
random()函数在生成随机数时很有用。该数字的值始终介于 0 和 1 之间(永远不会正好是 1)。例如:
Math.random();
round()
此函数用于将数字舍入到其最近的整数值。
参数
需要评估的值作为参数传递。
返回
舍入后的数字。
描述
此方法用于在舍入后创建整数值。
例如:
Math.round(4.3);// The value returned is 4
Math.round(4.8);// The value returned is 5
Math.round(4.5);// The value returned is 5
ceil()
此函数用于将数字向上舍入到最近的可能的最大整数值。
参数
需要评估的值作为参数传递。
返回
舍入后的最大数字。
描述
此方法用于在舍入到更高的整数后创建整数值。
例如:
Math.ceil(-6.2);// The value returned is -6
Math.ceil(6.2);// The value returned is 7
floor()
此函数用于将数字向下舍入到最近的可能的最小整数值。
参数
需要评估的值作为参数传递。
返回
舍入后的最小数字。
描述
此方法用于在舍入到更低的整数后创建整数值。
例如:
Math.floor(2.3);//The value returned is 2
Math.floor(-2.3);//The value returned is -3
RegExp 对象
在 JavaScript 中,对于字符串中的模式匹配,我们使用正则表达式。它是一种非常强大且有用的表达式模式匹配工具。
参数
以下参数:
-
模式:正则表达式的文本/模式
-
标志:如果指定,标志可以是以下组合之一:
-
g: 全局匹配 -
i: 忽略大小写 -
m: 多行;将开始和结束字符(^和$)视为跨越多行(即,匹配每行的开始或结束(由\n或\r分隔),而不仅仅是整个输入字符串的非常开始或结束)
-
返回
不同正则表达式的返回类型不同。
描述
使用正则表达式,你可以通过编写几行代码将复杂任务简化。JavaScript 中有五种方法:
-
RegExp.exec(pattern) -
RegExp.replace(pattern) -
RegExp.split(pattern) -
RegExp.match(pattern)
定义正则表达式
在 JavaScript 中,有两种编写正则表达式的方法。这些是:
-
RegExp 构造函数方法
-
文字语法
注意
RegExp对象和全局对象之间有区别。它们看起来相同,但行为不同。
RegExp 构造函数
此方法用于动态构建字符串搜索模式。在此方法中,正则表达式应写成引号内。此方法有三个参数。以下是一个例子:
var email=new RegExp("\d{2},"g");
在此示例中:
-
电子邮件是一个必需的参数,正则表达式值被分配给它
-
\d是一个用于匹配正则表达式的模式参数 -
g是全局的,这是一个标志参数。在此函数中,有四种类型的参数(g、I、m、u)。
文字语法
在文字表示法中,我们不使用括号来编写正则表达式。在这里,i是一个标志,表示忽略文本的大小写,无论是大写、小写还是其他。我们还有更多的标志对象,如下所示:
-
g: 全局对象 -
i: 忽略大小写 -
m: 多次搜索 -
u: Unicode 搜索
在正则表达式中,我们可以有一个全局正则表达式对象,它将为每个匹配情况提供信息。一个简单的正则表达式对象只包含特定正则表达式的信息:
var exp=\d{2}/i
字符串对象
有四种字符串匹配方法。在这些对象中,一个模式通过参数发送。这些方法允许您搜索、匹配、替换和分割模式。
这些方法如下所示。
Match(pattern)
此方法用于在字符串中找到匹配的模式。使用not(!)运算符,它也可以用于找到非匹配项。
语法是string.Match(Expression)。
参数
要匹配的字符串模式。
返回值
如果找到匹配项,则返回结果,如果没有找到匹配项,则返回0或null。
描述
这将在正则表达式中运行匹配字符串的搜索。如果搜索匹配或成功,则将返回匹配结果的数组,如果不匹配,则返回null或0。它还用于更新正则表达式的属性。
这里是一个例子:
var str=("I have 10 dollars");
//The pattern below is used to find non-digits in a string
var parsestring= str.match(/\D/g);
// Outputs I, ,h,a,v,e, , ,D,o,l,l,a,r,s
Replace(pattern)
此方法用于替换字符串的一部分。
语法是string.replace(stringSearched, stringReplacement)。
参数
要替换的字符串模式作为参数传递。
返回值
替换后的字符串。
描述
这将执行搜索并用于用替代文本替换正则表达式匹配的结果。这也用于用特定且不同的regExp属性替换正则表达式。
这里是一个例子:
var str1=("Apple Pie");
var parsestring1=str1.replace("Pie", "Cinnamon Roll");
这里parsestring1的值是Apple Cinnamon Roll。
注意
请记住,搜索是区分大小写的,所以如果您提供parsestring1=str1.replace("piE", "Cinnamon Roll");的值,则不会进行替换。
此外,只有模式的第一个出现被替换。因此:
var str1=("Apple Pie , Banana Pie", "Strawberry PIE");
var parsestring1=str1.replace("Pie", "Cinnamon Roll");
这里parsestring1的值是Apple Cinnamon Roll、Banana Pie、Strawberry PIE。
要执行全局搜索和替换,以便替换所有出现,我们使用以下代码:
var str1=("Apple Pie , Banana Pie", "Strawberry PIE");
var parsestring1=str1.replace(/Pie/g, "Cinnamon Roll");
这里 parsestring1 的值是 Apple Cinnamon Roll,Banana Cinnamon Roll,Strawberry PIE。
对于全局不区分大小写的搜索,请使用以下代码:
var str1=("Apple Pie , Banana Pie, "Strawberry PIE");
var parsestring1=str1.replace(/Pie/gi, "Cinnamon Roll");
这里 parsestring1 的值是 Apple Cinnamon Roll,Banana Cinnamon Roll,Strawberry Cinnamon Roll。
Split(pattern)
这用于使用正则表达式分割字符串。
语法是 string.split(separator,limit)。
参数
分隔符和限制是可选参数。
返回
返回分割后的字符串。
描述
使用此方法,字符串被分割。字符串中的每个单词都被视为数组中的一个单独元素。如果传递了空字符串作为参数,则该方法会将每个字母分割成不同的字符。例如:
var str1 = "My Car is at the garage in Queens";
var parseString = str1.split("");
parseString 的值将是:
M,y, ,C,a,r, ,i,s, ,a,t, ,t,h,e, ,g,a,r,a,g,e, ,i,n, ,Q,u,e,e,n,s
提供一个限制将返回一个逗号分隔的数组,其中只包含指定数量的元素。例如:
var str1 = "My Car is at the garage in Queens";
var parseString = str1.split(" ", 3);
parseString 的值是 My,Car,is。
使用字母或字母作为分隔符将给出以下结果:
var str1 = "My Car is at the garage in Queens";
var parseString = str1.split("a");
parseString 的值将是:
My C,r is ,t the g,r,ge in Queens
这里是另一个例子:
var str1 = "My Car is at the garage in Queens";
var parseString = str1.split("ar");
parseString 的值将是:
My C, is at the g,age in Queens
search(pattern)
此方法用于搜索特定字符串。
语法是 string.search(stringSearched)。
参数
要搜索的字符串模式作为参数传递。
返回
如果找到匹配项,则返回字符串起始字母的位置;如果没有找到匹配项,则返回 -1。
描述
它用于在字符串中查找匹配项。如果找到匹配项,它将发送该匹配项的索引;如果没有找到匹配项,则返回 -1。此方法不支持全局标志。
这里是一个例子:
var str1=("I have 10 dollars in my pocket");
var parsestring=str1.search("i");
这里 parseString 的值是 18。
注意
有其他字符串方法可用于在字符串上执行其他任务。
这些方法的详细列表可以在 msdn.microsoft.com/en-us/library/ecczf11c(v=vs.94).aspx 找到。
数组对象
数组是一组对象的集合。
在 JavaScript 中创建数组时,集合的元素被括在方括号内,并用逗号分隔,如下所示:
varcolors = ["red", "yellow", "blue"]
数组也可以使用 new 关键字或指定长度(介于 0 和 232-1 之间)来初始化:
new array(first, second, third, … )
new array(7) // creates an array of size 7
要访问数组元素,我们可以使用索引表示法:
varlastColor = colors[2]; // blue
总是记住,数组元素始终从零索引开始。因此,前面数组中的第三个元素的索引是 2。
数组对象可以存储各种数据,例如,字符串、数字、文字、日期,甚至用户定义的对象。
.Pop()
此方法用于从数组中 弹出 一个元素。
参数
此方法没有参数。
返回
它返回数组的 弹出 元素。
描述
在这里,数组被视为一个栈,最后进入数组的元素首先弹出。这遵循 LIFO 原则。
这里是一个示例:
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var element= sweets.Pop();
此处元素的值是 Black Forest。
.Push()
此方法用于 push 一个元素到数组中。
参数
此方法没有参数。
返回值
它返回数组的新的长度。
描述
在这里,数组被视为一个栈,推入的元素出现在数组的末尾。
这里是一个示例:
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var element= sweets.Push("Lemon Meringue");
此处元素的值是 6。
.ToString()
这将数组中的元素转换为字符串。元素以逗号分隔的字符串形式出现。
参数
没有参数。
返回值
这返回一个包含数组元素的字符串。
描述
ToString() 函数用于将数组转换为字符串。数组元素在字符串中显示,并由逗号分隔:
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var StrSweets= sweets.ToString()
这里 StrSweets 的值是:
Red Velvet,Chocolate Mousse,Strawberry Delight,Pineapple Sundae,Black Forest
.ValueOf()
此方法也用于将数组转换为字符串。
参数
没有参数。
返回值
这返回一个包含数组元素的字符串。
描述
这是数组的默认行为,与 ToString() 函数的工作方式相同。
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var StrSweets= sweets.ValueOf()
这里 StrSweets 的值是:
Red Velvet,Chocolate Mousse,Strawberry Delight,Pineapple Sundae,Black Forest
.Join()
此方法用于将数组转换为字符串。元素由指定的分隔符分隔。
参数
一个分隔符,用于分隔新字符串中的元素。
返回值
这返回一个包含数组元素的字符串,元素由指定的分隔符分隔。
描述
Join() 函数用于将数组转换为字符串。数组元素在字符串中显示,并由分隔符分隔:
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var StrSweets= sweets.Join(*)
这里 StrSweets 的值是:
Red Velvet * Chocolate Mousse * Strawberry Delight * Pineapple Sundae * Black Forest
.Splice()
Splice,如其名所示,用于向数组中添加新元素。与 push() 方法不同,我们可以添加到任何位置。
参数
以下参数:
-
位置
-
要删除的元素数量
-
要添加的元素
返回值
数组作为字符串,以及任何新元素(如果有)。
描述
此方法用于在一步中删除和添加元素。我们可以指定新元素要添加的位置以及要删除的元素。
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var StrSweets= sweets.splice(2, 0, "Lemon Meringue");
这里 StrSweets 的值是:
Red Velvet,Chocolate Mousse,Lemon Meringue,Strawberry Delight,Pineapple Sundae,Black Forest
.sort()
此方法用于将数组按字母顺序排序。
参数
没有参数。
返回值
返回排序后的数组。
描述
排序方法用于按字母顺序排序数组。
这里是一个示例:
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var StrSweets= sweets.Sort();
这里 StrSweets 的值是:
Black Forest,Chocolate Mousse,Pineapple Sundae,Red Velvet,Strawberry Delight
.reverse()
如其名所示,它反转数组的顺序。
参数
没有参数。
返回值
返回反转后的数组。
描述
反转方法用于按字母顺序反向排序数组。
这里是一个示例:
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var StrSweets= sweets.reverse();
这里 StrSweets 的值是:
Strawberry Delight,Red Velvet,Pineapple Sundae,Chocolate Mousse,Black Forest.slice()
.slice()
如其名所示,此方法用于将数组切片并使用原始数组的一部分创建一个新数组。
参数
我们想要切片的数组索引。数组的索引从 0 开始。因此,第一个元素的索引是 0,第二个元素的索引是 1,依此类推。
返回值
返回包含剩余元素的切片数组。
描述
切片方法用于切割数组并获取数组剩余部分作为字符串。
这里有一个示例:
var sweets = ["Red Velvet", "Chocolate Mousse", "Strawberry Delight", "Pineapple Sundae", "Black Forest"];
var StrSweets= sweets.slice(3);
这里 StrSweets 的值是:
Pineapple Sundae,Black Forest
.concat()
此方法用于将两个或多个数组连接成一个单一数组。
参数
作为参数传递要连接的数组。
返回值
此方法返回连接后的数组。
描述
Concat() 方法用于通过连接两个或多个数组来创建一个单一数组。
这里有一个示例:
var greenShades= ["Mint", "Basil", "Pine", "Emerald"];
var BlueShades=["Azure", "Cerulean", "Navy", "Aegan"];
var VioletShades= ["Lilac", "Orchid", "Mauve", "Wisteria"];
var CoolShades=greenShades.concat(BlueShades, VioletShades);
这里 CoolShades 的值是:
Mint,Basil,Pine,Emerald,Azure,Cerulean,Navy,Aegan,Lilac,Orchid,Mauve,Wisteria
第十一章. 扩展 JavaScript 和 ECMAScript 6
ECMA 262 是一个定义 JavaScript 语言核心特性的标准。由该标准定义的语言称为 ECMAScript。JavaScript 是 ECMAScript 的一个实现。它在客户端的网页浏览器中运行,而 Node.js 在服务器端运行。ECMAScript 6 于 2015 年 6 月发布。ES6 是从 2009 年发布的 ES5 的一次重大更新。
可以从 people.mozilla.org/~jorendorff/es6-draft.html 获取 ES6 语言规范的完整语言规范草案。
兼容性和目标
ES6 兼容性图表显示了当前浏览器支持 ES6 的哪些功能。它还链接了所有列出的功能到它们的规范指南。
注意
应注意,一些功能可能不符合其确切规范。在 Chrome 中工作时要记得启用实验性 JavaScript 标志。

参考:使用 ECMAScript 6 今天
ECMA6 脚本有以下主要目标:
-
默认导出
-
模块的静态结构
-
支持异步和同步加载
-
用于模块之间的依赖关系
JavaScript 子集和扩展
子集主要为了安全目的而定义;使用安全语言子集编写的脚本即使其源代码不可信,例如广告服务器,也可以安全执行。其中一些子集将在后面进行描述。
随着 JavaScript 的持续发展和允许显式扩展,发布了新版本。许多功能被标准化。这些扩展与现代浏览器(如 Firefox 和 Chrome)兼容。然而,非标准扩展的实现可能需要一个外部编译器,因为这些功能目前正在主要的 JavaScript 引擎中更新。
JavaScript 子集
如前所述,为了执行不可信代码的安全性,我们在 JavaScript 中使用子集。例如,当我们有一个信用卡检查脚本,其中信用卡号被发送到远程服务器时,为了这种类型的信息安全,我们使用子集。通过定义子集,我们检查了一个我们严格不允许的程序的行为。这意味着我们为一定量的代码使用子集,而代码的其他部分被省略。
JavaScript 子集有两个目标:
-
应将子集构造添加以最大化 JavaScript 构造的使用范围
-
它用于扩展分析以适应变化
这些子集的定义出于各种原因。
优点:这是一个子集,它是用于脚本最佳和值得部分的语言的一部分。这个子集的主要目标是净化和简化代码,使脚本更容易理解。优点子集没有 eval() 函数。它还消除了 continue 和 with 语句。它不包括函数定义语句,只使用函数定义表达式来定义函数。使用函数定义语句定义函数后,它不再使用函数定义语句。
注意
在子集的花括号中,我们有一个循环和条件语句的主体。如果主体中只有一个语句,那么它不会允许省略括号。
安全子集
有各种安全子集的实现。其中一些在这里简要描述。
ADsafe
ADsafe (www.adsafe.org/) 是最早提出的安全主题之一。它由 Douglas Crockford 提出并创建。ADsafe 使用工具,如 JSLint (www.jslint.com/) 来验证不安全的代码。它强制执行良好的编程实践,因此不安全代码正确执行的可能性要高得多。它阻止脚本访问全局变量或直接访问 DOM。相反,它允许脚本访问 ADsafe 对象,该对象提供对安全 API 的访问和间接访问 DOM 元素。ADsafe 不更改脚本,不会影响其功能。它使我们能够快速确定脚本是否可以放置在页面上。它还作为一个基础,有助于开发其他安全子集。
Dojox
dojox.secure 工具 (dojotoolkit.org/reference-guide/1.10/dojox/secure.html) 是一个受 ADsafe 启发的安全子集。它是 Dojo 工具包 (dojotoolkit.org) 的扩展,由 Kris Zyp 开发。它完全集成了确保不受信任的代码、内容、广告和来自不同域的小部件安全执行和加载的组件。它提供了一个沙盒环境,并限制了用于交互的 DOM 元素:

Caja
Caja (developers.google.com/caja/) 是由 Google 提供动力的开源安全子集。Caja(在西班牙语中意为“盒子”)进一步定义了两个子集:
-
Cajita(在西班牙语中意为“小盒子”)是一个狭窄的子集,就像 ADsafe 和 dojox.secure 一样。
-
Valija(在西班牙语中意为“手提箱”)是一个更广泛的子集,并且与严格模式的 ECMAScript(移除了
eval()方法)非常相似。
Caja 是一个编译工具,它将 HTML、CSS 和 JS 等第三方内容转换为安全代码,这使得代码更容易嵌入到网站中。
FBJS
FBJS(github.com/facebook/fbjs)是 Facebook 使用的 JavaScript 安全子集。它允许在安全环境中执行不受信任的代码。它通过转换代码来确保安全性。在转换过程中,所有顶级标识符都被添加了模块特定的前缀。添加模块特定前缀可以防止查询任何全局标识符。例如,你正在开发一个具有xyz123 ID 的应用程序,代码中有一个foo()函数。它最终会变成xyz123_foo()。甚至对eval()的函数调用也会被重定向到一个不存在的函数。
微软的 web sandbox
微软的Web Sandbox(www.websandbox.org/)定义了一个广泛的、安全的 JavaScript、HTML 和 CSS 子集。沙盒通过实现宿主虚拟化来提供安全性和可扩展性。不受信任的代码在虚拟机中执行,而不是直接在浏览器中运行。虚拟机将不受信任的代码隔离,防止它与虚拟机外的元素交互。让我们看一下以下块图:

微软的 Web Sandbox
JavaScript 扩展
已经编码了许多新的和有用的功能。它们将在 ES6 的发布中得到标准化。ES6 计划于 2015 年 6 月正式发布。然而,许多功能和扩展已经在 Firefox 和 Chrome 上可用(为了访问一些 ES6 功能,必须将实验性 JavaScript 标志打开)。我们将在本章的其余部分讨论主要功能。
Const
它的工作方式类似于var变量关键字。为了声明一个常量,我们使用const这个词。为了使用赋值,我们必须声明常量。
注意
使用 const 声明的值不能被重新声明、重新定义或重新初始化。JavaScript 通过 math 对象提供了 8 个常量。其中之一是 PI。我们无法使用 const 重新初始化 PI。
Let
Let关键字用于变量的块作用域。变量在代码的开始处声明,而不是在函数的开始处:
var name = "john";
console.log(name);
在前面的例子中,john这个名字是控制台中记录的名字的值。JavaScript 中的声明被移动到顶部。在函数作用域中声明的或初始化的变量的位置并不重要,它们将默认提升到顶部。JavaScript 的默认行为是将变量声明移动到顶部。
提升是 JavaScript 的默认行为,将变量声明移动到顶部。
JavaScript 中的变量是函数作用域的。这意味着,变量在整个函数中都是可用的,即使它们是在嵌套的代码块中声明的。以下是一个简短的例子,我们将记录客户端(即 Chrome、Firefox 等)控制台中的输出:
var name = "john";
(function () {
// var name = undefined;
if (!name)
{ var name = "jane"; }
console.log(name); // "jane"
}());
从前面的例子中,用于在控制台中登录的名字的值是jane。
ES6 使用 let 来处理这个问题。let 和 var 非常相似。唯一的区别是 let 是块作用域的,而 var 是函数作用域的。我们可以使用 let 重新编写之前的例子,如下所示:
var name = "john";
(function () {
// var name = undefined;
if (!name) {
let name = "jane";
}
console.log(name); // "john"
}());
注意,尽管在函数内部 name 的值是 jane,但使用 let 关键字将其作用域设置为全局,并且 name 的默认值是 john。因此,john 被记录在客户端控制台中。
注意
如果我们将一个变量声明为常量,给它赋一些值,然后在其他地方使用相同的常量改变它的值,那么它的新值将被忽略。像变量一样,我们可以在脚本中的任何地方添加常量而不会破坏代码。
解构赋值
我们可以使用一条命令将多个值赋给函数中的变量。
For each
属性值的迭代是通过这个循环完成的。属性名的迭代也已经完成。
迭代器
下一个方法的对象被返回。返回的对象具有 _iterator_ 属性。迭代器用于 iteratable 对象。
生成器
对象的生成在这里完成。每当函数调用 this 方法时,都会返回一个生成对象。使用 yield 关键字指定函数的当前执行。
数组
在数组中有相同值的 iteratable 对象可以通过使用数组来简写。
生成器表达式
函数被简写为多个 try-catch 表达式。返回的是用 {} 包裹的生成对象,而不是用 []。我们用这个来将多个值赋给函数中的变量。
作用域变量和常量
当我们声明一个变量时,它就具有局部作用域和全局作用域。我们可以在脚本中的任何地方定义一个变量。当我们用 JavaScript 声明一个变量时,我们可以在声明时或之后给它赋值。以下是一个示例:
_xyz123; // variable declared without assigning a value to it
varabc = "Star"; //variable declared while assigning a value to it
在 JavaScript 中,变量是通过查询中的美元符号定义的。在 JavaScript 中,我们使用 var 关键字动态创建变量。每个变量都有一个与之关联的名称和值。这些值可以是任何类型,例如 number、array、string 等。变量名可以是字符和数字的组合。以下是一个示例:
(a==undefined){
a=5}
在函数外部声明的变量是一个全局变量,具有全局作用域。这意味着它可以从脚本中的任何地方访问。
我们也可以使用 const 关键字声明一个变量为常量。常量变量的值是恒定的。
可以使用 const 关键字定义常量,如下所示:
Const a=5;
注意
const 和 let 关键字以类似的方式工作,因为它们都是块作用域的。然而,在 const 的情况下,值不能被重新声明、重新定义或重新初始化。简而言之,const 值是只读的。
这里有一个工作示例:
const PI = 3.14159265359;
console.log("value of PI = " + PI); //value of PI = 3.14159265359
PI = 3.1415; //<------- Can not re-assign value to PI
console.log("value of PI = " + PI); //value of PI = 3.14159265359
const PI = 2.0312; //<------- Can not re-initialize value of PI
console.log("value of PI = " + PI); //Uncaught TypeError: Identifier 'PI' has already been declared
var PI = 9.2144; //<------- Can not re-declare value of PI
console.log("value of PI = " + PI); //Uncaught TypeError: Identifier 'PI' has already been declared.
类变量在类中声明,而不是在任何类的任何方法中声明,而局部变量存在于任何类的任何方法中。
简短函数
简短函数,也称为表达式闭包,是 JavaScript 中使用简单函数的技术。它用于在事件中省略函数的花括号;它返回一个 true 或 false 语句。同样,如果你省略 return 关键字,它也会发送完全相同的结果。
表达式将在你的脚本中的参数列表之后快速评估,通过省略花括号和 return 关键字。
这里有一个示例:
Let student=function(a)
A+1, yes
Function()
True,no
它的行为类似于函数。它们通过花括号和 return 语句定义。当我们要将函数作为参数传递给另一个函数时,这非常有用。
多重捕获子句
在 JavaScript 中,try/catch 语句用于处理 try 代码块中存在的异常。
try 子句
在 try 块中,执行要评估的语句。
提示
如果你想故意抛出异常,我们将使用 throw 语句。这将中止剩余语句的执行,并将控制权转移到 catch 块。
catch 子句
在检查 try 块中的语句并遇到错误后,将调用异常块。如果遇到的异常与 catch 块中处理的异常相同,则控制立即转移到 catch 块,并执行 catch 块内的语句。
在错误语句之后呈现的语句将不会执行,除非 finally 块中有 return 语句。
提示
一个好的做法是,如果我们预计可能会发生任何异常,首先使用条件 catch 子句。无条件 catch 子句放在最后,以处理所有剩余的异常:
try {
demotrycatchfunction(); // may throw any type of exceptions
}
catch (e) {
if (e instanceofReferenceError) {
// statements to handle ReferenceErrorexceptions
} else if (e instanceofSyntaxError
) {
// statements to handle SyntaxError exceptions
}
else if (e instanceofEvalError) {
// statements to handle EvalError exceptions
}
else {
// statements to handle any unspecified exceptions
logMyError(e); // pass the exception object to the error handler
}
}
finally 子句
无论是否发生异常,此块都将执行末尾存在的语句。finally 块中的语句无论是否发生错误都会执行。finally 块通常包含必须执行的代码。因此,我们通常在 finally 块中释放资源并关闭连接。编写简单的 try-catch-finally 块的语法如下:
try {
//try code - This is the Code block to try
}
catch(error) {
//catch code – This is the Code block that handle errors
}
finally {
//finally code - This is the Code block to be executed regardless of try catch results
}
我们也可以用嵌套的 catch 块来写,如下所示:
try {
//do something
}
catch (Exception e) {
try {
//do something with little likeliness of output
}
catch (Exception ex) {
try {
//do the minimum acceptable
}
catch (Exception e1) {
//More try catches?
}
}
}
这里有一个示例,展示了多重 catch 子句的工作原理:
functionCheckEligibility(Age) {
var result;
try { //try block
if (Age < 16 { //condition to be tested
throw new Error("Children below the age of 16 are not allowed. Parent Supervision needed!"); //incase of false result, an error will be raised
}
result = age;
}
catch (e) { //catch block
console.log(e.toString()); //error is converted to string and logged into the console
throw e; //Uncaught Error
}
finally { // finally block - It will run in the end regardless of the try, catch results
console.log("Age doesn't matter!");
}
return result;
};
让我们传递 14 作为函数的参数,如下所示:
CheckEligibility(14);
输出将如下所示:
Children below the age of 16 are not allowed. Parent Supervision needed!
注意
在 try-catch 语句中,我们必须至少有一个 finally 或 try-catch 块。try 不一定需要一个 catch 子句。如果一个 try 语句不包含至少一个 catch 块,它必须包含一个 finally 块。与 try-catch-finally 一起的可能异常处理子句是 try-catch、try-finally 或 try-catch-finally 子句。
E4X – ECMAScript for XML
它是 JavaScript 对 XML 扩展的支持的扩展。通过使用 E4x,它通过 DOM 接口提供了对 XML 文档的便捷访问。它是一种在Rhino和SpiderMonkey中使用的服务器端技术,因为这些是所有浏览器都提供的强大扩展。
在 E4X 之前,读取和写入 XML 非常困难且耗时。在 JavaScript 中,E$X 提供 XML 文档作为 XML 对象,它将 XML 片段表示为xmlList。E4X 支持特殊的 XML 对象。这种技术在客户端编程中得到了应用。
下面是一个示例:
varstudent=<student>
<studentInfo>
<name>Ali</name></studentInfo>
</student>
如果我们将此 XML 输入到我们的 JavaScript 代码中,E4X 解释器将将其作为脚本中的 XML 对象处理。
ECMAScript 6 特性
ECMAScript 6,也称为ECMAScript 2015,是 ECMAScript 标准的最新形式。ES6 是对语言的重大升级,也是自 2011 年 6 月发布 ES5.1 以来的第一次语言更新。
ES6 的一些新特性包括:
-
箭头函数
-
类
-
增强对象字面量
-
解构赋值
-
扩展参数处理
-
生成器
-
模块
-
代理
我们将在接下来的章节中查看所有这些函数。
箭头函数
箭头函数也称为肥箭头函数。它是一个函数,类似于我们在 C#、Java 和 Coffee Script 中使用的函数。箭头支持语句和表达式体。箭头的词法与其周围的代码相似。这在函数中是不一样的。
如其名所示,箭头函数使用更短的语法,即箭头(=>),用于定义和语法。
例如,看看下面的示例:
// An empty arrow function returns undefined
let empty =()=>{};
(()=>"pine")()// returns "pine"
var simple = a => a >20?20: a;
simple(20);// 20
simple(10);// 10
let max =(a, b)=> a > b ?a : b;
// Easy array filtering, mapping, ...
varsampleArray=[7,4,1,0,3,5,11];
var sum =sampleArray.reduce((a, b)=> a + b);// The answer is 29
var even =sampleArray.filter(v => v %2==0);// The answer is [4, 0]
var odd =sampleArray.filter(v => v %2!=0);// The answer is [7, 1, 3, 5, 11]
var double =sampleArray.map(v => v *2);// The answer is[14, 8, 2, 0, 6, 10, 22]
与函数表达式相比,箭头函数表达式或肥箭头函数在语法上更短。箭头函数用于绑定 this 的值。(它不绑定自己的arguments、super、this或new.target)。箭头函数是无名的。
yield关键字用于暂停和恢复生成器函数(使用带星号的function*关键字定义的返回Generator对象的生成器函数)。
类
ES6 类的语法比基于原型的面向对象模式的区域语法糖更简单、更容易使用。这是一种语法糖。一次性声明使类模式更容易使用,并简化了类模式的使用。类支持构造函数、实例、基于原型的继承、静态方法和超类调用。
下面是一个在 ES6 和 ES5 中编写类的示例:
//ES5
functionsomeES5Class(fname, age) { // standard way to create an object prototype i.e. constructor function
this.fname = fname;
this.age = age;
}
someES5Class.prototype.sayName = function() { //prototype property enables us to add new functions to an existing prototype
console.log(this.fname);
}
someES5Class.prototype.sayAge = function() { //prototype property enables us to add new functions to an existing prototype
console.log(this.age);
}
varmyInstance = new someES5Class('Talha', 25); //new keyword is used with a constructor function to create new objects from the same prototype
myInstance.sayName(); //the new method can then be called as a regular member
myInstance.sayAge();
/*Output:
Talha
25*/
//ES6
classsomeES6Class { // ES6 class
constructor(fname, age) { // a constructor is defined with default parameters
this.fname = fname;
this.age = age;
}
sayName() { //functions can be added to the class
console.log(this.fname);
}
sayAge() { //functions can be added to the class
console.log(this.age);
}
}
varmyInstance = new someES6Class('Talha', 25); //new keyword is used to create new objects from the class
myInstance.sayName(); //functions are the class members and can be called directly
myInstance.sayAge();
/*Output:
Talha
25*/
增强对象字面量
对象字面量是 JavaScript 中最流行的模式之一。JSON 基于对象字面量。其受欢迎的原因在于它提供了一种非常快速、简洁、整洁的方式来执行key:value赋值、定义方法、评估表达式和进行超类调用。ES6 以各种方式扩展了对象字面量语法。这使得它们更有用。这里解释了对象字面量的两种扩展类型。
属性初始化简写
在 ECMAScript 5 中,对象字面量是一组以逗号分隔的 name:value 对。在初始化属性值时,存在重复的可能性。
这里有一个例子:
functioncreateStudent(StudentID, name, class) {
return {
StudentID: StudentID,
name: name,
class: class,
};
}
在前面的例子中,createStudent() 函数创建了一个 student 对象,其 name 和 class 属性与函数参数相似。这导致了 name 和 class 属性的重复,尽管它们的行为不同。
为了纠正这一点,ECMAScript 6 中引入了初始化器简写属性。这消除了属性名和局部变量之间重复的所有可能性。
例如,createStudent() 可以修改如下:
functioncreateStudent(StudentID, name, class) {
return {
StudentID,
name,
class,
};
}
如果属性名将与属性值相同,则可以简单地包含属性名而不加冒号和值。
如果对象字面量的属性没有值,JavaScript 引擎会在周围搜索具有相同名称的变量。如果搜索过程成功,则将值分配给对象字面量中的相同属性名。
方法初始化器简写
随着 ECMAScript 6 的出现,许多事情得到了改进,使得网页开发者的工作变得更加简单。对象字面量中编写方法的语法得到了极大的改善。在 ECMAScript 5 中,我们需要指定一个名称并立即编写完整的函数定义。
这里有一个例子:
varcustomer = {
name: "Samantha",
logName: function() {
console.log(this.name);
}
};
在 ECMAScript 6 中,语法变得更容易编写。冒号和函数关键字已被移除。相同的示例可以重写如下:
varcustomer = {
name: "Samantha",
logName() {
console.log(this.name);
}
};
person.logName();varobject = {
// __prototype__
__prototype__: theProtoTypeObj,
// Shorthand for 'handler: handler'
handler,
// Methods
toString() {
// Super calls
return "x " + super.toString();
},
// Dynamic property names
[ 'property_' + (() => 20)() ]: 20
};
模板字符串
模板字符串通过语法糖增强了 ECMAScript,用于构建字符串。这个组件类似于 Perl、Python 等语言中的字符串插入高亮。你同样可以添加一个标签来允许重用字符串开发,避免和防止注入攻击或从字符串内容构建复杂的数据结构。它们还使我们能够创建领域特定语言(DSLs)以安全的方式处理内容。
与向 JavaScript 字符串添加更多扩展功能不同,模板字符串提供了一种全新的字符串插值方法。
基础知识
模板字符串的最简单格式如下:
literal${substitution_variable}literal
这是模板字符串的最基本形式,它执行替换操作。
模板字符串用反引号(`)而不是单引号或双引号括起来。这里有一个例子:
letbasic_string = `Kung Fu Panda`;
console.log(basic_string); // "Kung Fu Panda"
console.log(typeofbasic_string); // "string"
console.log(basic_string.length); // 13
在这个例子中,basic_string 变量包含一个简单的 JavaScript 字符串。模板字符串语法仅用于创建字符串值,然后将其分配给 basic_string。
如果需要在字符串中使用反引号,则可以使用反斜杠(\)进行转义:
letbasic_string = `\`Kung Fu\` Panda.`; // `Kung Fu' Panda
多行字符串
在这种类型的字符串中,我们可以在单行代码中添加多行。要在字符串中插入新行,我们必须在字符串中手动包含 \n,如下所示:
letmultiline_string = "Kung Fu Panda, \n\
Releasing in 2016";
console.log(multiline_string);
这的结果是:
Kung Fu Panda
Releasing in 2016
我们需要小心空格,因为反引号内的空格被认为是字符串的一部分。所有在第二行之前的空格都被认为是字符串的一部分。
解构赋值
在 JavaScript 中,解构意味着模式匹配。在 ES6 中,我们可以在对象和数组中进行高效的模式匹配。以前,这是一个漫长且复杂的过程。以下是一些在客户端控制台编写的有效示例。
从对象和数组中获取数据在 JavaScript 中非常常见。对象属性通常存储在局部变量中以实现即时访问。让我们看看以下代码片段:
var settings = {
replay: true,
save: false
};
// later
varlocalReplay = options.replay,
localSave = options.save;
ES6 通过引入解构赋值使这变得更加容易,它遍历一个对象或数组,并将指定的值存储在局部变量中。它允许使用模式匹配来绑定对象和数组。
数组解构
所有变量可以一次性初始化和交换,而不是传统的创建临时变量的方式:
var [ first, last ] = ["one", "hundred"] // initialize
console.log(first + " to " + last); // one to hundred
[first, last] = [last, first] // variable swapping
console.log(first + " to " + last); // hundred to one
使用数组解构可以轻松地从函数返回多个值。我们不必围绕一个对象进行包装。要跳过变量,可以留空数组元素的位子:
function dob() {
return [29, "November", 1990, "Thursday"];
}
var [date, month, year, day] = dob();
console.log("My date of birth is on " + date + " " + month); // My date of birth is on 29 November
对象解构
由于解构,变量也可以从函数返回的对象中初始化,即使对象嵌套很深。
解构允许变量从具有深层嵌套对象的函数返回的对象中初始化。就像数组解构一样,我们可以跳过不需要的变量。以下是有效代码片段:
function dob() {
return {
date: 29,
month: "November",
year: 1990,
time: {
hour: 12, // nested
minute: 35,
meridian: "AM"
}
};
}
var { date: d, month: m, time : { hour: h, meridian: p } } = dob();
// h is the nested property while year and minute is skipped
console.log("I was born on " + d + " " + m + " at " + h + " " + p); // I was born on 29 November at 12 AM
扩展参数处理
函数是任何语言的一个重要和基本的部分。ES6 在函数方面引入了许多增量改进。这使得它们更不容易出错,并且更强大。
函数允许传递任意数量的参数,无论函数定义中参数的数量是多少。这些参数可以传递给函数的三种类型如下:
-
默认值
-
剩余参数
-
展开运算符
默认参数
ES6 允许我们设置默认参数。具有默认值的参数被认为是可选的。它将尾随参数绑定到一个数组上:
function multiply(x, y) {
y = typeofy !== 'undefined' ? y : 1;
returnx*y;
}
multiply(10);
剩余参数
剩余参数取代了arguments的需要,并更直接地解决了常见情况。剩余参数由三个点(…)在参数之前表示。
这里有一个展示剩余参数的例子:
//Rest Parameter
function sum(…nums) {
var result = 0;
nums.forEach(function(number) {
result += number;
});
return result;
}
console.log(sum(1)); // 1
console.log(sum(1, 2, 3)); // 6
命名参数变成一个包含剩余参数的数组。添加多个命名参数可能会导致语法错误。
展开运算符
展开运算符与剩余参数非常相似,但它允许我们将数组拆分为单独的参数,然后作为单独的参数传递给函数。
这里有一个展示展开运算符的例子:
//Spread Operator
functionsum2(a, b, c) {
return a + b + c;
}
varargs = [1, 2];
console.log(sum(…args, …args, 3)); // 6
这里有一个展示默认、剩余和展开参数使用的例子:
function sum() {
return ;
}
console.log(sum(
(1, 2)
//Spread Operator
//Rest Parameter
//Default Parameter Values
//Default Parameter Values
functioninc(num, increment = 1) {
returnnum + increment;
}
console.log(inc(2, 2)); // 4
console.log(inc(4)); // 5
绑定
let 关键字是一个新的 var。let 关键字的声明语法与 var 相同。您基本上可以用 let 替换 var 来声明一个变量,但保持其作用域在当前代码中:
functiongetCuisine(condition) {
if (condition) {
letcuisine = "Mediterranean";
// other code
returncuisine;
}
else {
// cuisine does not exist here
return null;
}
// cuisine does not exist here
}
使用 const 定义的变量被认为是常量,因此一旦设置值后就不能更改。因此,每个 const 变量都必须进行初始化:
// Valid constant
const ITEMS = 10;
// Syntax error: missing initialization
const ITEM;
迭代器和 for...of 操作符
我们使用迭代器来允许自定义对象的迭代方法/行为,例如 CLRIE 可数或 Java Iterable。将 for..in 操作符泛化到基于自定义迭代器的迭代,使用 for..of。迭代器是 ECMAScript 6 的一个重要特性。当与新的数组方法和新的集合类型(例如集合和映射)结合使用时,迭代器对于数据的高效处理变得更加重要。
斐波那契数,或斐波那契排列,是伴随的整数序列中的数:
let fibonacci = {
[Symbol.iterator]() {
let x = 0, y = 1;
return {
next() {
[x, y] = [y, x + y];
return { done: false, value: y }
}
}
}
}
for (vari of fibonacci) {
// truncate the sequence at 3000
if (i> 3000)
break;
console.log(i);
}
生成器
自定义迭代器是一个有用的工具,但它需要仔细编程,以便可以显式地维护其内部状态。ES6 引入了生成器,它提供了一个强大的替代方案。生成器允许我们通过编写单个函数来创建迭代算法。这个单函数能够维护其自己的状态。
生成器 是一个返回迭代器的函数。生成器 函数通过在函数关键字后嵌入一个星号 (*) 来表示。如果一个普通函数包含一个 yield 表达式并使用 function* 语法,它就变成了一个生成器。
小贴士
在 function 关键字和星号之间是否有空格无关紧要。
在生成器函数中使用 yield 关键字来指示在调用 next() 方法时迭代器必须返回的特性。因此,如果您需要为 next() 的每次递进调用返回唯一值:
我们可以将之前的迭代器示例转换为使用生成器,如下所示:
let fibonacci = {
*[Symbol.iterator]() {
let prex = 0, cury = 1
for (;;) {
[ prex, cury ] = [ cury, prex+curv ] = [
yield cury
}
}
}
for (let ni of fibonacci) {
if (ni> 3000)
break
console.log(ni)
}
更好的 Unicode 支持
ES6 支持 Unicode,包括字符串中的新 Unicode 字面量形式,新的 RegExp u 模式来处理代码点,以及新的 API 来处理 21 位代码点级别的字符串。这些更新使我们能够在 JavaScript 中创建全局应用程序。ECMAScript 6 强制字符串使用 UTF 编码。
支持的 Unicode 示例如下:
// same as ECMAScript 5
"▯".length == 2
// new RegExpbehaviour, opt-in 'u'
"▯".match(/./u)[0].length == 2
// new form
"\u{1D306}"=="▯"=="\uD834\uDF06"
// new String ops
"▯".codePointAt(0) == 0x20BB7
// for-of iterates code points
for(var c of "▯") {
console.log(c);
}
模块
ECMAScript 6 允许我们在模块之间导出和导入符号,而不会污染全局命名空间。它为组件定义提供了额外的模块支持。运行时行为由宿主定义的默认加载器定义。它是一个隐式异步模型;除非必要的模块可用并处理,否则不会执行任何代码:
export function sum(x, y, {
return x + y
}
console.log("4π = " + math.sum(math.pi, math.pi, math.pi, math.pi));
console.log("2π = " + sum(pi, pi));
一些额外的功能包括 export default 和 export *,如下代码片段所示:
exportvar e = 2.71828182846;
export default function(x) {
returnMath.log(x);
}
console.log("2π = " + ln(e)*pi*2);
模块加载器
模块加载器主要用于解析模块指定符、加载模块等。它们负责下载所需的模块并异步绑定它们。这揭示了客户端脚本的依赖关系。构造函数是Reflect.Loader。
模块加载器支持:
-
编译钩子
-
嵌套虚拟化
-
动态加载
-
全局命名空间隔离
-
状态隔离
加载器方法
-
System.module(source, options?):这个方法用于评估源中的 JavaScript 代码到一个模块(通过保证非并发地交付和返回) -
System.set(name, module):这个方法用于注册由System.module()创建的模块 -
System.define(name, source, options?):这个方法用于评估源中的模块代码并注册结果
我们可以配置默认模块加载器,并构建新的加载器来评估和加载隔离或受限上下文中的代码:
System.import('libraries/math').then(function(mx) {
console.log("π = " + (mx.pi));
});
// Create execution sandboxes – new Loaders
var loader = new Loader({
global: fixup(window)
});
loader.eval("console.log('live to code!');");
// Directly manipulate module cache
System.get('jquery');
System.set('jquery', Module({$: $}));
集合
集合在 JavaScript 中用于创建任何类型的唯一值集合。在值集合中,你也可以添加和移除值。集合中没有直接访问值的方式,它们是数组类型。
在 ECMAScript 6 中,集合是存储数据的一种新的高效方式。JavaScript 数组与其他编程语言的数组类似,具有索引。通过使用这些数组,你可以提取双倍和三倍数据,也可以堆叠数据。JavaScript 中有许多新的集合类型。以下是一些示例:
-
集合
-
映射
-
WeakMap
-
WeakSet
集合
一个set有一个唯一的值集合。集合的唯一值也是对象引用类型。集合中的值不能重复。在从set访问值之前,你需要检查这些值是否存在。
我们可以在set中添加值,也可以检查set中值的数量。以下是一个示例:
Var students=new set();
Students.add(10);
Students.add("Ali");
映射
map对象是一个键/值映射。map中的任何值都可以用作键或值。元素可以在map中以插入顺序迭代,并返回一个包含值或键的数组。map有两个属性:
-
Map.length:返回map中元素的数量 -
Map.prototype:Map.prototype属性代表map构造函数的原型
这里是map对象的一些方法。
Map.prototype.clear()
clear()方法用于从map对象中移除所有元素。
返回值
它不返回任何内容。
参数
没有输入参数。
描述
使用此函数后,我们在 map 上初始化的所有内容都将被清除。该函数没有参数,也不返回任何内容,因为它会清除所有内容。
这里是这个方法的示例:
varmyMap=newMap();
myMap.set("pine","apple");
myMap.set(1,"apple");
myMap.size;// 2
myMap.has("cone");// will return false
myMap.has("pine")// will return true
Map.prototype.delete()
delete()方法用于从Map对象中移除指定的元素。
返回值
如果 map 对象中的组件存在并且已被移除,则返回true。如果组件不存在,则返回false。
参数
需要一个键。这里的键基本上是要移除的元素。
描述
这与 map.prototype.clear() 不同,因为它明确地删除了特定的元素,而不是删除映射上的每个元素。我们传递一个键(要删除的元素),函数根据键返回 true 或 false。
这里是此方法的示例:
varmyMap=newMap();
myMap.set("pine","apple");
myMap.delete("apple");// Returns true. Successfully removed.
myMap.has("apple");// Returns false. The "apple" element is no longer present.
Map.prototype.entries()
此函数用于告诉我们映射上元素的键和值。
返回值
它返回一个包含映射上每个元素键和值的新的 iterator 对象。
参数
没有输入参数。
描述
此函数用于让我们了解映射上组件的键和值。
这里是此方法的示例:
varmyMap=newMap();
myMap.set("0","pine");
myMap.set(1,"apple");
myMap.set({},"cone");
varmapIter=myMap.entries();
console.log(mapIter.next().value);// ["0", "pine"]
console.log(mapIter.next().value);// [1, "apple"]
console.log(mapIter.next().value);// [Object, "cone"]
Map.prototype.forEach()
forEach 方法在映射对象中的每个键/值对上执行给定的回调一次。
返回值
它不返回任何内容。
参数
有三个参数:元素 value、元素 key 和正在遍历的 map 对象。
描述
forEach 策略对指南中实际存在的每个键执行给定的回调一次。它不针对已删除的键进行构造。不过,它会对可用的值执行;然而,它们具有定义的值。
这里是此方法的示例:
functionlogMapElements(value, key, map) {
console.log("m["+ key +"] = "+ value);
}
Map([["foo",3],["apple",{}],["cone", undefined]]).forEach(logMapElements);
// logs:
// "m[pine] = 3"
// "m[apple] = [object Object]"
// "m[cone] = undefined"
Map.prototype.get()
使用 get() 方法返回映射中的特定元素。
返回值
它返回用作参数的键(仅在映射中找到时);否则,它返回错误信息。
参数
它需要一个从映射中返回的键。
描述
我们输入一个想要在映射中找到的键,函数返回它。当我们要获取元素的值时使用。
这里是此方法的示例:
varmyMap=newMap();
myMap.set("apple","pine");
myMap.get("apple");// Returns "apple".
myMap.get("cone");// Returns undefined.
Map.prototype.has()
如果元素存在,则函数返回 true(布尔值),如果不存在,则返回 false。
返回值
如果在 map 对象中存在具有指定键的组件,则返回 true。如果没有找到,则返回 false。
参数
需要一个键。
描述
我们在函数中传递一个键来检查某个元素是否存在于映射中。如果元素存在,则返回 true;否则,返回 false。
这里是此方法的示例:
varmyMap=newMap();
myMap.set("apple","pine");
myMap.has("apple");// returns true
myMap.has("cone");// returns false
Map.prototype.keys()
它返回映射中每个元素的键。
返回值
它返回一个新对象,该对象包含映射上所有元素的键。
参数
没有输入参数。
描述
keys() 策略返回另一个 iterator 对象,该对象包含 map 对象中每个组件的键,按插入顺序排列。
此方法的示例如下:
varmyMap=newMap();
myMap.set("0","pine");
myMap.set(1,"apple");
myMap.set({},"cone");
varmapIter=myMap.keys();
console.log(mapIter.next().value);// "0"
console.log(mapIter.next().value);// 1
console.log(mapIter.next().value);// Object
Map.prototype.set()
这是向映射中添加新元素的程序。
返回值
它返回 map 对象。
参数
这是将要添加到映射中的元素的键。
描述
set() 策略将具有预定键和值的另一个组件包含到 map 对象中。
此方法的示例如下:
varmyMap=newMap();
// Add new elements to the map
myMap.set("apple","pine");
myMap.set(1,"pineapple");
// Update an element in the map
myMap.set("apple","custard");
Map.prototype.values()
这是获取包含每个元素值的新的对象的方法。
返回值
它返回一个对象,该对象包含映射上所有组件的值。
参数
没有输入参数。
描述
values() 技术返回另一个 iterator 对象,该对象包含 map 对象中每个组件的值,以插入顺序返回。
这里是这个方法的例子:
varmyMap = new Map();
varkeyObj = {},
keyFunc = function () {},
keyString = "This is a sample string";
// setting the values
myMap.set(keyString, "value associated to 'This is a sample string'");
myMap.set(keyObj, "value associated to a keyObj");
myMap.set(keyFunc, "value associated to a keyFunc");
myMap.size; // 3
// getting the values
myMap.get(keyString); // "value associated to 'This is a sample string'"
myMap.get(keyObj); // "value associated to a keyObj"
myMap.get(keyFunc); // "value associated to a keyFunc"
myMap.get("a string"); // "value associated to 'This is a sample string'"
// because keyString === 'a string'
myMap.get({}); // undefined, because keyObj !== {}
myMap.get(function() {}) // undefined, because keyFunc !== function () {}
WeakMap
它与 map 相同,但有一些区别。它只接受对象作为键。不允许在 WeakMap 中使用原始数据类型。由于 WeakMap 不引用像键一样的对象,因此没有垃圾回收。由于这些差异,没有方法可以访问 WeakMap 中的键。
注意
WeakMap 中的键不可枚举,这意味着没有方法可以给你一个键的列表。WeakMap 中有大小属性可用。
这里有一个例子:
varmyWeakMap1 = new WeakMap(),
myWeakMap2 = new WeakMap(),
varo1 = {},
o2 = function(){},
o3 = window;
myWeakMap1.set(o1, 37);
myWeakMap1.set(o2, "pineapple");
myWeakMap2.set(o1, o2);
myWeakMap2.set(o3, undefined);
myWeakMap2.set(myWeakMap1, myWeakMap2);
myWeakMap1.get(o2); // "pineapple"
myWeakMap2.get(o2); // undefined, because there is no value for o2 on myWeakMap2
myWeakMap2.get(o3); // undefined, because that is the set value
myWeakMap1.has(o2); // will return true
myWeakMap2.has(o2); // will return false
myWeakMap2.has(o3); // will return true
myWeakMap1.has(o1); // will return true
myWeakMap1.delete(o1);
myWeakMap1.has(o1); // will return false
WeakMap.prototype.clear()
这用于从 WeakMap 中移除所有元素。现在已过时,但仍然在一些浏览器中使用。
返回值
它返回要从中删除的 WeakMap 对象的键。
参数
这是需要从 WeakMap 对象中删除的元素的键。
描述
这里有一个例子:
varwm = new WeakMap();
varobject = {};
wm.set(object, "pine");
wm.set(window, "apple");
wm.has(object); // will return true
wm.has(window); // will return true
wm.clear();
wm.has(object) // will return false
wm.has(window) // will return false
WeakMap.prototype.delete()
此方法用于从 WeakMap 中删除特定对象。
返回值
如果 WeakMap 对象中的元素已成功删除,则返回 true。
参数
这是需要从 WeakMap 对象中删除的元素的键。
描述
delete() 方法从 WeakMap 对象中删除指定的元素。
这里有一个例子:
varwm = new WeakMap();
wm.set(window, "pineapple");
wm.delete(window); // Returns true. Successfully removed.
wm.has(window); // Returns false. The window object is no longer in the WeakMap.
WeakMap.prototype.get()
此方法用于从 WeakMap 中检索特定对象。
返回值
它返回与指定键关联的元素,如果键在 WeakMap 对象中找不到,则返回 undefined。
参数
这是返回自 WeakMap 对象的元素的键。
描述
返回 WeakMap 对象中元素的键。
这里有一个例子:
varwm = new WeakMap();
wm.set(window, "pine");
wm.get(window); // Returns "pine".
wm.get("apple"); // Returns undefined.
WeakMap.prototype.has()
此方法用于检查指定对象是否存在于 WeakMap 中。
返回值
如果 WeakMap 对象中存在具有指定键的元素,则返回 true;否则返回 false。
参数
它是要在 WeakMap 对象中测试是否存在的关键的键。
描述
has() 方法返回一个布尔值,指示具有指定键的元素是否存在于 WeakMap 对象中。
这里有一个例子:
varwm = new WeakMap();
wm.set(window, "pine");
wm.has(window); // returns true
wm.has("apple"); // returns false
WeakMap.prototype.set()
此方法用于将对象添加到特定位置。
返回值
WeakMap 对象。
参数
-
Key:要添加到WeakMap对象中的元素的键 -
Value:要添加到WeakMap对象中的元素的值
描述
set() 方法向 WeakMap 对象添加具有指定键和值的新元素。
这里有一个例子:
varwm = new WeakMap();
varobject = {};
// Add new elements to the WeakMap
wm.set(object, "pine").set(window, "apple"); // chainable
// Update an element in the WeakMap
wm.set(object, "cone");
Weakset
这是一个不阻止其元素被垃圾回收的对象集合。在 WeakSet 中没有循环、迭代和学习。它有三个方法。
WeakSet.prototype.add(someValue)
此方法将新对象追加到 WeakSet 的末尾。
返回
WeakSet.prototype.add(someValue) 方法返回 Nothing
参数
要添加到 WeakSet 集合中的对象。
描述
add() 方法将新对象追加到 WeakSet 对象的末尾。
下面是这个方法的示例:
varmyWeakSet=newWeakSet();
myWeakSet.add(window);// add the window object to the WeakSet created above
myWeakSet.has(window);// will return true
WeakSet.prototype.delete(someValue)
此方法从 WeakSet 中删除指定的对象。
返回
如果在 WeakSet 中找到值并将其删除,则返回 true。如果找不到值,则返回 false。
参数
要删除的值作为参数发送。
描述
delete() 策略从 WeakSet 对象中移除预定义的元素。在我们需要从 WeakSet 中删除某些元素时使用。
此方法的示例如下:
varmyWeakSet=newWeakSet();
varmyObject={};
myWeakSet.add(window);
myWeakSet.delete(myObject);// Will return false
myWeakSet.delete(window);// Will return true.
myWeakSet.has(window);// Will return false.
WeakSet.prototype.has(someValue)
如果对象存在于 WeakSet 中,则此方法将返回 true;否则返回 false。
返回
如果 WeakSet 对象中存在具有预定义值的组件,则返回 true;否则返回 false。
参数
需要一个要搜索的值。
描述
has() 技术返回一个布尔值,表明项目是否存在于 WeakSet 中。
下面是这个方法的示例:
varws=newWeakSet();
varobject={};
ws.add(window);
mySet.has(window); // will return true
mySet.has(object); // will return false
它只有任意值。在 WeakSet 对象中以弱引用方式持有对象的引用。它们也可以是垃圾收集器。由于垃圾收集器,WeakSet 中没有当前对象的列表。这些对象是不可枚举的。
这里有一个例子:
// Sets
varmySet = new Set();
mySet.add("apple").add("candy");
mySet.size === 2;
mySet.has("hello") === false;
// Maps
varmyMap = new Map();
myMap.set("boy", 27);
myMap.set(f, 25);
myMap.get(f) == 25;
// Weak Maps
varmyWeakMap = new WeakMap();
myWeakMap.set(s, { extra: 99 });
myWeakMap.size === undefined
// Weak Sets
varmyWeakSet = new WeakSet();
myWeakSet.add({ data: 99 });
代理
代理允许以广泛的行为创建对象,这些行为可用于宿主对象。它们可用于对象虚拟化、拦截、日志/分析等。代理为开发者提供了前所未有的对象控制能力,以及定义新交互模式的无限可能性。
这里有一个例子:
vartargetObject = {};
varhandlerObject = {
get: function (receiver, book) {
return `Title, ${name}!`;
}
};
varproxyObject = new Proxy(target, handler);
proxyObject.world === 'Lahore!';
// Proxying a function object
vartargetObject = function () { return 'Target, I am'; };
varhandlerObject = {
apply: function (receiver, ...args) {
return 'Le proxy';
}
};
var p = new Proxy(target, handler);
p() === 'Le proxy';
符号
符号是一种独特类型,可以用作对象属性的标识符。符号对象是对符号原始数据类型的隐式对象包装。
这里是如何创建一个新的原始符号:
var symb = Symbol();
或者
var symb = Symbol('abc');
以下代码创建了两个新的符号。Symbol('abc') 并不强制将 abc 转换为对象,而是创建了一个新的独立对象。
Symbol('abc') === Symbol('abc'); //false
使用 Symbol() 与 new 关键字会抛出类型错误。
var symb = new Symbol(); // TypeError
这防止了创建显式的符号包装对象而不是新的符号值。在 ES5 之前,仅支持在原始数据类型周围创建显式包装对象。然而,出于历史原因,仍然可以创建新的原始包装对象,如 new Boolean、new String 和 new Number。
如果需要创建符号包装对象,可以使用 Object() 函数:
var symb = Symbol("abc");
typeof symb; // "symbol"
var symbObj = Object(symb);
typeof symbObj; // "object"
Object.getOwnPropertySymbols() 方法返回一个符号数组,并允许您在给定的对象上找到符号属性。
这里有一个例子:
varSomeClass = (function() {
var key = Symbol("key");
functionSomeClass(privateData) {
this[key] = privateData;
}
SomeClass.prototype = {
doStuff: function() {
... this[key] ...
}
};
returnSomeClass;
})();
var c = new SomeClass("bye")
c["key"] === undefined
注意
ECMAScript 6 标准使用特殊的符号表示法来表示符号,例如在标识符前加上 @@,如 @@create。
可继承的内置对象
在 ECMAScript 6 中,Date、Array 和 DOM 元素等内置对象可以被继承。名为 Ctor 的对象构造现在使用两个阶段:
-
调用
Ctor[@@create]以分配对象并安装任何特殊行为 -
在新实例上调用构造函数以初始化它
已知的 @@create 符号可通过 Symbol.create 获取。内置对象现在明确公开它们的 @@create 语法。
以下是一个示例:
// Pseudo-code of Array
classSomeArray {
constructor(...args) { /* ... */ }
static [Symbol.create]() {
}
}
// User code of Array subclass
classSomeArray extends Array {
constructor(...args) { super(...args); }
}
// Two-phase 'new':
// 1) Call @@create to allocate object
// 2) Invoke constructor on new instance
vararr = new SomeArray();
arr[1] = 123;
arr.length == 1
Promises
ECMAScript 6 引入了 promise。这是一个用于异步编程的库。它是对未来可能可用值的顶级表示。许多现有的 JavaScript 库已经使用了 promise。
在 ES6 中提到的关于 promise 的某些方法。
Promise.All()
此方法返回一个 promise,一旦可迭代参数中的所有 promise 都已解决,它就会解决。在拒绝的情况下,它返回第一个被拒绝的 promise 的原因。
返回
Promise.All() 方法返回空值。
参数
一个 iterable 对象,例如一个数组。
描述
Promises 返回一个值数组的结果。如果数组中的任何值不是 promise,则使用 Promise.resolve 转换它。如果传递的任何 promise 被拒绝,则所有 promise 都会被拒绝,并返回一个 promise 拒绝的原因。它丢弃所有其他 promise,无论它们是否已解决。如果传递一个空数组,则此方法立即解决。
以下是一个此方法的示例:
varprom1 = 6000;
varprom2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "Here");
});
Promise.all([prom1, prom2]).then(function(values) {
console.log(values); // [6000, "Here"]
});
Promise.prototype.catch()
此方法仅在对象被拒绝的情况下使用。它的工作方式与 promise.prototype.then() 相同。
返回
promise.prototype.catch() 方法返回空值。
参数
- 一个拒绝的: 当
promise被拒绝时调用的function。此函数有一个参数,即拒绝的原因。
描述
catch() 方法返回一个 promise 并处理拒绝的情况。它的行为类似于调用 Promise.prototype.then(undefined, onRejected)。
以下是一个此方法的示例:
varprom1= new Promise(function(resolve, reject) {
resolve('This was Successful!!');
});
prom1.then(function(value) {
console.log(value); // "This was Successful!!"
throw 'oh, no!';
}).catch(function(e) {
console.log(e); // "Error found"
}).then(function() {
console.log('Catch Done!');
}, function () {
console.log('Not fired due to the catch');
});
Promise.resolve(value)
此方法返回一个 promise 对象,该对象由指定的值解决。如果该值关联到一个 then 方法,则返回的 promise 将移动到 then 方法,采用其最终状态。否则,返回的 promise 将以指定的值实现。
返回
使用给定值的 promise 对象。
参数
让我们看看以下参数及其用法:
-
onFulfilled: 当Promise被实现时调用的function -
onRejected: 当promise被拒绝时调用的function
描述
Promise.resolve(value) 系统返回一个 Promise 对象,该对象根据给定的质量确定。如果质量是一个可 then 的(即,有一个 then 方法),则返回的 promise 将会 跟随 那个可 then 的,采用其可能的状态。
then() 技术返回一个 Promise。它接受两个参数:成功和失败实例的回调能力。
使用 then 方法
此方法的示例如下:
varprom1=newPromise(function(resolve, reject) {
resolve("This was a Success!");
// or
// reject ("Error Found Try Again!");
});
prom1.then(function(value) {
console.log(value);//This was a Success!
},function(reason){
console.log(reason);// Error Found Try Again!
});
链式调用
由于 then() 方法返回一个 Promise,您可以轻松地链式调用 then:
varp2=newPromise(function(resolve, reject) {
resolve(1);
});
p2.then(function(value) {
console.log(value);// 1
return value +1;
}).then(function(value) {
console.log(value);// 2
});
p2.then(function(value) {
console.log(value);// 1
});
您还可以使用链式调用在另一个函数之上实现一个基于承诺的 API 的函数:
functionfetch_current_data() {
returnfetch("current-data.json").then((response)=> {
if(response.headers.get("content-type")!="application/json") {
thrownewTypeError();
}
var j =response.json();
// maybe do something with j
return j;// fulfillment value given to user of
// fetch_current_data().then()
});
}
Promise.reject(value)
此函数返回一个承诺对象,该对象因传递的值/原因而被拒绝。
返回值
Promise.reject() 方法返回一个简单的输出,说明拒绝的原因。
参数
这个承诺被拒绝的原因。
描述
静态 Promise.reject() 函数能力返回一个被拒绝的 Promise。为了故障排除和特定错误查找,将原因设置为错误实例很有帮助。
此方法的示例如下:
Promise.reject("Testing Promise reject").then(function(reason) {
// not called
},function(reason) {
console.log(reason);// "Testing Promise reject"
});
Promise.reject(newError("fail")).then(function(error) {
// not called
},function(error) {
console.log(error);// Stacktrace
});
Promise.race(value)
此函数返回一个承诺,其解决或拒绝的方式与可迭代中传递的承诺相同,使用该承诺的值或原因。
返回值
Promise.race() 函数返回一个承诺。
参数
一个可迭代的对象,例如一个数组。
描述
race 函数返回一个 Promise,其解决的方式与最初传递的 Promise 相同。它确定或拒绝,哪个先发生。
此方法的示例如下:
varmyPromise1=newPromise(function(resolve, reject) {
setTimeout(resolve,800,"first");
});
varmyPromise2=newPromise(function(resolve, reject) {
setTimeout(resolve,300,"second");
});
Promise.race([myPromise1,myPromise2]).then(function(value) {
console.log(value);// "second"
// Both resolve, but myPromise2 is faster
});
核心数学库 API
ECMAScript 6 对预构建库进行了几个新的扩展,包括核心 Math 库、数组、字符串 辅助工具和用于复制的 Object.assign。这些新方法有助于加快执行过程,从而提高可能执行计算和字符串操作的应用程序的性能。它还提高了必须执行许多计算和字符串操作的应用程序的速度。
包括核心数学库、数组转换辅助工具、字符串辅助工具和用于复制的 Object.assign 在内的许多新库增加。以下是一个使用核心数学库 API 的示例:
Number.EPSILON
Number.isInteger(Infinity) // will return false
Number.isNaN("NaN") // will return false
Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
"Neptune".includes("cd") // This will return false
"Mars".repeat(4) // This will be "MarsMarsMarsMars"
Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(2, 1) // [0,2,2]
[24, 14, 23, 57, 89, 75, 33].find(x => x == 33) // 33
[24, 14, 23, 57, 89, 75, 33].findIndex(x => x == 14) // 1
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["x", "y", "z"].entries() // iterator [0, "x"], [1,"y"], [2,"z"]
["x", "y", "z"].keys() // iterator 0, 1, 2
二进制和八进制字面量
ECMAScript 6 引入了二进制和八进制字面量表示法,用于二进制(b)和八进制(o)。这两种表示法与十六进制字面量表示法类似,需要在值前添加 0x 或 0X。
新的八进制字面量格式以 0o 或 0O 开头,而新的二进制字面量格式以 0b 或 0B 开头。每种字面量类型必须后跟一个或多个数字;八进制为 0-7,二进制为 0-1。以下是一个示例:
// ECMAScript 6
varvalue11 = 0o65; // 53 in decimal
varvalue22 = 0b100; // 4 in decimal
0b111110111 === 503 // will return true
0o767 === 503 // will return true
反射 API
reflect 对象是一个包含与反射 API 相关的函数的单个对象。正如其名所示,它仅仅是对象的反射,以便可以密切观察它们,无论对象是由谁创建的。reflect 对象不是一个 function 对象。它没有 constructor 方法。它不能作为一个函数调用,因为它没有 call 方法。
Reflect API 被认为是 Proxy API 的逆操作。
这里是 reflect 对象具有的方法列表。
Reflect.get(target, prop, [receiver])
此方法允许您获取对象的属性。此方法也与属性访问器语法类似。
返回值
reflect 对象返回属性的值。
参数
参数是获取属性的 target 对象、属性名称和值。
描述
静态 Reflect.get() 方法的工作方式类似于从对象中获取属性(target[propertyKey])作为一个函数。
获取方法的示例如下:
// Object
varobject={a:4,b:5};
Reflect.get(object,"b");// 5
// Array
Reflect.get(["first","second"],1);// "second", since array starts with 0 index
// Proxy with a get handler
var x ={p:9};
varobject=newProxy(x, {
get(a,b,c){returnb +"meow";}
});
Reflect.get(object,"woof");// "woofbar"
Reflect.set(target, prop, value, [receiver])
此方法允许您设置对象的属性。此方法也与属性访问器语法类似。
返回值
Reflect.set(target, prop, value, [receiver] 返回一个布尔值,指示属性设置是否成功。
参数
参数是目标对象、属性名称、要设置的值和接收者。
描述
静态 Reflect.set() 策略的工作方式类似于在项上设置属性。
此方法的示例如下所示:
// Object
varobject={};
Reflect.set(object,"property","value");// will return true
object.property;// "value"
// Array
vararr=["cow","cow","cow"];
Reflect.set(arr,1,"goat");// will return true
arr[1];// "goat"
// It can truncate an array.
Reflect.set(arr,"length",1);// will return true
arr;// ["goat"];
// With just one argument, propertyKey and value are "undefined".
varobject={};
Reflect.set(object);// will return true
Reflect.getOwnPropertyDescriptor(object,"undefined");
// { value: undefined, writable: true, enumerable: true, configurable: true }
Reflect.has(target, prop)
此方法允许您检查一个对象是否具有特定的属性。此方法与 in 操作符类似。
返回值
Reflect.has(target, prop) 返回一个布尔值,指示目标是否具有属性。
参数
将目标对象和属性键(要检查的属性名称)传递。
描述
静态 Reflect.has() 技术作为函数类似于 in 操作符。
此方法的示例如下所示:
Reflect.has({a:0},"a");// will return true
Reflect.has({a:0},"b");// will return false
// returns true for properties in the prototype chain
Reflect.has({a:0},"toString");
// Proxy with .has() handler method
object=newProxy({}, {
has(s,d){returns.startsWith("cat");}
});
Reflect.has(object,"catastrophe");// will return true
Reflect.has(object,"camel");// will return false
Reflect.apply(target, receiver, args)
此方法用于使用指定的一组参数调用目标函数。
返回值
Reflect.apply(target, receiver, args) 方法不返回任何内容。
参数
要调用的目标函数。thisArgument 和 ArgumentList 作为参数传递。
描述
静态 Reflect.apply() 技术使用指定的参数调用目标函数。
此方法的示例如下所示:
Reflect.apply(Math.floor, undefined,[3.999]);
// 3;
Reflect.apply(String.fromCharCode, undefined,[80, 97, 107, 105, 115, 116, 97, 110]);
// "Pakistan"
Reflect.apply("".charAt,"stars",[2]);
// "a"
Reflect.construct(target, args)
此方法允许您使用多个参数调用 constructor 函数。它就像调用 new 函数(…args)一样。
返回值
Reflect.construct(target, args) 不返回任何内容。
参数
要调用的目标函数、参数列表和新目标(要使用的构造函数)是参数。
描述
Reflect.construct 方法允许您使用可变数量的内容(这也可以使用与 new 操作符结合的展开运算符来实现)来构造构造函数。
此方法的示例如下所示:
使用 Reflect.construct():
var d =Reflect.construct(Date,[2015,1,5]);
dinstanceofDate;// will return true
d.getFullYear();// 2015
使用 newTarget:
functionmyConstructor(){}
var result =Reflect.construct(Array,[],myConstructor);
Reflect.getPrototypeOf(result);// myConstructor.prototype
Array.isArray(result);// will return true
Reflect.getOwnPropertyDescriptor(target, prop)
此方法类似于 Object.getOwnPropertyDescriptor()。如果该属性存在于对象上,此方法将返回该属性的属性描述符;否则,返回 undefined。这两个方法之间的唯一区别是处理非对象目标的方式。
返回值
Reflect.getOwnPropertyDescriptor(target, prop) 方法返回一个属性描述符对象。
参数
要查找属性的目标对象和属性键(要应用的属性名称)是参数。
描述
Reflect.getOwnPropertyDescriptor 系统在属性存在于对象的情况下返回给定属性的属性描述符,如果属性不存在,则返回 undefined。与 Object.getOwnPropertyDescriptor() 的主要区别是处理非对象目标的方式。
此方法的示例如下:
使用 Reflect.getOwnPropertyDescriptor():
Reflect.getOwnPropertyDescriptor({a:"bye"},"a");
// {value: "bye", writable: true, enumerable: true, configurable: true}
Reflect.getOwnPropertyDescriptor({x:"bye"},"y");
// undefined
Reflect.getOwnPropertyDescriptor([],"length");
// {value: 0, writable: true, enumerable: false, configurable: false}
与 Object.getOwnPropertyDescriptor() 的区别:
如果此方法的第一个参数不是对象(原始类型),则会导致 TypeError。在 Object.getOwnPropertyDescriptor 中,非对象第一个参数最初会被强制转换为对象:
Reflect.getOwnPropertyDescriptor("woof",0);
// TypeError: "woof" is not non-null object
Object.getOwnPropertyDescriptor("dummy",0);
// { value: "d", writable: false, enumerable: true, configurable: false }
Reflect.defineProperty(target, prop, desc)
此方法类似于 Object.defineProperty()。此方法允许我们修改对象的属性。Object.defineProperty() 方法在属性成功定义后返回一个对象,如果属性定义不成功则返回类型错误。Reflect.defineProperty() 方法如果属性成功定义则返回 true,否则返回 false。
返回值
Reflect.defineProperty(target, prop, desc) 方法返回一个布尔值,表明属性是否被有效定义。
参数
目标对象、属性键和属性是参数。
描述
Reflect.defineProperty 技巧允许精确地扩展或更改对象上的属性。对于更微妙的部分,请参阅比较的 Object.defineProperty。Object.defineProperty 在属性成功定义后返回对象,如果属性定义不成功则抛出 TypeError。Reflect.defineProperty 再次,基本上返回一个布尔值,表明属性是否被有效定义。
此方法的示例如下:
使用 Reflect.defineProperty():
http://haseeb.deeurl.com/client-demos/everydayadvice/v3/={};
Reflect.defineProperty(object,"x",{value:7});// will return true
object.x;// 7
检查属性定义是否成功:
在 Object.defineProperty 中,如果成功则返回对象,否则抛出 TypeError,您会使用 try...catch 块来捕获定义属性时发生的任何错误。由于 Reflect.defineProperty 返回一个布尔成功状态,您在这里可以使用 if...else 块:
if(Reflect.defineProperty(target, property, attributes)) {
// will return success
}
else{
// will return failure
}
Reflect.getPrototypeOf(target)
此方法返回指定对象的原型。它与 Object.getPrototypeOf() 方法类似。
返回值
Reflect.getPrototypeOf(target) 方法返回对象的原型或 null。
参数
我们需要原型目标对象作为参数传入。
描述
静态Reflect.getPrototypeOf()方法与Object.getPrototypeOf()相同的技术。它返回预定项的模型(即内部[[Prototype]]属性的估计)。
此方法的示例如下:
Reflect.getPrototypeOf({});// Object.prototype
Reflect.getPrototypeOf(Object.prototype);// will return null
Reflect.getPrototypeOf(Object.create(null));// will return null
Reflect.setPrototypeOf(target, newProto)
此方法将对象的原型设置为另一个对象或 null。此方法与Object.setPrototypeOf()方法相同。
返回值
Reflect.setPrototypeOf(target, newProto)方法返回一个布尔值,表明模型是否被有效设置。
参数
目标对象和原型是参数。
描述
Reflect.setPrototypeOf方法更改指定对象的原型(即内部[[Prototype]]属性的值)。
此方法的示例如下:
Reflect.setPrototypeOf({},Object.prototype);// will return true
Reflect.setPrototypeOf({},null);// will return true
Reflect.setPrototypeOf(Object.freeze({}),null);// will return false
var target ={};
varprototype=Object.create(target);
Reflect.setPrototypeOf(target,prototype);// will return false
Reflect.deleteProperty(target, prop)
此方法用于从对象中删除属性。此方法类似于 delete 操作符作为函数。
返回值
Reflect.deleteProperty(target, prop)方法返回一个布尔值,告诉我们属性是否被删除。
参数
目标对象和要删除的属性名称是参数。
描述
Reflect.deleteProperty方法允许你在对象上删除属性。它返回一个布尔值,表示属性是否成功移除,无论该属性是否被有效定义。它与非严格 delete 操作符几乎相同。
此方法的示例如下:
varobject={a:11,b:12};
Reflect.deleteProperty(object,"a");// will return true
object;// { y: 12 }
vararr=[11,12,13,14,15];
Reflect.deleteProperty(arr,"3");// will return true
arr;// [11, 12, 13, , 15]
// Returns true if no such property exists
Reflect.deleteProperty({},"bar");// will return true
// Returns false if a property is unconfigurable
Reflect.deleteProperty(Object.freeze({bar:1}),"bar");// will return false
Reflect.enumerate(target)
此方法返回一个包含目标对象枚举自有和继承属性的迭代器。
返回值
返回一个包含目标对象枚举自有和获取属性的迭代器。
参数
函数中传入的目标对象用于获取属性。
描述
Reflect.enumerate()方法返回一个包含目标对象的枚举自有和继承属性的迭代器。
此方法的示例如下:
varobject={a:98,b:99};
for(var name ofReflect.enumerate(object)) {
console.log(name);
}
// logs "a" and "b"
Reflect.preventExtensions(target)
这与Object.preventExtensions()相同方法。它阻止我们向对象添加更多属性(扩展)。
返回值
返回一个布尔值,表明目标是否被有效设置为防止扩展。
参数
我们需要防止扩展的目标对象。
描述
静态Reflect.preventExtensions()方法阻止新属性始终被添加到对象中(即,抵消对项目的未来增强)。它类似于Object.preventExtensions(),但有一些区别。
此方法的示例如下:
varblank={};
Reflect.isExtensible(blank);// === will return true
Reflect.preventExtensions(blank);
Reflect.isExtensible(blank);// === will return false
Reflect.isExtensible(target)
此方法允许我们检查是否可以向对象添加新属性,或者对象是否可扩展。此方法类似于Object.isExtensible()方法。
返回值
一个布尔值,指示目标是否可扩展。
参数
需要检查其可扩展性的目标对象。
描述
静态 Reflect.isExtensible() 技术确定一个项是否可扩展(是否可以向它添加新属性)。它类似于 Object.isExtensible(),但有一些区别。
此方法的示例如下:
var blank ={};
Reflect.isExtensible(blank);
前面的函数将返回 true。
Reflect.ownKeys(target)
此方法返回对象的自身属性键。
返回值
Reflect.ownKeys(target) 方法返回目标对象的一个数组。
参数
从中获取键的目标对象。
描述
静态 Reflect.set() 策略的工作方式类似于在对象上设置属性。
这里是此方法的示例:
Reflect.ownKeys({a:5,b:6,c:7});
Reflect.ownKeys([]);
varsymbol=Symbol.for("dirt");
varsymbolb=Symbol.for("sky");
varobject={[symbol]:0,"string":0,"99":0,"4":0,
[symbolb]:0,"100":0,"-7":0,"second string":0};
Reflect.ownKeys(object);
尾调用
尾调用位置中的调用不会在没有限制的情况下增长堆栈。这有助于在无界输入的情况下使递归算法安全且可靠。
示例
以下函数生成传递给它的任何数字的阶乘。函数末尾有一个尾调用,它调用了函数本身。以前,我们可能会得到堆栈溢出错误,但 ES6 对处理任意输入是安全的。
如果输出超出范围,它将简单地显示无穷大:
function factorial(n, acc) {
'use strict';
if (n <= 1) return acc;
return factorial(n - 1, n * acc);
}
console.log(factorial(5, 1)); //120
console.log(factorial(200, 1)); //Infinity
// Stack overflow in most implementations today,
// but safe on arbitrary inputs in ES6
console.log(factorial(10000000, 1));
第十二章. 服务器端 JavaScript – NodeJS
Node.js 是一个相对较新的基于 JavaScript 的服务器平台。Node 的一大特点是它是一个非阻塞服务器。这意味着资源密集型任务不会占用服务器。然后 Node.js 可以处理许多并发连接。它也比阻塞服务器更容易处理实时通信。
Node.js 的主要用途之一是作为 Web 服务器。这是一个完美的任务,因为服务网页通常涉及读取文件和连接到数据库。它能够在执行这两个动作中的任何一个时服务更多客户端。这与阻塞服务器非常不同。阻塞服务器必须等待所有资源返回,然后才能响应更多请求。
Note
注意,这个参考将仅限于 Node.js 特定的;我们不会在本章中涵盖任何框架或库。
最受欢迎的框架是有用的,并且应该在可能的情况下使用,但我们的重点将仅限于 Node.js 内置的函数和模块。我们将不涉及 Express(据说是最常用的 Node.js 框架)。最重要的是,我们将涵盖 Express 及其依赖项构建的基础。
一本涵盖框架等内容的好书是 Packt Publishing 出版的 使用 Redis 和 Node.js 构建可扩展应用程序。
在本章中,将描述以下几组参考,并附上示例:
-
文件和进程管理:
-
Modules
-
OS (operating system)
-
Process
-
File
-
Path
-
REPL (Read Eval Print Loop)
-
Errors
-
-
Utilities:
-
Events
-
Crypto
-
Buffer
-
Console
-
Npm (Node Package Manager)
-
Stream
-
-
Net 模块:
-
createServer
-
net.Server
-
-
HTTP:
-
Server
-
IncomingMessage
-
ServerResponse
-
clientRequest
-
文件和进程管理
我们将开始对 Node.js 的概述,从基础知识开始。这包括加载模块、管理进程、处理文件和路径,以及 REPL (读取-评估-打印循环)。这些都是几乎任何 Node.js 项目都需要的东西。
Modules
Node.js 是一个模块化系统。Node.js 的许多功能都包含在必须在运行时加载的模块中。这使得了解加载和构建模块成为使用 Node 的核心要求。以下是你可以用于你的 Node 模块的参考:
-
require() -
modules.export
require()
这将在给定路径加载模块:
require(path)
返回值
返回值将是一个对象。这个对象的属性将根据加载的内容而变化。我们将在下一节介绍 module.exports,这是模块设计者和甚至你可以用来设置这个返回值值的。
Description
require() 函数用于在指定路径加载模块,其中路径可以是核心模块(与 Node.js 一起打包的模块)、目录、文件或模块(你或其他人构建的项目)。因此,它非常灵活。require() 函数将按照以下顺序尝试解析传入的路径:核心模块、如果路径以 "./"、"/" 或 "../" 开头,则目录或文件,然后是模块。有关更多信息,请参阅以下描述。你需要检查不同位置的 require 函数,以便所有这些都能正常工作:
-
你首先会查找核心模块。核心模块可以在 Node.js 的源代码中在 lib 目录下查看。在本章中,我们将介绍最常用的模块。
-
接下来,如果字符串以 "./"、"/" 或 "../" 开头,require 将会将其作为文件加载路径。这些分别是当前目录、根目录和父目录。
-
如果找不到文件名,require 将尝试添加
.js、.json或.node扩展名。这意味着require (./data/models)函数和require (./data/models,js)将加载相同的文件。如果 require 找不到文件,它将尝试将路径作为目录加载。这意味着它会寻找index.js文件或package.json中的主属性。require 将使用index.js或package.json来加载文件。 -
最后,如果路径不以 "./"、"/" 或 "../" 开头,并且不是核心模块,require 将搜索
node_modules文件夹。第一个目录将是current目录。之后,每个目录将是一个父目录,一直到root目录。此外,require 还会在NODE_PATH环境变量中搜索路径。
简要总结一下,require 将会使用的顺序是:
-
核心模块(无相对路径)
-
文件模块(相对路径)
-
文件夹模块(相对路径)
-
node_modules模块(无相对路径)
这里有一些如何使用 require 函数加载核心模块、文件或模块的示例:
var http = require('http'); //loads a core module
如注释所示,此示例将加载 HTTP 核心模块:
var data = require('./data'); //loads a directory
此示例展示了如何加载一个目录:
var dataModels = require('./data/models'); //loads the file models.js
这个将会加载一个文件:
var redis = require('redis'); //loads a module
最后,这个将会加载一个模块。
每个 Node.js 项目都会多次使用 require,因此了解它如何以及在哪里加载是很重要的。
这里有一个简单的示例,演示了 require 以及它与 module.exports 的工作方式。
这里是将会用 require 加载的文件,requireTest.js,它将从相对路径加载:
module.exports = 'This value is from requireTest';
这里是如何在 Node.js 脚本中加载这个值的:
var requireTest = require('./requireTest');
console.log(requireTest);
module.exports
module.exports 属性是一个便利属性,用于在模块中暴露模块的功能,使其超出当前文件的作用域。
返回值
module.exports 属性是模块的返回值。这可能会让人产生误解。我们不会返回 module.exports。实际上,是设置在 module.exports 上的对象或属性可以从该模块中访问。
描述
module.exports 属性是从当前文件链接到调用文件的作用域。在当前文件中定义的任何变量都不会在调用它的文件的作用域中。为了使变量可用,你必须将它们设置为 module.exports 的值或作为 module.exports 的属性。这种功能是 Node.js 使用 require 的机制。导出可以设置为任何类型:字符串、整数、函数、对象等。函数允许我们传递值或创建 constructor() 函数。对象可以创建并用于覆盖导出对象或将其作为属性添加到导出对象中。我们拥有 JavaScript 的所有函数和对象创建技巧。
注意
一个简短的说明是,require 会缓存输出。这意味着对同一模块的连续调用将返回相同实例的对象。
这里展示了 constructor() 函数的使用示例:
-
这允许传递一个对象:
module.exports = function Foo(bar) {do something with bar}; -
这允许导出函数被执行:
module.exports = function FooConstructor() {}; -
在以下两个示例中,将使用
foo属性:module.exports = {foo: foo()}; module.exports.foo = foo();
OS 模块
下面是 os 模块最重要的函数和属性。os 模块允许你从操作系统中获取信息。这很重要,因为我们可能需要知道主机名或当前有多少个 CPU 可用。
我们现在将要查看的所有函数都假设 var os = require('os') 已经在文件中。
hostname()
这将返回设备的主机名:
.hostname()
描述
下面展示了如何使用 os.hostname() 函数的示例。在这种情况下,它将返回当前计算机使用的计算机名。它不会返回计算机的域名后缀:
os.hostname();
cpus()
这将返回当前设备的 CPU 数量:
.cpus()
描述
我们将得到一个映射到每个 CPU 的对象的数组。这些对象将包含型号、速度和 times:
-
模型和速度分别代表 CPU 的型号和速度。请注意,大多数情况下,型号和速度与我们的代码无关。
-
Times 展示了 CPU 在
user、nice、sys、idle和irq中的耗时分布。
通常,这些信息可以用来找出机器有多少个 CPU。了解这些信息是有好处的,因为 Node.js 是单线程的,我们可以为每个 CPU 在集群中启动多个进程。
下面是一个获取计算机上 CPU 数量的示例:
var cpus = os.cpus().length;
networkInterfaces()
这将获取网络接口列表:
.networkInterfaces()
描述
这将返回一个包含所有网络接口的对象。每个属性映射到一个接口,并且它将有一个包含所有 IP 地址(IPv4 和 IPv6)的数组。
例如,这是获取计算机所有接口的对象的方法:
var network = os.networkInterfaces();
进程模块
进程是一个对象,它允许我们访问进程上的事件。我们还可以访问stdin、stdout和stderr。这些是全局对象,在任何文件或上下文中都可用。
stdout
stdout对象是一个可写流。
stdout
描述
这是连接到stdout的流。请注意,流将在本章的“实用工具”部分稍后介绍。如果我们以控制台应用程序的形式运行 Node.js,如果需要,我们可以在这里写入stdout。Node.js 中的大多数流都是非阻塞的,但写入 stdout 和 stderr 是阻塞的。
我们还可以使用stdout来找出 Node.js 是否在 TTY 中运行。我们可以访问process.stdout.isTTY。这是一个布尔值。
此处的示例将展示如何将消息写入stdout流。默认情况下,这将发送到process.stdout.write控制台。这将写入stdout。
stderr
stderr对象是一个可写流。
stderr
描述
这与stdout类似,关键区别在于它写入stderr。这对于控制台应用程序非常有用,因为我们可以将正在发生的事情写入控制台。
例如,这会将内容写入stderr流。默认情况下,这将写入控制台。
process.stderr.write("Something seems to have gone wrong.");
stdin
这是一个映射到stdin的可读流。
stdin
描述
这与标准流stdin相对应,就像stdout和stderr映射到stderr流一样。区别在于stdin对象是可读的,而其他的是可写的。任何通过管道输入此进程的内容都可以使用process.stdin读取出来。要从可读流中读取,我们需要监听两个可能的事件,这些事件会告诉我们如何检索数据。第一个是可读事件,另一个是数据事件。当我们到达流部分时,我们将更深入地介绍这一点。
例如,这个例子将stdin中发送的数据通过可读事件发送到stdout:
process.stdin.on('readable', function() {
var data = process.stdin.read();
if(data !== null) process.stdout.write(data);
});
argv
这就是所有传递的命令行参数:
argv
描述
argv命令将是一个包含传递给此脚本的全部参数的数组。参数通过空格分隔。这意味着debug=true(没有空格)将是一个参数,而debug = true(每个单词之间有空格)将是三个。如果你想在参数中传递值,这是一个需要记住的重要区别。参数0和1将始终是节点和当前脚本的路径和文件名。
这里是一个例子:
process.argv.forEach(function(val){ if(val === 'debug'){ debug(); } });
信号事件
信号事件允许你监听标准的 POSIX 信号:
process.on({signal, callback});
描述
除了SIGKILL和SIGSTOP之外的所有POSIX信号都可以监听。除了这些信号之外,你还可以监听一些 Windows 信号。以下是信号的列表:
-
SIGUSR1:这是一个用户定义的信号。在 Node.js 中,它通常用于启动调试器。 -
SIGTERM:这是一个终止信号。 -
SIGINT:这是中断的信号。通常通过按下 Ctrl + C 发送。 -
SIGPIPE:这会让进程知道它正在尝试向一个不存在的进程进行管道操作。 -
SIGHUP:这是告诉进程它运行的终端已经挂起的信号。 -
SIGBREAK:这是一个非 POSIX 信号,由 Windows 使用。它应该以类似于SIGINT的方式使用。 -
SIGWINCH:这是告诉进程窗口已更改大小的信号。
这里是一个监听 SIGINT 的示例,它识别出按下了 Ctrl + C:
process.on('SIGINT', function(){
//ctrl+c was pressed
});
process.env
此对象包含环境变量:
process.env
描述
process.env 对象是一个简单的 JavaScript 对象,包含所有环境变量。每个属性都将是一个字符串。
在构建可扩展应用程序时,将配置设置放在环境变量中是一个很好的地方。然后可以使用 process.env 对象来检查当前环境是否为生产环境,甚至只是存储配置设置。
这里是一个检查环境和从环境中设置值的示例:
if(process.env.NODE_ENV !== 'production')
//do test stuff
var redisHost = process.env.REDIS_HOST;
kill
这将向进程发送一个信号事件:
process.kill(pid, [signal])
描述
这将发送信号事件部分中定义的任何信号事件,我们在前面已经讨论过。这本质上是在运行 POSIX kill 命令。
我们可以使用这个 kill 命令向当前进程发送信号,使用 process.pid,或者向另一个我们有引用的进程发送 kill 信号。
这里是一个杀死特定进程 ID 4634 的示例:
process.kill(4634, 'SIGTERM');
pid
这将获取当前的 pid:
process.pid
描述
这是进程的 pid(进程 ID)。
这是一个 process.kill 和 process.pid 一起使用的示例:
process.kill(process.pid, 'SIGTERM');
cwd
这将获取当前工作目录:
process.cwd()
这里是一个将 cwd 变量设置为进程当前工作目录的示例:
var cwd = process.cwd();
文件函数
本节不是一个真正的模块,就像之前关于进程的章节。本节将关注任何允许我们读取、写入或查找文件和目录的函数或模块。
__filename
这将返回当前文件名的字符串:
__filename
描述
__filename 命令返回当前文件名。这可能会根据正在执行的文件而有所不同。正在执行的模块将返回其文件名而不是主入口点。
这里是一个将当前文件名记录到控制台的示例:
console.log(__filename);
__dirname
这是一个当前目录的字符串:
__dirname
描述
与 __filename 类似,这将返回当前正在执行的文件的目录。__dirname 命令在需要创建相对路径时经常被使用。
注意
__filename 和 __dirname 变量在 Node.js 执行的任何文件中都是可用的。它们按文件确定,因此对于每个执行的文件都是正确的。
此示例假设 Express 已经被加载为 express:
//express is loaded
app.use(express.static(__dirname + '/static'));
文件模块
我们现在将查看文件模块中的关键函数列表。所有这些函数只是运行底层的 POSIX 命令。
我们将要介绍的每个命令都会有每个函数的异步和同步版本。同步函数将使用相同的名称,并在后面添加 Sync,例如 open 和 openSync。从某种意义上说,异步版本更像是 Node.js,因为它们允许事件循环处理而不阻塞执行。
每个异步函数都需要定义一个作为最后一个参数的回调函数。这个函数的形式将是 function(err, result)。我们将在处理错误时介绍这一点。快速总结是,如果没有发生错误,第一个参数 err 将是 null,或者它将包含错误。
注意
在当前版本的 Node.js 中,您不需要使用回调函数,但在 v0.12 版本中这将成为一个例外。
同步函数将在函数返回之前不在事件循环中处理任何内容。虽然这似乎与 Node.js 的非阻塞范式相矛盾,但在某些情况下是有意义的,例如,在处理其他任何内容之前必须打开特定文件时。这意味着需要使用经典的 try/catch 来处理任何异常或错误。
在几乎所有情况下,都应该使用异步版本。
每个示例都基于 fs 变量已经存在的假设。以下是设置 fs 变量为 fs 模块的代码:
var fs = require('fs');
stat
这将返回 fs.Stats,这是一个包含查询的文件或目录信息的对象:
fs.statstat(path, callback)
fs.statSync(path)
描述
stat 变量获取在操作系统上运行 stat() 后返回的数据。stat 对象是 fs.Stats 的一个实例。该对象提供了诸如 isFile() 和 isDirectory() 等有用的函数。此外,fs.Stats 还有许多属性。我们可以看到修改时间、访问时间和文件大小。
还有更多函数和属性,但这些都是最可能使用的。
fs.lstat() 和 fs.fstat() 函数都会在指向文件时返回一个 fs.Stats 对象。区别在于 lstat 将针对链接运行而不是跟随链接到文件或目录。fstat 将针对文件描述符而不是路径运行。
这里有一个示例,它加载与代码文件相同的目录下的名为 test.txt 的文件,并记录 fs.Stats 对象:
fs.stat(__dirname + '\test.txt', function(err, stats){
console.log(stats);
});
open
这将返回传入路径的文件描述符:
fs.open(path, flags, [mode], callback)
fs.openSync(path, flags, [mode])
描述
这将在传入的路径中打开一个文件。可以传入许多标志。它们在这里进行了描述:
-
r: 只读,当文件不存在时出错 -
r+: 读写,当文件不存在时出错 -
rs: 只读同步,这里的“同步”仅指文件系统缓存数据,而不是像openSync这样的同步 -
rs+: 读写同步 -
w: 写入 -
wx: 写入,当文件存在时出错 -
w+: 读写,文件被创建或截断 -
a: 追加,文件被创建 -
ax: 追加,当文件存在时出错 -
a+: 读取和追加,文件被创建 -
ax+: 读取和追加,当文件存在时出错
标志允许你打开、读取和写入文件,无论它是否存在。这意味着大多数时候,不需要调用 fs.exists 作为标志之一,因为其中一个标志会给你需要的答案。
模式参数是在创建文件时使用的权限。默认为 0666。
最后,回调返回一个文件描述符。有了这个,可以使用 fs.read 或 fs.write 来读取或写入数据。
这是一个打开文件 test.txt 的示例:
fs.open(__dirname + '\file.txt', 'r', function(err, fd){
//fd is available to be read from
});
read
从文件描述符读取:
fs.read(fd, buffer, offset, length, position, callback)
fs.readSync(fd, buffer, offset, length, position)
描述
read() 函数运行需要很多参数。我们需要一个文件描述符,这是从打开中获得的,一个缓冲区,以及文件的大小。在示例中,我们使用了 fs.stat 来获取文件大小。
这是一个打开文件并从中读取的完整示例:
fs.stat(__dirname + '/test.txt', function(error, stats) {
fs.open(__dirname + '/test.txt', 'r', function(err, fd){
var buffer = new Buffer(stats.size);
fs.read(fd, buffer, 0, stats.size, null, function(err, bytesRead, buffer){
console.log(buffer.toString('utf8'));
});
});
});
readFile
这是一个读取文件的简化版本:
fs.readFile(filename, [options], callback)
fs.readFileSync(filename, [options])
描述
readFile() 函数极大地简化了在 Node.js 中读取文件的过程。在之前的 fs.read 函数中,我们需要在尝试读取文件之前设置好一切。readFile() 函数允许我们只传递一个文件名,然后返回文件中的缓冲区。
optional options 对象接受一个标志和一个编码属性。标志属性与 fs.open 中的标志相同,因此可以使用任何一个。编码用于回调中返回的缓冲区。
这里有一个示例,展示了使用 readFile 加载文件有多容易。该示例还使用了 optional options 参数:
var filename = __dirname + '/test.txt';
fs.readFile(filename, {flag: 'r', encoding: 'utf8'}, function(err, data){
console.log(data.toString('utf8'));
});
close
将关闭一个文件描述符:
fs.close(fd, callback)
fs.closeSync(fd)
描述
在我们的脚本中打开的任何文件都很重要。如果我们从 fs.open 获取文件描述符,我们将在某个时候调用 fs.close 来关闭该文件描述符。
这是一个关闭文件描述符的示例:
fs.close(fd, function(err){
//handle err here
});
write
这是写入文件描述符的示例:
fs.write(fd, buffer, offset, length, position, callback)
fs.writeSync(fd, buffer, offset, length, position)
描述
write() 函数接受一个文件描述符和一个要写入文件的缓冲区。与读取类似,我们必须传递相当多的参数才能使其工作。
在下面的示例中,我们将文件读入缓冲区,然后将该缓冲区写回另一个文件。偏移量和长度都是需要传递的整数。位置可以是整数,也可以是 null。Null 将从文件当前位置开始写入。
就像读取一样,写入也可以很复杂。这里有一个从文件读取并写入另一个文件的完整示例:
var fs = require('fs');
var filename = __dirname + '/test.txt';
var writeFile = __dirname + '/test2.txt';
fs.stat(filename, function(error, stats) {
fs.open(filename, 'r', function(err, fd) {
var buffer = new Buffer(stats.size);
fs.read(fd, buffer, 0, stats.size, null, function(err, bytesRead, buffer) {
fs.open(writeFile, 'w', function(err, writeFD) {
//will create a file named test2.txt with the contents from test.txt
fs.write(writeFD, buffer, 0, buffer.length, null, function(err, bytesWritten, writeBuffer) {
console.log(writeBuffer.toString('utf8'));
});
});
});
});
});
writeFile
这是一个写入文件的简化函数:
fs.writeFile(filename, data, [options], callback)
fs.writeFileSync(filename, data, [options])
描述
正如读取和 readFile 之间的区别一样,writeFile 是写入的简化版本。我们只需传递一个文件名和一个字符串或缓冲区,它就会写入文件。
当发生错误时,回调只返回错误。
在大多数情况下,readFile和writeFile似乎是最佳选择,实际上,这很可能就是真的。使用这些函数所放弃的主要是控制权。你只能读取整个文件或写入整个文件。
注意
使用读取或写入,你可以读取文件中的任何部分,也可以写入文件中的任何部分。这一点很重要,需要记住。
这里是writeFile的一个例子:
var filename = __dirname + '/write.txt';
var buffer = new Buffer('Write this to a file.', 'utf8');
fs.writeFile(filename, buffer, {encoding: 'utf8', flag: 'w'}, function(err){
if(null !== null){
//do something
}
});
appendFile
这个函数允许我们追加文件:
fs.appendFile(filename, data, [options], callback)
fs.appendFileSync(filename, data, [options])
描述
appendFile存在的原因是writeFile只会写入整个文件。因此,我们需要另一个函数来向文件中添加内容。这就是为了方便而放弃一些控制权的地方。如果我们使用文件描述符和写入操作,那么我们可以选择从文件的末尾开始写入。这实际上就是追加文件:
这里是appendFile的一个例子:
var filename = __dirname + '/write.txt';
var buffer = new Buffer('Append this to a file.', 'utf8');
fs.appendFile(filename, buffer, {encoding: 'utf8', flag: 'w'}, function(err){
if(null !== null){
//do something
}
});
path模块
path模块与文件模块是分开的。path模块关注的是路径的修正,而文件模块关注的是文件和目录的操作。很多时候,这两个模块会一起使用。
涵盖的函数是最常用且最有用的。你很可能需要定位到当前项目相对的路径,这正是path模块的作用所在:
注意
注意,path模块不会检查路径修改的存在性。它本质上只对路径的字符串值进行修改。
就像其他模块一样,这个例子假设path模块已经被加载:
var path = require('path');
normalize
这将返回一个经过修正的路径字符串:
path.normalize(pathString)
描述
normalize函数将修复与读取路径相关联的许多问题。一个很好的例子是 Windows 和 Unix 路径之间的差异。Unix 使用正斜杠,而 Windows 使用反斜杠。normalize将根据执行的环境返回正确的斜杠。
此外,normalize还会移除当前目录和父目录的快捷方式(分别是.和..),也会从目录中移除多余的斜杠。它会规范化传入的所有路径。
这里是一个在 Windows 系统上使用 Unix 斜杠的例子。这个例子会将所有的斜杠都转换为反斜杠:
var pathString = "/unix/style/path/separators";
console.log(path.normalize(pathString));
join
这将返回所有路径连接在一起形成的字符串:
path.join([pathString1],[…])
描述
join函数使得从部分路径创建完整路径变得简单。这看起来像是可以通过连接操作完成的,但很容易忘记路径分隔符。join函数会确保路径分隔符都位于正确的位置。
这里是join的一个例子。这个例子将接受所有参数,并使用系统正确的斜杠将它们连接起来:
console.log(path.join('path', 'separators', 'added'));
resolve
这将根据参数返回路径的字符串:
path.resolve([pathString], […])
描述
这可以看作是对每个参数执行的 cd 命令。传入的路径可以是相对路径或完整路径。相对路径将添加到返回的路径中,而完整路径将被整个使用。
这里有两个例子:
-
相对路径将返回
/home/josh/test:console.log(path.resolve('/home/josh/node', '..', 'test')); -
完整路径将返回
/home/brian/node:console.log(path.resolve('/home/josh/node', '/home/brian/node'));
relative
这返回to和from路径之间的差异:
path.relative(from, to)
描述
返回的路径可以用cd来更改到新目录。
以下是一个示例,将返回../../brian/node,因为您必须向上移动两个父目录,然后转到brian/node才能从一个移动到另一个:
var from = '/home/josh/node';
var to = '/home/brian/node';
console.log(path.relative(from, to));
dirname
这返回目录名字符串:
path.dirname(pathString)
此示例将返回当前文件所在的目录。如果文件位于/home/users/jjohanan/node目录中,则示例将返回/home/users/jjohanan/node:
console.log(path.dirname(__filename));
basename
这返回路径的最后一部分字符串:
path.basename(pathString, [ext])
描述
这将根据传入的路径返回文件名或目录。如果存在,可选的ext参数将从返回值中移除该部分。
这里有两个示例,一个涉及文件,另一个涉及目录:
-
这将返回
test:console.log(path.basename('/home/josh/test.js', '.js')); -
这将返回
josh:console.log(path.basename('/home/josh'));
extname
这将返回路径的扩展名字符串。如果没有扩展名,则返回一个空字符串:
path.extname(pathString)
这里有两个示例:
-
此示例将返回
.js:console.log(path.extname('/home/josh/test.js')); -
此示例将返回一个空字符串:
console.log(path.extname('/home/josh'));
REPL
REPL 代表读取-评估-打印循环。这意味着它是一个交互式控制台。我们可以输入一个命令(读取)。命令将被执行(评估)。命令的输出将被打印到控制台(打印)。最后,我们可以多次这样做(循环)。REPL 非常适合运行几行代码以查看它们将做什么。
node
这将在 REPL 模式下启动 Node.js:
node
描述
REPL 的主要使用方式是通过直接调用它。这可以通过运行不带文件服务的 Node.js 来实现,只需运行node。一旦node返回提示符,我们就可以添加命令并查看运行它们时会发生什么。这对于测试几行代码非常完美。
这里是一个快速示例,说明如何在控制台中登录;首先运行node以获取提示符,然后运行命令:
node
//wait for >
console.log('hey this REPL!');
处理错误
错误是任何开发项目的一部分。我们必须能够优雅地处理错误。如果我们不这样做,那么我们正在为我们的用户提供糟糕的体验。更糟糕的是,我们可能会打开攻击的途径。发送给最终用户的堆栈跟踪可能会泄露许多细节。
这将是一个专门处理设计模式而不是实际代码引用的特殊部分。Node.js 是一个异步事件驱动平台。对于大多数人来说,他们没有在类似这样的平台上工作过,处理错误时可能会犯错。我们认为处理错误非常重要。
这些信息的核心来自 Joyent,它是今天Node.js背后的主要力量之一。您可以在www.joyent.com/developers/node/design/errors上找到有关 Joyent 的更多信息。
错误类型
错误可以分为两种类型:操作错误和程序员错误。操作错误是在应用程序操作期间发生的错误。例如,数据库服务器不可访问就是一个例子。这些错误可以计划并优雅地处理。
接下来是程序员错误,这在字面上是错误。例如,一段代码格式不正确或出现了意外的条件。这些很难计划(如果我们已经计划了它们,那么它们就不会是错误了!)。这些几乎总是会破坏服务器,因此我们可以通过日志回溯来找出出了什么问题。
错误设计模式
现在我们已经知道了两种不同类型的错误,让我们看看三种通知应用程序有错误的方式。这三种方式是抛出错误、异步回调和发出错误事件:
-
抛出错误的第一个模式是内置于 JavaScript 中的。这种模式非常适合任何同步代码。如果我们进行任何同步操作并且发生错误,我们应该抛出它。在处理同步调用时,我们应该在函数调用周围包裹一个
try/catch块。以下是一个使用JSON.parse的示例,它同步运行,并在传递非 JSON 字符串时抛出错误:try{ JSON.parse(jsonObject); } catch (ex) { //do something with this error } -
下一个模式是使用异步回调。许多内置的 Node 函数已经这样做了。模式是使用一个具有签名
function(error, result)的回调函数。第一个参数将要么包含一个错误,要么是 null 或 undefined。我们可以在编写任何异步函数时自行实现这一点。如果有错误,请在回调中将它作为第一个参数返回。注意
当处理这些错误时,我们必须在每个回调函数中放置一个错误检查。这是非常重要的,因为不这样做可能会默默地吞下错误。
这的一个好例子是异步和同步的 filesystem 模块调用。例如,读取操作需要一个回调,而 readSync 应该被包裹在一个 try/catch 块中。
这里有一个示例回调和错误检查:
fs.read(path, function (err, data) {
if(err !== null)
//handle error
})
最后,我们可以发出一个错误事件。这也用于异步函数。我们实现回调或事件是个人选择,但应该清楚使用的是哪一个。这也是一个最佳实践,只实现一个。很多时候,当存在长时间运行的异步过程时,会使用事件。从网络套接字读取数据就是一个例子。套接字并不总是简单地在一次传递中提供数据,因此会设置事件。其中之一就是错误事件。要处理这个问题,我们只需要监听那个事件。以下是一个监听套接字错误事件的示例:
socket.on('error', function(error){
//handle error here
})
工具
在下一组模块中,我们将查看工具。这里选择的功能被用于许多不同类型的应用程序。我们将涵盖从事件和密码学到缓冲区和 npm 的所有内容。
事件
事件被用于许多内置的 Node 对象中。这是因为触发和监听事件是让另一个函数知道何时开始执行的最佳方式。这在 Node.js 的异步世界中尤其如此。任何时候我们使用对象的 on 函数,就意味着它已经继承了 EventEmitter。所有示例都将假设事件变量已经按照以下方式创建:
var events = require('events');
EventEmitter
这是可以继承以创建新 EventEmitter 的父类:
events.EventEmitter
描述
Node.js 拥有一个功能齐全的事件系统,我们可以轻松地继承并实现。我们不需要任何额外的框架或自定义代码。EventEmitter 是要继承的类,我们将获得本节其余部分的所有函数。
这里是设置自定义 EventEmitter 参数的示例:
var util = require('util');
var events = require('events');
function MyEventEmitter(){
events.EventEmitter.call(this);
this.test = function (emitThis) {
this.emit('testEvent', emitThis);
}
}
util.inherits(MyEventEmitter, events.EventEmitter);
var myEE = new MyEventEmitter();
myEE.on('testEvent', function (data) { console.log(data) });
myEE.test('test');
on
这个函数为特定事件添加监听器:
emitter.on(event, listenerFunction)
emitter.addListener(event, listenerFunction)
描述
on 函数已成为添加事件监听器的首选命名约定。例如,jQuery 使用完全相同的函数名作为它们的事件监听器。event 处理器是即将触发的事件的字符串名称。listenerFunction 参数是事件触发时将要执行的函数。
listenerFunction 参数可以是一个匿名函数或对函数的引用。添加监听器的首选方式是对函数的引用。这将允许我们在稍后时间移除这个特定的监听器。
这里是一个基于我们新的 MyEventEmitter 类的示例:
var quickLog = function (data) {
console.log('quickLog: ' + data);
}
myEE.on('testEvent', quickLog);
once
这与 on 函数的工作方式相同,但它只执行一次,然后作为监听器移除自己:
emitter.once(event, listenerFunction)
removeListener
这是一个用于从事件中移除监听器的函数:
emitter.removeListener(event, function)
描述
当我们完成对事件的监听后,我们希望移除我们的监听器。这将有助于防止内存泄漏。如果我们添加了一个匿名函数作为监听器,那么我们无法像之前那样移除它,因为我们没有对这个函数的引用。使用我们之前的 on 示例,我们将移除监听器:
myEE.removeListener('testEvent', quickLog);
removeAllListeners
这个函数将移除所有事件或特定事件的监听器:
emitter.removeAllListeners([event])
描述
这实际上是一种移除监听器的核选项。它对监听器没有选择性。removeAllListeners 参数甚至会移除我们没有添加的监听器。请将此作为最后的手段使用。
这里展示了一个移除此事件所有监听器的示例。如果事件留空,它将移除所有事件的监听器:
myEE.removeAllListeners('testEvent');
setMaxListeners
这个函数设置了在 Node.js 之前监听器的数量,并警告可能存在的内存泄漏:
emitter.setMaxListeners(numberOfListeners)
当监听器的数量超过阈值时,Node.js 会提供一个有用的警告。默认值是 10,所以当你添加第十一个监听器时,Node.js 将会警告:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
作为一般规则,这是正确的。如果我们继续向事件添加监听器,就有很大的内存泄漏风险。然而,有时我们可能需要在事件上添加超过 10 个监听器。这就是我们使用 setMaxListeners 的地方。如果我们把最大监听器数设置为零,那么我们可以添加任意多个。
这里有一个将最大监听器数设置为 50 的示例:
myEE.setMaxListeners(50);
emit
这就是如何触发一个事件的方式:
emitter.emit(eventName, [argument], […])
如果我们扩展了一个对象使其成为事件发射器,那么我们可能想要发射一些事件!这是执行此操作的函数。它将根据 eventName 执行已附加到该事件的全部事件监听器。
这里有一个示例,展示了添加监听器然后触发事件的操作:
myEE.on('testEvent', function (data) { console.log(data) });
myEE.emit('testEvent', 'Emit This!', 'Another Argument!');
Crypto
每个现代应用程序都需要加密。Node.js 使用加密的一个很好的例子是与 HTTPS 一起使用。我们不会探索 HTTPS 的内部工作原理,因为有一个模块(https 模块)为我们做了这件事。我们将查看用于哈希、存储和检查密码的加密函数。
与其他模块一样,我们将需要 crypto 模块,并在我们的示例中使用它。以下是我们需要的内容:
var crypto = require('crypto');
createHash
此函数将返回一个 crypto.Hash 对象:
crypto.createHash(algorithm)
Description
可以使用的算法将因系统而异,因为它依赖于 OpenSSL。我们可以通过调用 crypto.getHashes() 来找出 crypto 可以使用的算法。这将返回一个字符串数组,然后可以将其传递给 createHash 作为算法。
此函数的返回对象是一个 crypto.Hash 对象,这在下一节中会介绍。
这里有一个创建 MD5 哈希的示例:
var md5 = crypto.createHash('md5');
哈希对象
这是 crypto.createHash 返回的对象:
hash.update(data, [encoding])
hash.digest([encoding])
Description
一旦我们获得了返回的哈希对象的引用,您会看到它有两个函数。第一个是 update,它允许我们添加到将被哈希的数据。这可以多次调用。如果我们想要哈希流输入,这很重要。
下一个函数是 digest。这将根据创建哈希对象时使用的算法返回摘要。此函数的字符串编码可以是十六进制、二进制或 BASE64\。
这里有一个从文件中读取数据然后计算文件 MD5 哈希的完整示例。
var f = file.readFileSync(__dirname + '/test.txt');
var md5 = crypto.createHash('md5');
md5.update(f);
console.log(md5.digest('base64'));
Tip
不要使用哈希来存储密码。我们将要介绍的下一个函数比简单的哈希更安全。摘要哈希非常适合检查数据是否已更改,因为即使是一个比特位不同,哈希值也会不同。此外,它可以用作密钥或标识符。一个很好的例子是将其用于内存缓存,并使用哈希作为密钥。如果数据相同,密钥也将相同。
pbkdf2
此函数将多次使用 HMAC-SHA1 来创建派生密钥:
crypto.pbkdf2(password, salt, iterations, keyLength, callback)
crypto.pbkdf2Sync(password, salt, iterations, keyLength)
返回类型
pbkdf2 和 pbkdf2Sync 都会返回一个作为缓冲区的派生密钥。
Description
Pbkdf2(基于密码的派生函数 2)是为密码存储而设计的。它比哈希更安全,因为它更难。哈希是为了快速计算而设计的。这是不好的,因为现代 CPU 每秒可以计算数千个哈希值。这使得破解哈希密码变得容易。
Pbkdf2 通过在迭代中使用工作因子来解决这个问题。迭代次数越高,计算时间越长。现在,我们不再每秒计算数千次,而是可以将 CPU 速度降低到每秒仅几个。这是一个显著的降低。
这些是使用的参数:
-
password:这是我们想要创建派生密钥的字符串。 -
salt:这是一个与密码结合的字符串。这样做可以确保即使salt不同,相同的密码也不会有相同的哈希值。 -
iterations:这是工作因子,指示函数重复的次数。随着 CPU 的变快,这可以增加。目前,至少 10,000 次可以创建一个相当安全的派生密钥。 -
keyLength:这是返回的派生密钥的期望长度。
这是一个为字符串 password 和 salt 创建派生密钥的示例:
crypto.pbkdf2('password', 'salt', 10000, 32, function (err, key) {
console.log(key.toString('base64'));
});
randomBytes
这将返回具有加密强度的伪随机数据:
crypto.randomBytes(length, [callback])
返回类型
返回一个缓冲区。
描述
需要随机数据用于各种函数。虽然没有任何数据可以真正是随机的,但存在不同级别的随机性。randomBytes 参数的随机性足以用于加密函数。randomBytes 的一个完美用途是在 pbkdf2 中用作 salt。salt 变量与密码结合,即使密码相同,也会创建不同的哈希值。
此函数可以异步或同步执行。这取决于是否有回调,如果有,它将异步执行。
这是一个为 pbkdf2 创建随机 salt 的函数。如果您将此示例与上一个示例进行比较,您将看到此示例每次输出一个独特的字符串,而上一个示例则不是:
var random = crypto.randomBytes(256);
crypto.pbkdf2('password', random.toString('base64'), 10000, 32, function (err, key) {
console.log(key.toString('base64'));
});
pseudoRandomBytes
这将返回伪随机数据:
crypto.pseudoRandomBytes(length, [calback])
crypto.pseudoRandomBytes(length)
返回类型
返回一个缓冲区。
描述
这个函数与 randomBytes 完全一样,但它不是加密强度的。这意味着我们不应该将其与任何加密函数(如 pbkdf2)一起使用。
我们可以用它做任何需要随机性、文件名或缓存键等其他事情。
这是一个异步执行此函数的简单示例:
crypto.pseudoRandomBytes(256, function (err, randomData) {
console.log(randomData.toString('base64'));
});
缓冲区
Node.js 在许多方面都使用缓冲区。我们已经在许多函数返回缓冲区时看到了这一点。这是因为任何需要存储原始数据或二进制数据时,它都会存储在缓冲区中。
缓冲区有几个需要注意的特性。首先,缓冲区存储数据,但为了利用其中存储的数据,我们必须对其进行编码。本节将介绍编码方式以及如何进行编码。其次,缓冲区的大小不能调整。当创建缓冲区时,我们必须指定一个长度,这个长度将始终是缓冲区的长度。当然,我们可以创建一个新的更大的缓冲区,然后将数据复制过去。最后,缓冲区是全局的。我们不需要使用 var buffer = require('buffer')。此外,它可以在任何文件中的任何时间被使用。
缓冲区创建
缓冲区的初始化函数如下代码片段所示:
new Buffer(size)
new Buffer(array)
new Buffer(str, [encoding])
返回值
这将返回一个缓冲区对象。
描述
有三种不同的方式可以初始化缓冲区。第一个函数使用给定大小的整数,下一个函数使用数组,最后一种方法可以使用字符串。编码是可选的,默认为 UFT8。
此示例演示了使用包含 ASCII 码中hello字符串的数组进行初始化:
var hello = [72, 101, 108, 108, 111];
var buffer = new Buffer(hello);
console.log(buffer.toString('ascii'));
index
这在缓冲区的特定索引处获取值:
buffer[index]
返回值
这将返回指定索引处的值。
描述
这与数组的工作方式非常相似。以下是一个获取缓冲区第一个索引的示例:
var buffer = new Buffer('Hello!');
console.log(buffer[0]);
toString
这将根据编码返回缓冲区作为字符串:
buffer.toString([encoding], [start], [end])
返回值
这将返回一个字符串。
描述
这很可能是您将用于从缓冲区获取数据的函数。第一个参数是编码,它可以是以下之一:
-
ASCII
-
UTF8
-
UTF16LE
-
BASE64
-
Binary
-
Hex
所有参数都是可选的,这意味着它们都有默认值。编码默认为 UTF8,start为0,end为缓冲区的末尾。
下面是一个创建缓冲区并从中检索数据的示例。它明确定义了每个参数:
var buffer = new Buffer('Hello this is a buffer');
console.log(buffer.toString('utf8', 0, buffer.length));
toJSON
这将返回缓冲区的内容作为 JavaScript 对象:
buffer.toJSON()
返回值
这将返回一个包含缓冲区内容的数组。
描述
这将返回缓冲区内容映射到数组。此示例类似于上一个示例,但使用了toJSON:
var buffer = new Buffer('Hello this is a buffer');
console.log(buffer.toJSON());
isBuffer
这是一个类方法,用于确定一个对象是否是缓冲区:
Buffer.isBuffer(objectToTest)
返回值
这将返回一个布尔值。
描述
记住这是一个类方法,因此可以在没有缓冲区新实例的情况下执行。以下是一个使用该函数的示例:
var buffer = new Buffer('Hello this is a buffer');
console.log(Buffer.isBuffer(buffer));
write
以下代码向缓冲区写入数据。
buffer.write(stringToWrite, [offset], [length], [encoding])
返回值
这将返回写入的字节数的整数。
描述
此函数将写入传递到缓冲区的字符串。与其他缓冲区函数一样,有许多可选参数具有默认值。默认偏移量为0,长度为buffer.length – offset,编码为 UTF8。
此示例使用第一次写入的返回值向缓冲区写入两次,以附加第二个字符串:
var buffer = new Buffer(12);
var written = buffer.write('Buffer ', 0, 7, 'utf8');
console.log(written);
buffer.write('time.', written);
console.log(buffer.toString());
byteLength
此函数将根据编码获取字符串的字节长度:
buffer.byteLength(string, [encoding])
返回值
这返回一个整数,表示所需的字节数。
描述
缓冲区初始化后不能调整大小,因此我们可能需要事先知道字符串的大小。这就是 byteLength 发挥作用的地方。
这里是一个确定字符串大小并将其写入缓冲区的示例:
var byteLength = Buffer.byteLength('Buffer time.', 'utf8');
var buffer = new Buffer(byteLength);
var written = buffer.write('Buffer time.', 0, buffer.length, 'utf8');
console.log(buffer.toString());
readUInt
这将在缓冲区的某个位置获取一个无符号整数:
buffer.readUInt8(offset, [noAssert])
buffer.readUInt16LE(offset, [noAssert])
buffer.readUInt16BE(offset, [noAssert])
buffer.readUInt32LE(offset, [noAssert])
buffer.readUInt32BE(offset, [noAssert])
返回值
这返回一个表示使用大小的无符号整数,readUInt8 为 8。
描述
存储在缓冲区中的数据并不总是精确的字节。有时,数据需要以 16 位或 32 位块读取。此外,您还可以指定数据是低位字节序还是高位字节序,分别由函数名中的 LE 或 BE 表示。
偏移量是指从缓冲区的哪个位置开始。如果偏移量大小在缓冲区中,noAssert 参数将运行验证。默认情况下,它是 false。
这里是一个设置数据然后使用 readUInt16 读取数据的示例:
var buffer = new Buffer(2);
buffer[0] = 0x1;
buffer[1] = 0x2;
console.log(buffer.readUInt16LE(0));
console.log(buffer.readUInt16BE(0));
writeUInt
这将一个无符号整数写入缓冲区:
buffer.writeUInt8(value, offset, [noAssert])
buffer.writeUInt16LE(value, offset, [noAssert])
buffer.writeUInt16BE(value, offset, [noAssert])
buffer.writeUInt32LE(value, offset, [noAssert])
buffer.writeUInt32BE(value, offset, [noAssert])
描述
这与 readUInt 函数正好相反。有时,我们需要写入长度大于一个字节的 数据。这些函数使这变得简单。
noAssert 参数是可选的,默认为 false。这不会对值或偏移量执行任何验证。
这里是一个将 UInt16 写入缓冲区的示例:
var buffer = new Buffer(4);
buffer.writeUInt16LE(0x0001, 0);
buffer.writeUInt16LE(0x0002, 2);
console.log(buffer);
小贴士
注意,缓冲区类还有更多此类读写函数。而不是创建一个非常冗余的部分,我将列出它们。请记住,它们与我们所讨论的函数以相同的方式工作:readInt8、readInt16LE、readInt16BE、readInt32LE、readInt32BE、readDoubleLE、readDoubleBE、readFloatLE 和 readFloatBE。还有一个 write() 函数映射到这些函数中的每一个。
控制台
这与大多数现代浏览器中存在的控制台非常相似。控制台本质上映射到 stdout 和 stderr。这不是一个模块,每个函数都不太复杂,所以让我们直接进入。
log
这写入到 stdout:
console.log(message, […])
描述
这可能是最常用的控制台函数。它非常适合调试,输出可以与管道结合写入文件以保存历史记录。多个参数创建了一个类似字符串的函数。
这里是一个使用多个参数的示例:
console.log('Multiple parameters in %s', 'console.log');
dir
这是 util.inspect 的别名:
console.dir(object)
描述
许多时候,console.log 和 console.dir 的输出将是相似的。然而,当试图查看一个对象时,应该首选 console.dir。
time 和 timeEnd
这两个函数一起使用来标记计时器的开始和结束:
console.time(label)
console.timeEnd(label)
描述
这两个函数总是一起使用。console.time 参数将启动一个计时器,可以通过传递相同的标签使用 console.timeEnd 来停止。当调用 timeEnd 时,它将在毫秒中记录开始和结束之间的经过时间。
这里是一个使用 setTimeout 的示例:
console.time('simple-timer');
setTimeout(function () {
console.timeEnd('simple-timer');
}, 500);
trace
这会在控制台记录并包含堆栈跟踪:
console.trace(message, […])
描述
这与console.log的工作方式非常相似。第一个参数可以被视为格式化字符串,其他参数提供额外的输入。主要区别是console.trace在记录到控制台时会包含堆栈跟踪。
这里有一个简单的例子:
console.trace('This should be the first line.');
npm(Node 包管理器)
npm 不是一个 Node.js 模块。我们将探讨一些 npm 的功能和用法,因为几乎每个 Node.js 项目都会使用 npm。
大多数现代平台都有一种将执行特定功能或目的的代码分组在一起的方式,称为包。Node.js 使用 npm 来跟踪、更新、固定和安装这些包。
init
这通过在当前目录中创建package.json来初始化一个 node 模块:
npm init
描述
一个交互式控制台会问你很多问题,并使用这些答案为你构建一个package.json文件。这是一个启动新模块的好方法。如果package.json文件存在,这将不会删除当前的package.json文件或任何当前属性。
package.json
这是包含你项目所有信息的文件。
描述
这不是一个函数或命令,但它是你项目中最重要的文件。它决定了关于你项目所有信息。虽然技术上只需要 name 和 version 这两个属性,但可以设置许多属性。如果你使用 npm 创建了这个文件,你将会有很多已经填写好的。列出所有可能性将会很繁琐。这里只列出一些最有用的:name、version、scripts、dependencies、devDependencies、authors 和 license。
npm 文档在www.npmjs.org/doc/files/package.json.html中详细介绍了所有设置及其用法。
install
这是安装包的命令:
npm install
npm install [package] [@version] [--save | --save-dev]
描述
这是安装新包及其依赖项的主要方式。如果没有参数调用npm install,它将使用package.json并安装所有依赖项。
这个命令还允许你通过执行包名来安装包。可以通过添加版本来增强这一点。如果省略版本,它将安装最新版本。此外,你可以使用 save 标志在 dependencies 或 devDependcies 中创建属性。
这不是npm install能做的全部列表,但这是最常用的列表。
update
这将更新一个包到最新版本:
npm update [package]
描述
这个命令将更新所有包或特定包到最新版本。
shrinkwrap
这将明确定义项目的所有依赖项:
npm shrinkwrap
描述
这与 package.json 中基本依赖列表不同。大多数包都有自己的要求。当安装一个包时,npm 将出去寻找与依赖指定的版本匹配的最新版本。这可能导致在运行不同时间时安装不同版本的包。这是大多数开发者想要避免的事情。
一种对抗这种情况的方法是运行 npm shrinkwrap。它将创建 npm-shrinkwrap.json 文件。这个文件将明确定义每个已安装的包递归安装的当前版本。这确保了当你再次运行 npm install 时,你会知道将安装哪些包版本。
run
这将运行一个任意命令:
npm run [script]
描述
package.json 文件中有一个名为 scripts 的属性。这是一个对象,可以包含可以被 npm 运行的命令列表。这些脚本可以是任何可以通过命令行运行的命令。
在 npm 中有三个命令使用这些脚本对象。这些是 npm test、npm start 和 npm stop。这些命令分别映射到测试、启动和停止脚本对象。
这里是一个来自 package.json 的脚本对象示例以及从 npm 调用它的方法:
package.json:
"scripts": {
"hey": "echo hey"
}
npm run hey
Stream
Stream 是许多内部对象使用的接口。每当需要读取或写入数据时,最有可能通过流来完成。这与 Node.js 的异步范式相符合。如果我们从文件系统中读取一个大文件,我们会创建一个监听器来告诉我们每个数据块何时准备好读取。如果这个文件来自网络、HTTP 请求或 stdin,这也不会改变。
在这本书中,我们只将涵盖使用流。流接口也可以用你自己的对象实现。
流可以是可读的、可写的,或者双工(两者都是)。我们将分别介绍可读流和可写流。
Readable
这当然是一个我们可以从中获取数据的流。一个可读流可以在两种不同的模式中,流动模式或非流动模式。它处于哪种模式取决于监听哪些事件。
要将流置于流动模式,你只需监听数据事件。相反,要将流置于非流动模式,你必须监听可读事件,然后调用 stream.read() 函数来检索数据。理解这些模式的最简单方法是将数据视为许多块。在流动模式下,每次一个块准备好时,数据事件就会触发,你可以在数据事件的回调中读取该块。在非流动模式下,块会触发一个可读事件,然后你必须调用 read 来获取块。
这里是一个事件列表:
-
readable
-
data
-
end
-
close
-
错误
这里有两个例子,一个使用流动模式,一个使用非流动模式:
var fs = require('fs');
var readable = fs.createReadStream('test.txt');
readable.on('data', function (chunk) {
console.log(chunk.toString());
});
var fs = require('fs');
readable.on('readable', function () {
var chunk;
while (chunk = readable.read()) {
console.log(chunk.toString());
}
});
read
使用非流动的 readable 流:
readable.read([size])
返回值
这将返回字符串、缓冲区或 null。如果设置了编码,则返回字符串。如果没有设置编码,则返回缓冲区。最后,当流中没有数据时返回 null。
描述
这从流中读取。大多数时候,可选参数大小是不需要的,应该避免使用。仅与非流动流一起使用。
这是一个简单的示例,用于读取文件:
readable.on('readable', function () {
var chunk;
while (chunk = readable.read()) {
console.log(chunk.toString());
}
});
setEncoding
这设置了流的编码:
stream.setEncoding(encoding)
描述
默认情况下,可读流将输出一个缓冲区。这将设置缓冲区的编码,因此返回一个字符串。
这是一个使用setEncoding的打开示例:
readable.setEncoding('utf8');
readable.on('readable', function () {
var chunk;
while (chunk = readable.read()) {
console.log(chunk);
}
});
恢复和暂停
这些函数暂停和恢复流:
stream.pause()
stream.resume()
描述
暂停将停止流发出数据事件。如果在对非流动流调用此函数,它将被更改为流动流并暂停。恢复将使流再次开始发出数据事件。
这是一个示例,在读取之前暂停流几秒钟:
readable.pause();
readable.on('data', function (chunk) {
console.log(chunk.toString());
});
setTimeout(function () { readable.resume();}, 3000);
管道
这允许你将可读流的输出发送到可写流的输入:
readable.pipe(writable, [options])
返回值
这返回可写流,以便可以链式管道。
描述
这与在 shell 中管道输出完全相同。
一个很好的设计范例是从一个流管道到另一个转换流的流,然后再将其管道到输出。例如,你想通过网络发送文件。你会以可读流打开文件,将其传递给一个双工流,该流将压缩它,然后将压缩输出管道到套接字。
这里是一个简单的示例,将输出管道输出到stdout:
var readable = fs.createReadStream('test.txt');
readable.pipe(process.stdout);
可写
这是数据流向的流。这有点简单,因为实际上只有两个重要的函数:写入和结束。
这里是它们触发时的事件和详细信息:
-
drain:当内部缓冲区已写入所有数据时触发 -
finish:当流已结束并且所有数据都已写入时触发 -
error:当发生错误时触发
注意
需要注意的是,流可以接收比它能及时写入更多的数据。这在写入网络流时尤其如此。正因为如此,finish和drain事件让程序知道数据已被发送。
write
这个函数写入流:
writable.write(chunk, [encoding], [callback])
返回值
如果流已完全写入,则返回一个布尔值。
描述
这是可写流的主要功能。数据可以是缓冲区或字符串,编码默认为 UTF8,当当前数据块被写入时,将调用回调函数。
这是一个简单的示例:
var fs = require('fs');
var writable = fs.createWriteStream('WriteStream.txt');
var hasWritten = writable.write('Write this!', 'utf8', function () {
console.log('The buffer has written');
});
end
这将关闭流,并且无法再写入更多数据:
writable.end([chunk], [encoding], [callback])
描述
当你完成向流写入时,应该在它上调用 end 函数。所有参数都是可选的,块是在流结束之前可以写入的数据,编码默认为 UTF8,回调将附加到 finish 事件。
这里有一个结束可写流的例子:
var fs = require('fs');
var writable = fs.createWriteStream('WriteStream.txt');
writable.end('Last data written.', 'utf8', function () {
//this runs when everything has been written.
});
net模块
Node.js 中的net模块允许我们创建网络连接。创建的连接将是我们可以写入和读取的流。本节将仅关注网络连接,而不是 HTTP。Node.js 有一个完整的 HTTP 模块,我们将在下一节中介绍。
所有这些函数都假设net模块已经以这种方式加载:
var net = require('net');
createServer
这个函数将创建一个 TCP 服务器:
net.createServer([options], [listener])
返回值
这返回一个net.Server对象。
描述
这个函数允许我们监听连接。返回的对象将是一个net.Server对象,连接监听器将被传递给一个net.Socket对象。我们将在稍后介绍这两个对象。
这里有一个简单的例子,展示了我们如何监听并写入套接字。每个连接都必须手动关闭:
var net = require('net');
var server = net.createServer(function (connection) {
connection.write('You connected!');
});
server.listen(5000, function () {
console.log('Listening on port 5000');
});
net.Server
我们现在将查看net.Server对象。下一节中的所有函数都需要通过createServer创建一个Server对象。
net.Server参数是一个EventEmitter,它将发出事件。以下是一个包含事件及其事件参数(如果有)的列表:
-
连接:
net.Socket -
close -
错误:
Error -
listening
这里有一个使用所有事件的例子:
var net = require('net');
var server = net.createServer();
server.on('listening', function () {
console.log('I am listening');
});
server.on('connection', function (socket) {
console.log(socket);
socket.end();
server.close();
});
server.on('error', function (err) {
console.log(err);
});
server.on('close', function () {
console.log('The server has stopped listening');
});
server.listen(5000);
listen
这开始接受连接:
server.listen(port, [host], [backlog], [callback])
描述
创建服务器并不会让它开始监听请求。我们必须至少提供一个端口号给监听函数。主机是可选的,因为它将监听所有 IPv4 地址,而 backlog 将是连接队列。最后,当服务器开始监听时,回调函数将被调用。
你可能会得到EADDRINUSE错误。这仅仅意味着该端口已经被另一个进程使用。
这里有一个定义所有参数的例子:
server.listen(5000, '127.0.0.1', 500, function () {
console.log('Listening on port 5000');
});
close
这关闭当前服务器:
server.close([callback])
描述
这将停止服务器创建新的连接。这一点很重要,因为它不会关闭当前连接。
当没有更多连接时,回调将被调用。
address
这获取端口号和地址:
server.address()
描述
这将给出服务器监听的端口号和 IP 地址。
getConnections
这获取连接数量:
server.getConnections(callback)
返回值
这返回一个整数。
描述
这不会给出每个连接的任何信息。它只返回数量。这是一个查看是否有连接的好方法。回调函数将需要是function(err, connections)的形式。
connect
这可以轻松地创建到指定地址的连接:
net.connect(port, [host], [connectListener])
net.createConnection(port, [host], [connectListener])
返回值
这返回一个net.Socket对象。
描述
这个函数并不做任何你不能用套接字做的事情。这是一个方便的函数,它返回一个net.Socket对象。
对于参数,需要一个端口号,主机将默认为 localhost,connectListener将被添加到新形成的net.Socket对象的连接事件中。
这里是一个示例,它将连接到我们刚刚创建的服务器,并且每秒发送数据:
var net = require('net');
var server = net.createServer();
server.on('listening', function () {
console.log('I am listening');
});
server.on('connection', function (socket) {
socket.on('data', function (d) {
console.log('from client: ' + d);
});
});
server.listen(5000);
var client = net.connect({ port: 5000, host: 'localhost' }, function () {
setInterval(function () {
client.write('hey!');
}, 1000);
});
net.Socket
这一节将与net.Server部分类似。net.Socket参数是在建立连接时返回的对象。它也可以用来创建新的连接。
它是一个可读和可写流。这是从net.Socket发送和接收数据的唯一方式。
这里是事件列表以及它们触发时的详细信息:
-
connect:在连接时。 -
data:当接收到数据时。 -
end:当套接字结束时。 -
timeout:当套接字由于不活动而超时时。此时套接字仍然打开。 -
drain:当写入缓冲区中的所有数据都已发送时。 -
Error:在出错时。 -
close:当套接字关闭时。
由于net.Socket是一个可读流,没有读取函数。你必须监听数据事件以获取数据。
这里是一个使用套接字连接到本地服务器的示例:
var server = net.createServer();
server.on('listening', function () {
console.log('I am listening');
});
server.on('connection', function (socket) {
socket.on('data', function (d) {
console.log('from client: ' + d);
});
});
server.listen(5000);
var client = new net.Socket();
client.on('connect', function () {
setInterval(function () {
client.write('Hey!');
}, 1000);
});
client.connect(5000, 'localhost');
connect
这创建了一个连接:
socket.connect(port, [host], [listener])
描述
这是实际创建连接的函数。与net.connection类似,端口是必需的,主机默认为 localhost,监听器将函数映射到连接事件。
这里是一个本地连接并写入连接的示例:
var client = new net.Socket();
client.on('connect', function () {
setInterval(function () {
client.write('Hey!');
}, 1000);
});
client.connect(5000, 'localhost');
write
这是在套接字上发送数据:
socket.write(data, [encoding], [callback])
描述
套接字是缓冲的,因为很容易排队比可以通过网络发送的数据更多的数据。这是 Node.js 自动完成的,但你应该意识到这一点,因为缓冲会使用内存来保存要发送的数据。
编码参数默认为 UTF8,但可以使用我们讨论过的任何编码。数据写入套接字后,将调用回调函数。
这里是一个定义了所有参数的示例:
var client = new net.Socket();
client.on('connect', function () {
client.write('This is the data', 'utf8', function(){
console.log('Data has been sent');
});
});
client.connect(5000, 'localhost');
end
这开始关闭套接字的过程:
socket.end([data], [encoding])
描述
这实际上是关闭套接字。我们无法确定,但原因可能是服务器可能发送一些数据,尽管套接字将很快关闭。
在套接字关闭之前,你可以发送一些数据,这就是可选参数的作用:
Here is an example that closes a socket.
var client = new net.Socket();
client.on('connect', function () {
client.end('I am closing', 'utf8');
});
client.connect(5000, 'localhost');
HTTP 模块
我们将介绍 HTTP 服务器模块。技术上,你可以使用net模块编写你的 HTTP 服务器,但你不必这样做。
其中一些函数与net模块的函数非常相似。这应该是有意义的,因为 HTTP 在本质上是一个网络服务器。
所有这些函数和对象也用于 HTTPS 模块。唯一的区别是,对于createServer和https.request的选项,你可以传递证书。
所有的以下示例都假设模块已经被加载:
var http = require('http');
createServer
这创建了一个 HTTP 服务器:
http.createServer([requestListener])
返回值
这返回一个http.Server对象。
描述
与net.createServer类似,这是提供任何内容所必需的。requestListener参数附加到请求事件。
这里有一个简单的示例,它会在请求被制作时记录到控制台:
var server = http.createServer(function (req, res) {
console.log('Someone made a request!');
res.end();
});
server.listen(8080);
http.Server
这是http.createServer返回的服务器对象。这是将响应所有请求的对象。
我们将从函数开始,并单独查看每个事件,因为事件对于处理请求非常重要。
监听
这告诉服务器在提供的端口、路径或文件描述符上监听:
server.listen(port, [host], [callback])
server.listen(path, [callback])
server.listen(fd, [callback])
描述
虽然这个函数有三种不同的执行方式,但你最可能只会使用网络监听器。实际上,其他两个监听器在 Windows 上执行起来可能很困难,甚至不可能。让我们快速了解一下最后两个。
路径监听器将使用本地套接字服务器,并且文件描述符需要一个句柄。如果这听起来很陌生,这意味着你将使用另一种方法。
网络监听器要求使用端口。如果没有传入任何内容,主机将默认为 localhost。在所有函数中,都会将一个回调函数附加到监听事件。
这里是一个在定义了所有参数的网络端口上监听的示例:
var server = http.createServer();
server.listen(8080, 'localhost', function(){
console.log('The server is listening');
});
关闭
这将关闭服务器:
server.close([callback])
描述
这将停止服务器监听。回调函数将附加到关闭事件。
这里有一个简单的示例:
var server = http.createServer();
server.listen(8080, 'localhost', function () {
server.close(function () {
console.log('Server has closed');
});
});
事件
http.Server参数是一个EventEmitter对象。事件也是大多数工作将完成的地方。
请求
当有请求进来时,此事件会被触发:
server.on('request', function (req, res) { });
描述
如果你只监听一个事件,这就是你要监听的事件。它包含request和服务器响应。req属性将是http.IncomingMessage,而res属性将是http.ServerResponse。在本节中,我们将查看这两个对象。此外,req实现了一个可读流接口,而res实现了一个可写流接口。
这里是一个监听请求的示例:
server.on('request', function (req, res) {
res.end();
console.log('A request was received');
});
关闭
当服务器关闭时,此事件会被触发:
server.on('close', function () { });
升级
当客户端发送 HTTP 升级时,此事件会被触发:
server.on('upgrade', function (req, socket, buffer) { });
描述
升级请求要求 Web 服务器更改协议。如果你正在实现 HTTP 之外的协议,你应该监听并处理此事件。一个很好的例子是WebSocket升级。
req属性是请求,套接字将是一个net.Socket,而buffer是一个 Buffer。
IncomingMessage
这是监听请求事件或从http.clientRequest返回的请求对象。这是一个可读的流。
头部信息
请求的 HTTP 头信息:
message.headers
描述
有时,你可能需要根据头部信息中的信息做出决策。以下是一个使用头部信息检查基本身份验证的示例:
server.on('request', function (req, res) {
if (req.headers.authorization !== undefined)
//do a check here
res.end();
});
方法
这将获取请求的 HTTP 方法:
message.method
描述
这将返回一个字符串形式的函数,并且是大写的。以下是一个GET方法的示例:
server.on('request', function (req, res) {
if (req.method === 'GET')
res.write(req.method);
res.end();
});
url
这是请求的 URL:
message.url
描述
这将是一个包含任何查询参数的 URL 字符串。你可以自己解析这个字符串,或者使用 Node 的查询字符串模块并使用parse函数。
下面是一个简单的示例,它将服务当前目录中的任何文件。请记住,这只是一个示例,并且没有进行错误检查:
server.on('request', function (req, res) {
var file = fs.createReadStream('.' + req.url);
file.pipe(res);
});
data
这是可读流接口的数据事件。
描述
如果你有一个传入的消息,你很可能会想知道消息的内容。由于它是一个可读流,我们需要监听数据事件以获取所有数据。当数据耗尽时,将触发结束事件。
下面是一个创建数据事件和结束事件的监听器的示例:
var data = '';
response.on('data', function (chunk) {
console.log(chunk);
data += chunk;
});
response.on('end', function () {
console.log(data);
});
ServerResponse
这是 HTTP 服务器为事件请求创建的响应。每个请求都需要一个响应,这就是它。这实现了可写接口。
writeHead
这将写入 HTTP 响应头:
response.WriteHead(statusCode, [headers])
描述
这将为响应写入头。这个方法必须在response.write之前调用。如果不这样做,服务器将自动为你发送带有你设置的头的响应。
statusCode是响应的 HTTP 状态码。一个header是一个对象,其属性是头的名称,值是头的值。
下面是一个写入头的示例:
server.on('request', function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end();
});
statusCode
这设置响应的状态码:
response.statusCode
描述
这是在response.writeHead被调用后使用的方法。如果在这个方法被调用之后writeHead已经被执行,那么它将不会改变响应头。它必须替代writeHead来调用。
下面是一个使用statusCode的示例:
server.on('request', function (req, res) {
res.statusCode = 404;
res.end();
});
setHeader
这将写入特定的头:
response.setHeader(name, value)
描述
与statusCode必须替代writeHead一样,setHeader也必须替代writeHead来调用。这个方法可以多次调用以设置多个头。
下面是使用statusCode和setHeader一起使用的示例:
server.on('request', function (req, res) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.setHeader('Custom-Header', 'Custom-Value');
res.end();
});
write
这是写入响应体的函数:
response.write(chunk, [encoding])
描述
response.write参数是一个可写流,因此可以使用这个接口。一个块可以是一个缓冲区或字符串。编码是可选的,因为它将默认为 UTF8。下面是一个写入简单 HTML 页面的示例:
server.on('request', function (req, res) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.write('<html><body><h1>Hello!</h1></body></html>');
res.end();
});
end
这结束响应:
response.end([data], [encoding])
描述
response参数是一个可写流,因此当我们完成写入时,我们必须结束流。数据是需要写入的任何可选数据,编码将默认为 UTF8。所有的响应示例都使用了res.end。如果你不结束响应,浏览器将等待来自服务器的响应。
http.request
这使用 HTTP 发起请求:
http.request(options, [callback])
返回值
这返回一个http.ClientRequest对象。
描述
Node.js 允许你消费 HTTP 请求以及提供 HTTP 服务。选项对象有许多可以设置的属性。以下是一个列表:
-
host -
hostname -
port -
localAddress -
socketPath -
method -
path -
headers -
auth -
agent
并非每个请求都需要每个选项。大多数时候,只需要 hostname、port、path 和 method 来进行请求。选项参数也可以是一个字符串形式的 URL。
回调将被附加到响应事件。请求对象是一个可写流,因此可以向服务器发送数据。以下是一个向 Packt Publishing 发送请求的示例:
var request = http.request({
host: 'www.packtpub.com',
port: 80,
path: '/',
method: 'GET'
}, function (res) {
console.log(res);
});
request.end();
http.get
这是 GET 请求的便捷方法:
http.get(options, [callback])
返回值
这返回一个 http.ClientRequest 对象。
描述
它的工作方式与 http.request 类似,但会自动发送一个空请求并调用结束函数。如果你只进行 GET 请求,这可以节省一些样板代码。
这里是一个请求 Packt Publishing 的示例:
http.get('http://www.packtpub.com', function (res) {
console.log(res);
});
http.clientRequest
这是 http.request 返回的对象。
write
这在请求中向服务器写入:
request.write(data, [encoding])
描述
http.clientRequest 属性是一个可写流。当你需要向远程服务器发送数据时,它可以被写入,例如,在执行 POST 请求时。
它与所有其他可写流的工作方式相同,因此数据可以是缓冲区或字符串,编码将默认为 UTF8。
end
这结束了请求:
request.end([data], [encoding])
描述
当你向流写入数据时,你必须使用此函数结束流。如果不这样做,连接将保持并/或超时。数据是可选的,可以是缓冲区或字符串,而编码将默认为 UTF8。
响应
这是响应事件。它让你知道远程服务器已经响应:
request.on('response', function(response){})
描述
当远程服务器响应时,此事件会被触发。回调中的响应对象将是 http.incomingMessage。
如果没有添加响应处理程序,服务器响应将被丢弃。如果有响应处理程序,那么 Node.js 将开始将响应缓冲到内存中。如果你不将其读回,可能会导致服务器崩溃。
这里是一个读取响应数据的示例监听器:
var request = http.request({host: 'www.google.com', path: '/', port: 80, method: 'GET'});
request.on('response', function (response) {
var data = '';
response.on('data', function (chunk) {
console.log(chunk);
data += chunk;
});
response.on('end', function () {
console.log(data);
});
});
第十三章. Bootstrap – 精美的 CSS 前端框架
Bootstrap 是一个使用 HTML 和 CSS 开发网站和应用程序的前端框架和开源工具。
Twitter Blueprint 是 Bootstrap 的初始名称。Mark Otto 和 Jacob Thornton 开发了 Bootstrap,并使用 Twitter 作为框架以保持一致性。根据 Twitter 开发者 Mark Otto 的说法:
"我和一小群开发者聚在一起设计和构建一个新的内部工具,并看到了做更多事情的机会。在这个过程中,我们看到了自己构建了一个比另一个内部工具更实质性的东西。几个月后,我们最终有了 Bootstrap 的早期版本,作为在公司内部记录和共享常见设计模式和资源的方式。"
Bootstrap 的第一个官方版本发布于 2011 年 8 月 19 日。目前有三个版本的 Bootstrap。然而,Bootstrap 4 已经宣布,但其最终版本尚未发布。
Bootstrap 基础介绍
Bootstrap 与包括 Firefox、Opera、Internet Explorer、Google Chrome 和 Safari 浏览器在内的许多最新版本的网页浏览器兼容。
HTML5 doctype 简介
要开始使用 Bootstrap,必须在每个 bootstrap 项目中包含以下 HTML5 doctype 的代码:
<!DOCTYPE html>
<html lang="en">
...
</html>
移动优先
Bootstrap 非常适合移动设备。移动优先样式都包含在一个库中,而不是分散在各种文件中。为了准确渲染和触摸缩放,请将 viewport 元标签添加到 <head> 中:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
可以通过将 viewport 元标签中的属性 user-scalable 设置为 no 来禁用缩放,如下所示:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
响应式图片
可以使用简单的类来使图片响应各种屏幕尺寸,如下所示:
<img src="img/..." class="img-responsive" alt="Responsive image">
容器
在 bootstrap 中,所有网页内容和网格系统都被包裹在一个主容器内。这些容器不可嵌套。
容器有两种类型,如下所示:
-
响应式固定宽度容器,例如:
<div class="container"></div> -
响应式全宽度容器,例如:
<div class="container-fluid"></div>
开始使用
现在是时候开始您的第一个 Bootstrap 项目或网站了。您可以从各种来源获取 Bootstrap。为了快速入门,这里有一些您可以使用来获取 Bootstrap 的资源。
GitHub 项目
Bootstrap 是 Twitter 创始人发起的开源项目。您可以从他们的 GitHub 仓库或您喜欢的任何命令行界面下载它。
下载 Bootstrap
您可以从以下链接轻松下载 Bootstrap:github.com/twbs/bootstrap/releases/download/v3.3.5/bootstrap-3.3.5-dist.zip
使用 bower 安装
您可以使用以下命令使用 bower 安装 Bootstrap:
$ bower install bootstrap
使用 npm 安装
您可以使用以下命令使用 npm 安装 Bootstrap:
$ npm install bootstrap
使用 composer 安装
您可以使用以下命令使用 composer 安装 Bootstrap:
$ composer require twbs/bootstrap
布局
布局帮助您定义网站的标准结构或骨架。有三种类型的布局:
-
固定布局
-
流体布局
-
响应式布局
固定布局不会随着屏幕尺寸的变化而改变,所有样式都是静态的。流体布局使得div元素在无法适应查看屏幕宽度时流向底部。响应式布局会密切关注并响应屏幕尺寸的调整。以下章节中描述了这些选项的使用方法。
固定布局
网站的固定布局有一个常宽度的包装器(它包裹或包含所有列),即无论屏幕分辨率多小或多宽,都不能更改。包装器或容器不能移动,并设置为固定位置。许多网页设计师更喜欢固定布局的原因在于其使用和定制的简便性。
描述
在固定布局中,列宽是固定的,不能更改。为您的网站声明固定布局的语法如下:
<body>
<div class="container"> <!--This line is for declaring fixed layouts-->
</div>
</body>
在前面的代码中,container类内部的所有内容将固定在执行此代码的每个设备上。
流体布局
流体布局就像液体一样,在运行时根据用户的屏幕分辨率调整自己。此类布局的组件主要包含百分比宽度,因此能够有效地调整到用户的屏幕。此类布局更易于用户使用,使网站看起来更好。它还提高了可访问性和界面。
描述
流体布局根据接收到的屏幕分辨率使用预定义的百分比宽度来自动调整。为您的网站声明流体布局的语法如下:
<div class="container-fluid"> <!--declaration of a fluid container-->
<div class="row-fluid">
<div class="span3"> <!--spans 3 columns -->
<!--Sidebar content-->
</div>
<div class="span5"> <!--spans 5 columns -->
<!--Body content-->
</div>
</div>
</div>
Bootstrap 的网格系统允许页面最多有 12 列。
在前面的示例中,span3组合了三列,span5组合了五列,它们共同完成整个页面,根据屏幕分辨率调整布局。
响应式布局
响应式布局根据条件数量为网站提供设计,这些条件包括比例、宽度、显示类型等。此类布局会自动调整和适应任何屏幕尺寸,从而为用户提供更好的可访问性和最佳观看体验。
描述
响应式布局在网页设计师中越来越流行,因为它们在定制和实施方面提供了更少的麻烦。
以下示例代码展示了如何使用元标签以及 Bootstrap 样式表来包含响应式特性:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
支持的设备
为了在不同的设备上提供有效的布局,Bootstrap 可以在一个文件中支持许多媒体查询。以下表格显示了支持的设备范围:
| 标签 | 布局宽度 | 列宽度 | 间隙宽度 |
|---|---|---|---|
| 大屏幕 | 1200px 及以上 | 70px | 30px |
| 默认 | 980px 及以上 | 60px | 20px |
| 纵向平板 | 768px 及以上 | 42px | 20px |
| 手机到平板 | 767px 及以下 | 流体列,无固定宽度可用 | |
| 手机 | 480px 及以下 | 流体列,无固定宽度可用 |
参考来源:getbootstrap.com/css/#grid-options
网格系统
使用行和列创建特定大小的网格并添加数据。以下是一些需要记住的指南:
-
使用
.container(fixed-width)或.container-fluid(full-width)方法放置行,以实现准确的对齐。 -
横向的列组可以使用行创建。在列中插入数据,并且只有列可以是行的直接子元素。
填充用于列创建间隙。这种缓冲在.lines的第一和最后一部分通过负边距来平衡。通过指定列数来启动列。一行中不能启动超过 12 列,所有额外的列都将跳转到新的一行。网格类适用于屏幕宽度大于或等于断点大小的设备,并覆盖针对较小设备的网格类。
网格选项速查表
以下表格显示了 Bootstrap 网格系统可以用于多个设备的几种有效方法:
| 大型设备(>=1200 px) | 中型设备(>=992 px) | 小型设备(如平板电脑)(>=768px) | 超小设备(如手机)(<768px) | |
|---|---|---|---|---|
| 网格行为 | 默认折叠,在断点以上水平排列 | 总是水平排列 | ||
| 最大容器宽度 | 1170px | 970px | 750px | 无(自动) |
| 类前缀 | .col-lg- |
.col-md- |
.col-sm- |
.col-xs- |
| 列数 | 12 | |||
| 最大列宽 | 95px | 78px | 60px | 自动 |
| 间隙宽度 | 350px(每列两侧各 15px) | |||
| 可嵌套 | 是 | |||
| 偏移量 | 是 | |||
| 列排序 | 是 |
媒体查询
媒体查询帮助网站根据屏幕大小调整样式。我们可以在我们的LESS文件中使用媒体查询来创建网格系统中的关键断点。观察速查表,我们可以编写媒体查询。让我们看看以下代码片段:
/* Large Device (>=1200 px) */
@media (min-width: @screen-lg-min) { ... }
/*Medium Devices (>=992 px)*/
@media (min-width: @screen-md-min) { ... }
/* Small Devices such as Tablets (>=768px) */
@media (min-width: @screen-sm-min) { ... }
/* Extra small devices such as Phones (<768px)*/
/* No media query as this is the default*/
我们偶尔会扩展这些媒体查询,包括最大宽度以限制 CSS 适用于更窄的设备集:
/* Large Device (>=1200 px) */
@media (min-width: @screen-lg-min) { ... }
/*Medium Devices (>=992 px)*/
@media (min-width: @screen-md-min) and (max-width: @screen-md-max) { ... }
/* Small Devices such as Tablets (>=768px) */
@media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { ... }
/* Extra small devices such as Phones (<768px)*/
@media (max-width: @screen-xs-max) { ... }
响应式列重置
我们需要这些类型的列,因为在网格中,由于数据量的不同,并非所有列都以相同的对齐方式结束。然而,响应式列将确保一切完美对齐。让我们看看以下代码片段:
<div class="row">
<div class="col-xs-6 col-sm-3" style="background-color:pink">.col-xs-6 .col-sm-3</div>
<div class="col-xs-6 col-sm-3" style="background-color:brown;">.col-xs-6 .col-sm-3</div></div>
<!-- Add the extra clearfix for only the required viewport -->
<div class="clearfix visible-xs-block"></div>
<div class="col-xs-6 col-sm-3" style="background-color:orange;>.col-xs-6 .col-sm-3</div>
<div class="col-xs-6 col-sm-3" style="background-color:black;>.col-xs-6 .col-sm-3</div>
</div>
偏移列
有时,我们需要放置一个列或从一些空闲空间偏移处开始一个列。因此,我们设置一个偏移量,从列需要开始的地方:
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">.col-md-6 .col-md-offset-3</div>
</div>
嵌套列
如其名所示,嵌套列是在列中嵌入列的一种方式。让我们看看以下代码片段:
<div class="row">
<div class="col-md-9">
Level 1: .col-md-9
<div class="row">
<div class="col-md-6">
Level 2: .col-md-6
</div>
<div class="col-md-6">
Level 2: .col-md-6
</div>
</div>
</div>
</div>
列排序
列排序也可以通过将列向右或向左移动来改变。以下代码显示了如何移动列:
<div class="row">
<div class="col-md-9 col-md-push-3">.col-md-9 .col-md-push-3</div>
<div class="col-md-3 col-md-pull-9">.col-md-3 .col-md-pull-9</div>
</div>
LESS 变量和混入
LESS 混入(mixins)和变量用于通过变量和混入提供的特定值快速实例化布局。
混入
混入(mixins)主要用于与网格变量(grid variables)一起使用,为单个元素提供 CSS 样式。
描述
如其名所示,混入(mixins)是一种将一组属性从一个规则集包含或混合到另一个规则集中的方法。以下示例显示了 make-row() 混入:
make-row (@gutter: grid-gutter-width) {
margin-left : (@gutter / -2);
margin-right : (@gutter/ -2);
&: extend( .clearfix all);
}
make-row() 混入为包含所有列的包装元素生成样式。它使用 @gutter 参数的值来计算行的左右边距。
变量
媒体查询点(media query point)从哪里开始浮动列,列的总数和间隙宽度由变量确定。这些信息由变量提供,以生成预定义的网格类,以及用于自定义混入(custom mixins)。
描述
变量与混入(mixins)一起使用,以生成单个元素的样式。
以下代码块预定义了一些在混入(mixins)中用作默认值的变量:
//Number of columns in the grid.
@grid-columns: 12;
//padding between columns. Divided in half for left and right.
@grid-gutter-width: 30px;
//point at which the navbar collapses.
@grid-float-breakpoint: 768px;
字体排印
字体排印是安排字体元素的艺术和技术,使书面语言在显示时易于阅读、可读且吸引人,使用标题、粗体字体、斜体字体、粗体字体、列表等。
标题
在 Bootstrap 中,从 h1 到 h6 的所有标题都可用。标题主要用于突出讨论中的主要主题。标题文本应包含在适当的 HTML 标题标签之间,例如 <h1> 这里是标题文本 </h1>。标题的大小随着标题数字的增加而减小,提供了突出主要主题和子主题的功能。这种技术有助于为网站管理适当的设计。
这里有一些关于如何使用标题的示例:
<h1> This is a Bootstrap heading H1</h1>
<h2> This is a Bootstrap heading H2</h2>
<h3> This is a Bootstrap heading H3</h3>
<h4> This is a Bootstrap heading H4</h4>
<h5> This is a Bootstrap heading H5</h5>
<h6> This is a Bootstrap heading H6</h6>
正文
所有与字体排印和设计相关的 HTML 标签都必须包含在 body 标签内,例如文本、超链接、图像、表格、列表等。以下代码显示了一个段落标签,它显示了段落中的文本:
<p>...</p>
领头正文
领头类(lead class)有助于使标签内的文本突出。其声明方法如下所述:
<p class="lead">...</p>
着重号
着重号基本上将文本的大小和字体与其在文档中的重要性相关联。例如,较大的文本比较小的文本或斜体文本更重要,或者斜体文本可能包含来自其他资源的引用。
小文本
small 标签内的文本主要减小到原始大小的 85%。这种技术主要用于降低文本的重要性:
<small>...</small>
粗体文本
strong 标签内的文本通过使其更大和更粗来提高其可见性。这有助于在文档中增加文本的强调:
<strong>...</strong>
斜体文本
em 标签内的文本将被设置为斜体。这种技术主要用于表示参考文献,以及其他许多用途:
<em>...</em>
对齐
对齐是一种基本技术,用于将段落对齐到屏幕的左侧、右侧或居中,无论屏幕分辨率如何:
<p class="text-left">Text here will be left-aligned</p>
<p class="text-center"> Text here will be center-aligned </p>
<p class="text-right"> Text here will be right-aligned </p>
缩写
HTML 定制的 <abbr> 元素可以使用以下语法使用,如下面的代码片段所示。
基本版
<abbr> 标签显示文本的较小版本,当鼠标悬停在其上时将展开:
<abbr title="attribute">Here is an example of an attribute tag</abbr>
此代码的输出将显示 attr 缩写。
首字母缩略词
首字母缩略词与基本缩写具有相同的功能,但文本较小:
<abbr title="HyperText Markup Language" class="initialism">HTML using Initialism</abbr>
地址
地址标签用于容纳与地址相关的所有文本。以下示例显示了格式:
<address> …
<strong>Packt PublishingPublishing.</strong><br>
Berwick House, <br>
35 Livery St, <br>
Birmingham B3 2PB,<br>
United Kingdom <br>
<abbr title="Phone">P:</abbr> +44 121 265 6484
</address>
块引用
块引用主要用于引用其他来源的文本。它们与段落标签一起使用,以引用段落:
<blockquotes> … </blockquotes>
表格
表格用于以有组织的形式清晰地显示内容,以便数据易于访问和阅读。
| # | 类别 | 项目 | 项目 ID |
|---|---|---|---|
| 1 | 服装 | 蓝衬衫 | App_BlueShirt |
| 2 | 服装 | 白大褂 | App_WhiteCoat |
| 3 | 配件 | 皮带 | Acc_LeatherBelt |
基本版
在前面的表格中,是带有轻量填充和仅水平分隔符的 Bootstrap 表格的基本版本。其语法如下:
<table class="table"> ... </table>
斑马纹行
斑马纹行的结构与基本表格相同,其样式类似于斑马线的条纹,即浅色和深色交替的行:
<table class="table table-striped"> ... </table>
有边框的表格
此类将表格转换为具有可见边界的等分。每个部分包含一个单一值:
<table class="table table-bordered"> ... </table>
悬停行
此类添加了突出显示鼠标悬停行的功能:
<table class="table table-hover"> ... </table>
紧凑行
通过减少行之间的填充,可以实现更紧凑和更小的表格版本:
<table class="table table-condensed"> ... </table>
上下文类
当上下文类应用于表格行或单元格时,它们将具有预定义的颜色。以下是一些可用的类:
-
.active: 此类将悬停颜色应用于表格行 -
.success: 此类将绿色应用于表格行 -
.info: 此类将蓝色应用于表格行 -
.warning: 此类将黄色应用于表格行 -
.danger: 此类将红色应用于表格行
我们可以将整个行或单个单元格设置为显示特定颜色,以表示特定的信息。以下是如何实现此功能的示例:
<!-- Contextual classes when applied on rows -->
<tr class="active">...</tr>
<tr class="success">...</tr>
<tr class="warning">...</tr>
<tr class="danger">...</tr>
<!-- Contextual classes when applied on cells (`td` or `th`) -->
<tr> <td class="active">...</td>
<td class="success">...</td>
<td class="warning">...</td>
<td class="danger">...</td> </tr>
响应式表格
响应式表格在小设备上会自动调整以水平滚动。差异仅在小型设备上可见:
<div class="table-responsive">
<table class="table"> ... </table>
</div>
列表
列表用于按特定顺序分组数据,或者可以取消分组以按顺序显示数据。
列表可以是以下类型:
-
无序列表 -
有序列表 -
无样式 -
内联 -
描述
无序列表
无序列表是一组项目集合,其中项目的顺序无关紧要。以下是无序列表的语法:
<ul>
<li>...</li>
<li>...</li>
</ul>
有序列表
有序列表是一组项目,其中顺序很重要。以下是有序列表的语法:
<ol>
<li>...</li>
<li>...</li>
</ol>
无样式列表
无样式列表可以通过移除左外边距和默认列表样式来有序或无序。以下是无样式列表的语法:
<ul class="list-unstyled">
<li>...</li>
<li>...</li>
</ul>
内联列表
内联列表将列表的所有项目排列成一行或一行。以下是内联列表的语法:
<ul class="list-inline">
<li>...</li>
<li>...</li>
</ul>
描述列表
描述列表包含列表项及其描述。以下是描述列表的语法:
<dl>
<dt>...</dt>
<dd>...</dd>
</dl>
水平描述
水平描述类与描述列表类做同样的事情,唯一的区别在于列表项的相应描述在同一行中的位置。以下是水平描述列表的语法:
<dl class="dl-horizontal">
<dt>...</dt>
<dd>...</dd>
</dl>
Bootstrap 中的表单
表单元素是 Bootstrap 中用于使导航和 GUI 更具吸引力和满足感的各种元素。使用各种文本框、按钮等可以产生更好的输出。
表单有三种布局类型:
-
垂直表单
-
内联表单
-
水平表单
垂直表单
垂直表单是 Bootstrap 表单的默认布局。这里使用的属性是 role,其值设置为 form,以提供更好的可访问性和自动默认样式。该语法的格式如下:
<form role="form"> … </form>
内联表单
许多时候,我们也会遇到表单元素内联且单行左对齐的情况。内联表单需要为 <form> 元素添加 form-inline 类。该语法的格式如下:
<form class="form-inline" role="form"> … </form>
水平表单
水平表单是这一组中最巧妙的,在网页上广泛用于收集网站用户的资料。这种表单的外观和性能是它区别于其他两种表单类型的地方。这种表单将标签和表单控件组水平对齐。
水平表单需要为 <form> 元素添加 form-horizontal 类。此外,标签需要为 <label> 元素添加 control-label 类。语法如下:
<form class="form-horizontal" role="form"> … </form>
Bootstrap 中表单的输入
所有 HTML 支持的输入类型在 Bootstrap 中都可以使用,这使得有 HTML 背景的人可以轻松掌握这些概念。如文本区域、密码、单选按钮、复选框等输入都在 Bootstrap 中得到支持。
简单文本框作为输入方式的语法如下:
<input type="text" class="form-control" placeholder="Text input" id ="txtName">
如果我们想要文本被修改为不显示实际输入的字母,则可以使用 input 类型的 password。使用 input 类型作为 password 的语法如下:
<input type="password" class="form-control" placeholder="Text input" id="txtPassword">
文本区域
文本区域是用户输入文本的区域;它可以容纳从少量单词到大量段落的文本。文本区域的语法如下:
<textarea class="form-control" rows="44"></textarea>
前一行告诉控件文本区域必须跨越四行。
帮助文本
help 块为表单控件提供块级帮助文本:
<span class="help-block"> </span>
复选框
checkbox 控制为相关选项组分配一个框,用户可以通过点击框来选择。当用户需要只从给定选项中选择时,会使用此功能。添加复选框的语法如下:
<div class="checkbox"> </div>
添加禁用复选框的语法如下:
<div class="checkbox disabled"> </div>
选择列表
select 类控制触发一个下拉菜单,其中包含一组选项,一次只能选择一个。其语法如下:
<select class="form-control"> … </form>
单选按钮
radio 类控制与 checkbox 控制执行相同的功能,但用户一次只能选择一个选项。其语法如下:
<div class="radio"> … </div>
添加禁用 radio 类的语法如下:
<div class="radio disabled"> </div>
静态控制
static 类控制允许用户在其对应标签旁边插入文本。可以使用 "form-control-static" 类在段落标签内添加文本到表单标签旁边。必须使用 form-static-control 类。
以下示例插入静态文本——“Web 开发者参考指南”:
<p class="form-control-static">Web Developer's Reference Guide<p>
输入焦点
input 类允许输入字段在页面加载时自动聚焦。其语法如下:
<input class="form-control" id="focusedInput" type="text" value="...">
禁用输入
disabled 属性禁用特定文本框中的输入,无法点击或使用。要使用此功能,可以将 disabled 属性添加到 <fieldset> 标签以禁用其所有控件。
验证状态
这些类在从服务器返回消息时为输入控件赋予意义,例如字段被留空或输入了错误的组合。
可以通过添加 .has-success、.has-warning 或 .has-error 到类中来使用验证状态。以下代码显示了这一点:
<div class="form-group has-success"> … </div>
<div class="form-group has-warning"> … </div>
<div class="form-group has-error"> … </div>
控件尺寸
用户可以轻松设置各种列的高度以满足其需求。
我们可以使用类如 .input-lg 和 .col-lg-* 等轻松设置高度和宽度:
<input class="form-control input-lg" type="text" placeholder=".input-lg">
<div class="col-xs-2"> … </div>
图片
我们可以通过添加类到 <img> 元素来使用内置 CSS 样式进行图像处理:
<img src="img/..." alt="..." class="img-rounded">
<img src="img/..." alt="..." class="img-circle">
<img src="img/..." alt="..." class="img-thumbnail">
以下代码将创建以下图像:

注意
注意,Internet Explorer 8 不支持图像的圆角。
图标(Glyphicons)
Glyphicon 是用于帮助用户理解功能意义的小图标。例如,电子邮件将有一个信封图标,搜索将有一个放大镜图标,等等。以下图中显示了某些 Glyphicons:

更多 250 个以字体格式存在的 Glyphicons 在 Glyphicon Halflings 集中。以下是向 Bootstrap 添加 Glyphicons 的方法:
<span class="glyphicon glyphicon-search"></span>
注意
所有可用的 Glyphicons 都可以在 getbootstrap.com/components/ 找到。
导航元素
Bootstrap 支持多种类型的导航元素,可以使用以下代码描述:
标签页
tab 类在导航栏上创建小标签页,每个标签页提供链接到不同的页面:
<ul class="nav nav-tabs"> … </ul>
标签基本上是链接到其他页面或网站的链接;因此,tab 类应该在链接标签内声明,如前述代码所示。
药丸
pill 类与 tab 类具有相同的功能,唯一的区别在于样式。标签现在看起来像药丸:
<ul class="nav nav-pills"> … </ul>
对齐
添加一个额外的 nav-justified 类会允许标签或药丸根据屏幕分辨率自动调整自身。标签或药丸被赋予相等的宽度:
<ul class="nav nav-tabs nav-justified"> … </ul>
禁用链接
在导航栏中的标签或药丸上添加 disabled 类会移除悬停状态,禁用链接访问:
<ul class="nav nav-pills">
...
<li class="disabled"><a href="#">Disabled link</a></li>
...
</ul>
注意
请记住将实际链接放在 # 的位置。
导航栏
Bootstrap 中的导航帮助用户在网站中导航。它允许快速访问用户经常访问的链接。
默认
使用 .navbar 和 .navbar-default 包含在导航标签中创建一个简单的导航栏,使用 navbar 类:
<nav class="navbar navbar-default" role="navigation">
要制作一个可伸缩、响应式的菜单栏,当在移动设备上显示时可以折叠成下拉菜单,请使用以下类来包装栏:
<div class="navbar-header">
表单
您还可以通过添加 .navbar-form 类将表单放入导航栏中:
<form class="navbar-form navbar-left" role="search">
按钮
与 navbar 类类似,.navbar-btn 在栏中添加一个按钮,可以执行许多有用的功能:
<button type="button" class="btn btn-default navbar-btn"> … </button>
文本
通过添加 .navbar-text 类,我们还可以在导航栏中添加文本:
<p class="navbar-text"> … </p>
非导航链接
navbar-link 类允许我们添加标准链接,这些链接不在 navbar 导航组件中:
<p class="navbar-text navbar-right">
<a href="#" class="navbar-link"></a>
</p>
固定到顶部
在 <nav> 标签内添加 navbar-fixed-top 类允许 navbar 在页面顶部动态定位。以下是其语法:
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
固定到底部
navbar-fixed-bottom 类允许导航栏位于页面底部。以下是其语法:
<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation">
静态顶部
navbar-static-top 类为导航栏添加了一个新功能,允许元素随页面滚动。以下是其语法:
<nav class="navbar navbar-default navbar-static-top" role="navigation">
倒置导航栏
navbar-inverse 类仅更改导航栏的颜色,并将其变为相反的颜色。例如,navbar 获得黑色背景和白色文本:
<nav class="navbar navbar-inverse" role="navigation">
面板
面板是包含纯文本的简单框。面板主要用于以视觉上吸引人的方式展示重要信息。
基本
一个基本面板由一个包含一些文本的单个框组成。其声明方法如下:
<div class="panel panel-default"> … </div>
标题
panel-heading 类在基本面板上方添加了一个额外的框,其中包含其标题或标题。这两个框默认颜色不同。以下是语法:
<div class="panel-heading">This is a Panel Heading</div>
页脚
panel-footer 类在基本面板下方添加一个框,其中也包含某种文本。以下是语法:
<div class="panel-footer">This is a Panel Footer</div>
组
panel-group 类下的面板被分组在一起。以下是语法:
<div class="panel-group">
面包屑
面包屑作为帮助工具,跟踪您访问不同页面所采取的路径。使用面包屑,您可以知道网站中页面的当前位置。
面包屑用于在导航层次结构中找到当前页面的路径。
这里是一个示例代码:
<ol class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Library</a></li>
<li class="active">Data</li>
</ol>
标签和徽章
标签和徽章提供帮助工具,通过计数或显示网站加载状态等方式跟踪渐进因素,如数值指标、计数、百分比等。
标签
标签与不同的标题或标题相关联,有助于记录计数或提供提示等。标签可以声明如下:
<h3>This is an example Heading<span class="label label-default">This is an example label</span></h3>
徽章
徽章与标签相同,唯一的区别是形状。徽章比标签有更多的曲线形状。它们主要用于通知用户新更改、未读电子邮件等。让我们看看以下代码片段:
<a href="#">Check EMailsEMails <span class="badge">4545</span></a>
分页
分页是将数据分组到各个页面上的操作,就像教科书一样,通常将相同重要性的数据发布在同一页面上以更好地访问。分页具有高度的可扩展性,提供更大的点击区域,不易错过。分页可以与表格一起使用,对于分页搜索结果非常有用。
默认
以下是一个基本的 Bootstrap 分页示例:
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
在 <li> 中添加 .active 将突出显示当前页面链接:
<li class='active'><a href="#">3</a></li>
在 <li> 中添加 .disabled 将禁用页面链接并使其不可点击:
<li class='disabled'><a href="#">3</a></li>
分页器
下一页和上一页链接用于分页以快速访问。分页器主要用于简单的网站,如杂志、报纸或博客等。以下是语法:
<ul class="pager"> … </ul>
进度条
基本进度条是一个根据进度水平填充的矩形条。这些条主要用于显示关于动作的当前进度。
创建进度条的代码如下:
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="505"
aria-valuemin="0" aria-valuemax="100" style="width:505%">
</div>
</div>
注意
更多信息请访问:www.w3schools.com/bootstrap/bootstrap_progressbars.asp。
高级 Bootstrap/JavaScript 插件
Bootstrap 可以从强大的 JavaScript 库中受益,以在网页上显示各种类型的动态内容。Bootstrap 插件需要 jQuery 作为依赖项。这些包括按钮、下拉菜单、工具提示、警告、标签页等。我们现在将介绍如何使用它们。
按钮
在 Bootstrap 中,按钮可以用于各种组合。
基本
btn-group 类生成一个默认的灰色按钮,具有曲线边缘,当用户点击时可以触发任何功能:
<div class="btn-group"> … </div>
按钮工具栏
btn-toolbar 类将所有包含在 btn-toolbar 类中的按钮组合在一起:
<div class="btn-toolbar" role="toolbar"> … </div>
尺寸
sizing 类用于一次性调整按钮组的大小,只需添加 btn-group-*。
声明如下所示:
<div class="btn-group btn-group-lg">...</div> //large
<div class="btn-group">...</div> //normal
<div class="btn-group btn-group-sm">...</div> //small
<div class="btn-group btn-group-xs">...</div> //extra small
嵌套
通过在 btn-group 中放置一系列按钮来创建下拉菜单,如下所示:
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default">Alpha</button>
<button type="button" class="btn btn-default">Beta</button>
<button type="button" class="btn btn-default">Gamma</button
<div class="btn-group" role="group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle ="dropdown"> List of Top Publishers</button>
<ul class="Top Publishers">
<li><a href="https://www.packtpub.com/"> Packt Publishing</a></li>
<li><a href="http://www.oreilly.com/"> O'Reilly</a></li>
</ul>
</div>
</div>
垂直变化
btn-group-vertical类以垂直方式排列一组按钮。以下是语法:
<div class="btn-group-vertical"> ... </div>
水平居中链接变体
btn-group-justified类允许按钮组根据任何屏幕分辨率进行调整,并为按钮提供相等的宽度。以下是语法:
<div class="btn-group btn-group-justified"> ... </div>
下拉菜单
当用户点击下拉菜单中的按钮时,会触发下拉菜单。下拉菜单主要用于访问相关链接。
单按钮
btn btn-default dropdown-toggle类将按钮转换为简单的下拉菜单。其声明如下所示:
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
</button>
分离按钮
btn btn-danger类不会将按钮完全转换为下拉菜单,而是将按钮分成两部分,其中一部分执行简单的按钮功能,另一部分成为下拉菜单:
<div class="btn-group">
<button type="button" class="btn btn-danger">Action</button>
<button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Toggle for Dropdown</span>
</button>
</div>
工具提示
工具提示是在指针悬停在元素上时弹出的小框。
要创建工具提示,请将data-toggle="tooltip"属性添加到元素上。要将data-toggle="tooltip"属性添加到元素上以创建工具提示,请使用title属性指定显示在工具提示内的文本:
<a href="#" data-toggle="tooltip" title="Tooltip">…</a>
定位
定位工具用于定位工具提示的弹出框,例如,当框可能出现在元素的顶部、底部、左侧或右侧时:
这里是定位到顶部的语法:
<a href="#" data-toggle="tooltip" data-placement="top" title="Tooltip">Tooltip at the top</a>
这里是定位到底部的语法:
<a href="#" data-toggle="tooltip" data-placement="bottom" title="Tooltip"> Tooltip at the bottom</a>
这里是定位到元素左侧的语法:
<a href="#" data-toggle="tooltip" data-placement="left" title="Tooltip">Tooltip at the left</a>
这里是定位到元素右侧的语法:
<a href="#" data-toggle="tooltip" data-placement="right" title="Tooltip"> Tooltip at the right</a>
注意
记得将实际的链接放在#的位置。
弹出框
弹出框和工具提示具有相同的功能,唯一的区别是,对于弹出框要出现,元素需要被用户点击。它们用于呈现有关元素的附加信息。
基本创建
可以使用以下代码生成弹出框:
<a href="#" data-toggle="popover" title="Popover Header" data-content="Some content inside the popover">Toggle popover</a>
定位
可以使用以下代码将弹出框定位在元素的顶部、底部、左侧或右侧:
这里是定位弹出框到顶部的语法:
<a href="#" title="Header" data-toggle="popover" data-placement="top" data-Content="Content"> Popover at the top </a>
这里是定位到底部的语法:
<a href="#" title="Header" data-toggle="popover" data-placement="bottom" data-content="Content"> Popover at the bottom </a>
这里是定位到左侧的语法:
<a href="#" title="Header" data-toggle="popover" data-placement="left" data-content="Content"> Popover at the leftleft</a>
这里是定位到右侧的语法:
<a href="#" title="Header" data-toggle="popover" data-placement="right" data-content="Content">PopoverPopover at the right </a>
注意
记得将实际的链接放在#的位置。
关闭
popover类允许在点击其他地方时关闭弹出框:
<a href="#" title="Dismissible popover" data-toggle="popover" data-trigger="focus" data-content="Click anywhere in the document to close the popover">Click here to close popover</a>
警告
Bootstrap 提供了显示警告消息的实用功能。其声明的代码如下。Bootstrap 还允许您为警告消息分配不同的颜色,以表示不同的情况。Bootstrap 需要 jQuery,并且在此语法中的$表示我们正在调用 jQuery。让我们看看以下代码:
<button type="button" class="close" data-dismiss="alert" aria label="Close"> <span aria-hidden="true">×</span> </button>
警告的语法如下:
$().alert():
它监听具有data-dismiss-alert的数据元素上的点击事件。语法如下:
$().alert('close'):
这将从 DOM 中移除一个警告。如果元素包含.fade和.in类,它将淡出。
选项卡
标签页用于导航栏,以提供快速访问不同的链接或页面。标签页需要单独激活,如下所示:
<div class="container">
<h1>Alpha Zoo</h1>
<ul class="nav nav-tabs">
<li class="active">
<li><a href="#">Exhibit A to Exhibit H</a></li>
<li><a href="#">Exhibit I to Exhibit M</a></li>
<li><a href="#">Exhibit N to Exhibit Y</a></li>
<li><a href="#">Mini Aquarium</a></li>
<li><a href="#">Alpha Aviary</a></li>
<li><a href="#">Adopt an animal for just $4</a></li>
</ul>
<br>
<p>Welcome to our Zoo! We take pride in the happy animals we house.</p>
</div>
我们可以使用 fade 类在查看后淡出标签页的内容:
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="homepage">...</div>
<div role="tabpanel" class="tab-pane fade" id="profile">...</div>
<div role="tabpanel" class="tab-pane fade" id="posts">...</div>
<div role="tabpanel" class="tab-pane fade" id="settings">...</div>
</div>
折叠面板
许多时候,我们会遇到需要在单个页面内管理大量信息的场景。将所有这些内容放在一个页面上可能会导致创建一个非常长的页面,对于使用网站的人来说,上下滚动可能会很令人沮丧。折叠小部件用于解决这个问题,因为它们在网站上用于管理大量内容和导航列表。它们基本上是可折叠的面板,其中放置了信息。使用 Bootstrap 折叠插件,创建折叠面板非常简单。
以下代码创建了一个具有面板组件的折叠面板:
<div class="panel-group" id="accordion">
<H1> Welcome to Alpha Zoo </H1>
<p>Welcome to our Zoo! We take pride in the happy animals we house.</p>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">
Exhibit A to Exhibit H</a>
</h4>
</div>
<!--Data for Panel 1-->
<div id="collapse1" class="panel-collapse collapse in">
<div class="panel-body">
These exhibits are for animals from the tropical regions of the planet. Take a guided tour through Exhibit A, our largest exhibit housing our bengal tigers Uri and Kayla with their cubs at exhibit A or simply feed our talking toucan Charlie in Exhibit D.
<a href='#'> See more</a>
</div>
</div>
</div>
<!--Data for Panel 2-->
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse2">
Exhibit I to Exhibit M</a>
</h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">
This is the second panel. The content for the second panel will go in here.
</div>
</div>
</div>
</div>
模态框
模态框插件是显示在页面顶部的弹出窗口或框。一个模态框看起来像这样:
模态框大小
模态对话框有两种大小。小型模态框可用于处理小型功能,而大型模态框可用于提示大型数据集。
小型
modal-dialog modal-sm 类创建一个小型模态框。以下是语法:
<div class="modal-dialog modal-sm">
大型
modal-dialog modal-lg 类创建一个大型模态框。以下是语法:
<div class="modal-dialog modal-lg">
媒体对象
媒体对象是抽象的对象样式,可用于制作博客评论或其他描述性缩略图:
-
.media: 这个类将media对象浮动到内容块的右侧或左侧 -
.media-list: 这个类形成了一个无序列表的项目:<div class="media"> <a class="pull-left" href="#"> <img class="media-object" data-src="img/64x64"> </a> <div class="media-body"> <h4 class="media-heading">This is the Main Media heading </h4> </div> <div> <ul class="media-list"> <li class="media"> <a class="pull-left" href="#"> <img class="media-object" data-src="img/64x64"> </a> <div class="media-body"> <h4 class="media-heading">This is a Media heading </h4> <!-- Nested media object --> </div> </li> </ul>
轮播图
轮播图插件允许您在查看每个元素的同时使元素在圆形中移动。
轮播图通过循环显示组件。以下代码可以创建一个动物照片的轮播图:
<div id="myCarousel" class="carousel slide" data-ride="carousel"> <!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="img/Emperor_Penguin.jpg" alt="Emperor Penguin">
</div>
<div class="item">
<img src="img/bengal_tiger.jpg" alt="Tiger">
</div>
<div class="item">
<img src="img/african_elephant.jpg" alt="Elephant">
</div>
<div class="item">
<img src="img/australian_kiwi.jpg" alt="Kiwi">
</div>
</div>
<!-- Left and right controls -->
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a></div>
Typehead
Typehead 只是一种文本框的另一种形式,它会在用户在文本框中输入文本时提供文本预测,如果编程为提前输入美国各州的状态,它可能看起来像这样:

如何创建 typehead
以下代码显示了您如何创建一个简单的 typehead 文本框:
<input type="text" data-provide="typeahead">
通过 JavaScript 使用 typehead
我们可以使用以下代码调用 typehead:
$('.typeahead').typeahead()
对于完整的实现,请访问 twitter.github.io/typeahead.js/examples/。
Scrollspy
Scrollspy 插件允许导航目标在用户上下滚动时自动更新自己。
Scrollspy 可以帮助在随机滚动时识别您到达的页面部分,使查找所需数据变得更加容易。Scrollspy 插件通常可以通过两种方式激活,我们现在将看到。
通过数据属性激活 Scrollspy
数据属性允许通过向元素添加 <data-spy ="scroll" 来监视特定元素:
<body data-spy="scroll" data-target=".navbar">...</body>
通过 JavaScript 激活 Scrollspy
Scrollspy 也可以通过选择元素并执行scrollspy()函数由 JavaScript 触发:
$('#navbar').scrollspy()
Affix
affix插件用于将元素锁定在页面上的某个区域。
affix 插件可以通过数据属性或 JavaScript 激活。affix 插件用于在网站上放置社交图标,它们被锁定在一个位置,以便用户随时访问。
通过数据属性激活 affix 插件
使用以下方法激活affix工具:
<div data-spy="affix" data-offset-top="200">...</div>
通过 JavaScript 激活 affix 插件
我们还可以通过以下代码手动使用 JavaScript 激活affix工具:
$('#navbar').affix()
自定义 Bootstrap
由于 Bootstrap 是一个非常庞大的项目,包括所有其仓库实际上并非必需,即使你包括了它们,这也可能给你的网站带来巨大的负载,使其变得缓慢并影响用户体验。为了获取适合你特定需求的 Bootstrap 引擎,请访问 getbootstrap.com/customize/ 并导入具有所需设置的样式文件。你还可以在先前的链接中导入现有的设置文件,在 GUI 中添加或删除选项,并获取一个无需编写任何代码的更新版本。
使用 Bootstrap 构建的网站
WordPress 已经存在,许多大型网站和公司都在使用它。Twitter 的网站本身就是用 Bootstrap 制作的。看看一些使用 Bootstrap 框架构建的著名网站:
Bootstrap 资源
互联网上充满了 Bootstrap 资源;以下是一些:
-
www.wrapbootstrap.com: 你可以在 WrapBootstrap 上购买或出售。这是一个大型的高质量模板和主题市场。
-
www.bootswatch.com: Bootstrap 主题 在 MIT 许可下发布,并由 GitHub 上的社区维护。主题是为 Bootstrap 的最新版本构建的。
-
www.startbootstrap.com: Startbootstrap 是学习和开发 Bootstrap 的简单方法,因为它包含数千个启动主题和模板,甚至包括 Bootstrap 3。
-
themes.getbootstrap.com: 这些是 Bootstrap 的创建者提供的官方 Bootstrap 主题 和模板,包括仪表板、管理员界面和营销网站。
这里还有一些 Bootstrap 的资源,但还有很多。你可以浏览这些网站,并获取更多关于 Bootstrap 的工作和复杂性的知识:
注意
目前,Bootstrap 4 alpha 版本已经发布。所有 JavaScript 插件都已重写为 ECMAScript6,完全从 LESS 迁移到 SASS,并且已放弃对 IE8 的支持。
这里是官方博客文章:blog.getbootstrap.com/2015/08/19/bootstrap-4-alpha/
第十四章。jQuery – 流行的 JavaScript 库
jQuery 是一个开源的 JavaScript 库。jQuery 使得 JavaScript 编程变得更加简单。
以下是一些 jQuery 基金会的知名企业成员:
-
WordPress: (
wordpress.org/) -
IBM: (
ibm.com/) -
NeoBux: (
www.neobux.com/) -
Mozilla: (
www.mozilla.org/) -
英特尔开源技术中心:(
software.intel.com/en-us/oss) -
Adobe: (
adobe.com/)
你可以在他们的官方网站www.jQuery.com找到有关 jQuery 的所有信息。
JQuery 的演变
jQuery 自第一天起一直在发展。目前有两个主要版本可供下载。1.x 和 2.x 版本有所不同;1.x 版本更稳定,也支持旧版浏览器;而 2.x 版本与 1.x 版本具有相同的 API,但不支持旧版浏览器。
注意
旧版浏览器是指尚未更新到最新版本的较老版本的浏览器。
如果你在一个项目中使用 jQuery,你可以获取一个占用资源更少且加载速度更快的版本。
开始使用
要开始开发 jQuery,你可以通过访问jquery.com/下载 jQuery 软件。在接下来的章节中,我们将介绍一些下载链接。
安装 jQuery
我们可以从jquery.com/download/下载 jQuery。
可以下载的 jQuery 有两个版本:压缩版和未压缩版。
要选择你的选项,请访问前面的链接,右键点击另存为并选择我的电脑下载它。
jQuery 1.x
我们可以从code.jquery.com/jquery-1.11.3.min.js下载压缩版本。
对于开发,我们可以从code.jquery.com/jquery-1.11.3.js下载 1.x 版本。
jQuery 2.x
我们可以从code.jquery.com/jquery-2.1.4.min.js下载压缩版本。
对于开发,我们可以从code.jquery.com/jquery-2.1.4.js下载 2.x 版本。
使用 jQuery
jQuery 是一个非常强大的 JavaScript 库。以下是一些代码示例,可以帮助你在下一个项目中快速入门。
如果你已经将 jQuery 库下载到你的硬盘上,并计划从那里使用它,那么你可以在你的 HTML <head>标签中包含以下代码:
<script src="img/jquery.min.js"></script>
在这里,js是项目根目录中的一个文件夹。
小贴士
为了避免较长的加载时间和性能问题,脚本应该添加到 <body> 标签的末尾,因为当浏览器加载网页(比如说,sample1.html)并且脚本位于 body 标签的末尾时,浏览器可以渲染页面的内容(body),然后才开始加载脚本。
jQuery 语法用于对 HTML 元素执行任何特定操作。
<script src="img/jquery.min.js">
</script>
一个点/句号后跟类名作为参数传递。
选择器
$(selector).action()
这里是描述:
-
$:$用于访问 jQuery 对象。 -
(selector): 使用熟悉的 CSS 样式选择器语法查询(或查找)HTML 元素。例如,你可以通过元素名称、类型、类或 ID 来选择。 -
基本语法如下:
这通过类名选择元素。
jQuery action(): 例如,它可以是指点击、按键、聚焦等事件。
选择器以 $ 符号开头,后跟括号:$()
元素选择器
元素选择器通过名称选择元素。例如,如果一个段落被写为 <p> 标签,你可以通过其名称选择这个段落,即 p:
$("p")
参数
返回
ID 选择器通过 ID 选择元素。HTML 的每个元素都可以有自己的标识 ID,并且可以使用 # 访问。例如,要访问 ID 为 text 的元素,我们可以使用以下语法:
元素选择器返回元素。
返回
要选择的元素名称作为参数传递。
ID 选择器
这通过 ID 选择元素。ID 通常用于通过 JavaScript 中的井号或哈希符号唯一标识通过 DOM 访问的元素。
$("#text")
元素选择器通过名称选择元素。例如,如果一个段落被写为 <p> 标签,你可以通过其名称选择这个段落。
数字符号(或井号)后跟 ID 名称作为参数传递。
另一种首选的方法是使用 Google 托管库;这些库比使用你自己的托管 jQuery 库提供了更快的页面渲染和 jQuery 代码。你可以使用以下代码片段使用 Google 开发者托管库:
这将使用作为参数传递的 ID 返回元素。
描述
如其名所示,selector 属性用于选择 HTML 的各种元素。selector 属性基本上支持 CSS 选择器。
类选择器
这将使用作为参数传递的Class名称返回元素。
$(".sample")
参数
参数
类选择器通过类名选择元素。例如,一个名为 sample 的类可以通过以下语法访问:
描述
描述
参数
事件
jQuery 使得当用户与网页交互时更容易做出响应。例如,当他们在某处点击、滚动文档、悬停在字段上或类似操作时,我们可以执行多个任务。每当用户与网页交互时,都会发生一个事件。我们可以使用事件处理来执行我们的代码。
鼠标事件
这些是在用户激活与鼠标相关的任何函数时立即实例化的事件。在接下来的章节中,我们将介绍每个鼠标事件的描述。
.click()
点击事件接收一个 DOM 对象,并在用户点击时调用该函数。
参数
点击事件接收一个回调函数。
返回值
这将返回在点击时调用的函数生成的响应。
描述
点击事件使用 ID 获取用户点击的位置,并相应地调用在 body 内部定义的相应函数。
这里是它用法的一个例子。
HTML 代码:
<div id="clicked">
//function to be called after clicked
</div>
jQuery 代码:
$( "#clicked" ).click(function() {
alert( "Function for .click() called." );
});
.dblclick()
我们可以使用.dblclick() jQuery 方法将处理程序附加到 HTML 元素的双击事件。
参数
dbclick事件接收一个回调函数。
返回值
这将返回在双击时调用的函数生成的响应。
描述
dblclick事件使用 ID 获取用户双击的位置,并相应地调用其相应的函数。
这里是它用法的一个例子。
HTML 代码:
<div id="clicked">
// function to be called after clicked
</div>
jQuery 代码:
$( "#clicked" ).dblclick(function() {
alert( "Function for .dblclick() called." );
});
.hover()
hover事件使用 ID 获取用户鼠标所在的位置,并相应地调用其相应的函数。
参数
hover事件接收一个回调函数。
返回值
这将返回在悬停时调用的函数生成的响应。
描述
hover事件使用 ID 获取用户鼠标所在的位置,并相应地调用其相应的函数。
这里是它用法的一个例子。
HTML 代码:
<ul>
<li>Lahore</li>
<li>Karachi</li>
<li>Peshawar</li>
<li>Sialkot</li>
</ul>
jQuery 代码:
$( "li" ).hover(
function() {
$( this ).append( $( "<span> (*)</span>" ) ); // "this" is used to access the current object itself
}, function() {
$( this ).find( "span:first" ).remove();
}
);
.mousedown()
当用户左键点击鼠标并突出显示特定文本时,.mousedown事件被激活。
参数
当元素被点击时执行的.mousedown()函数。
返回值
这将返回在点击时调用的函数生成的响应。
描述
当用户左键点击并突出显示一些特定文本时,此事件被激活。
这里是它用法的一个例子。
HTML 代码:
<div id="myTarget">
Click here
</div>
jQuery 代码:
$( "#myTarget" ).mousedown(function() {
alert( "Function for .mousedown() called." );
});
.mouseenter()
当鼠标悬停在所选文本上时,此事件被激活,并相应地调用一个函数。
参数
mouseenter事件接收一个回调函数。
返回值
这将返回在鼠标进入时调用的函数生成的响应。
描述
当鼠标悬停在所选文本上时,此事件被激活,并相应地调用一个函数。与mouseenter()相关的事件只触发一次,所以即使你将光标悬停在元素上,通过此函数分配的函数也只执行一次。
这里是它用法的一个例子。
HTML 代码:
<div id="external">
External
<div id="internal">
Internal
</div>
</div>
<div id="myLog"></div>
jQuery 代码:
$( "#external" ).mouseenter(function() {
$( "#myLog" ).append( "<p>Function for .mouseenter() called.</p>" );
});
.mouseleave()
当光标从 HTML 元素移开时,会激活 .mouseleave 事件。
参数
mouseleave 事件接收一个回调函数。
返回值
这返回了在点击时调用的函数生成的响应。
描述
当鼠标离开时,会激活此事件。函数会相应地被调用。
这里是它使用的一个示例。
HTML 代码:
<div id="external">
External
<div id="internal">
Internal
</div>
</div>
<div id="myLog"></div>
jQuery 代码:
$( "#external" ).mouseleave(function() {
$( "#myLog" ).append( "<p> Function for .mouseleave() called.</p>" );
});
.mousemove()
当鼠标在元素内部移动时,会触发 .mousemove 事件。
参数
mousemove 事件接收一个回调函数。
返回值
这返回了在鼠标移动时调用的函数生成的响应。
描述
当鼠标在元素内部移动时,会触发此事件。
这里是它使用的一个示例。
HTML 代码:
<div id="myTarget">
Move here
</div>
<div id="other">
Trigger the Function
</div>
<div id="myLog"></div>
jQuery 代码:
$( "#myTarget" ).mousemove(function( event ) {
// the event keyword identifies the mousemove event in the case of this example
var msg = "Function for .mousemove() called at ";
msg += event.pageX + ", " + event.pageY;
$( "#myLog" ).append( "<div>" + msg + "</div>" );
});
.mouseout()
当鼠标指针离开元素的边界时,会触发 .mouseout 事件。任何 HTML 元素都可以绑定到此事件。
参数
mouseout 事件接收一个回调函数。
返回值
这返回了在鼠标移出目标元素时调用的函数生成的响应。
描述
当鼠标指针离开元素时,会触发 mouseout 事件。
这里是它使用的一个示例。
必需的 HTML 代码:
<div id="external">
External
<div id="internal">
Internal
</div>
</div>
<div id="other">
Trigger the Function
</div>
<div id="myLog"></div>
必需的 jQuery 代码:
$( "#external" ).mouseout(function() {
$( "#myLog" ).append( "<p>Function for .mouseout() called.</p>" );
});
.toggle()
此 .toggle() 函数用于将多个处理程序绑定到匹配的元素上,这些处理程序在交替点击时执行。
参数
toggle() 函数的参数是 duration、easing 和 callback。
duration 参数是可选的,用于指定隐藏和显示效果的速率。可能的值有快速、慢速和毫秒。默认值为 400 毫秒。
easing 参数是可选的,用于指定用于动画的 easing() 函数。默认值是 string。
callback 参数也是可选的,用于指定在动画完成后要调用的函数。
返回值
这返回了被调用的函数的输出。
描述
此函数用于检查元素的可见性,然后交替使用 hide() 和 show() 方法。回调总是在动画完成后被触发,并且对于找到匹配的元素只触发一次。
这里是它使用的一个示例。
必需的 HTML 代码:
<ul>
<li>Mercury</li>
<li>Venus</li>
<li>Earth</li>
<li>Mars</li>
</ul>
必需的 jQuery 代码:
$(document).ready(function() {
$("ul").click(function() {
$("li").toggle("slow", function() {
});
});
});
键盘事件
键盘事件在 Keyboard 函数上触发,例如,当按钮/键被按下或释放时,等等。键盘事件可以通过以下内置 jQuery 函数进行控制。可用的函数有 KeyDown、KeyPress 和 KeyUp。
KeyDown 和 KeyPress 之间的唯一实际区别是 KeyPress 传递由 KeyPress 事件产生的字符,并且只有当存在一个时才会被调用。
例如,如果你在键盘上按下 A 键,你会得到以下事件序列:
-
KeyDown:KeyCode=Keys.A,KeyData=Keys.A,Modifiers=Keys.None -
KeyPress:KeyChar='a' -
KeyUp:KeyCode=Keys.A
.keydown()
当用户按下键时,会实例化keydown事件。
参数
keydown事件将按下的键作为参数发送。
返回值
这返回了按键按下时调用的函数的输出。
描述
当用户按下键时,会实例化keydown事件,这会调用要执行的功能。
这里是它用法的一个示例。
必需的 HTML 代码:
<form>
<input id="myTarget" type="text" value="KeyPress">
</form>
必需的 jQuery 代码:
$( "#myTarget" ).keydown(function() {
alert( "Function for .keydown() called." );
});
之前的示例代码选择了具有myTarget ID 的div元素,并在按下键时触发警报函数。
.keypress()
当用户按下键时,会实例化keypress事件。
参数
这会将按下的键作为参数发送。
返回值
这返回了由按键触发的函数的输出。
描述
当用户按下键时,会实例化keypress事件,这会调用要执行的功能。
这里是它用法的一个示例。
必需的 HTML 代码:
<form>
<fieldset>
<input id="myTarget" type="text" value="Tomato">
</fieldset>
</form>
必需的 jQuery 代码:
$( "#myTarget" ).keypress(function() {
console.myLog( "Function for .keypress() called." );
});
之前的示例代码选择了具有myTarget ID 的div元素,并在按下键时触发警报函数。
.keyup()
当用户释放按下的键时,会发生keyup事件。
参数
这会将按下的键作为参数发送。
返回值
这返回了释放键时调用的函数的输出。
描述
当用户释放按下的键时,会发生此事件。
这里是它用法的一个示例。
必需的 HTML 代码:
<form>
<input id="myTarget" type="text" value="Hello there">
</form>
必需的 jQuery 代码:
$( "#myTarget" ).keyup(function() {
alert( "Function for .keyup() called." );
});
之前的示例代码选择了具有myTarget ID 的div元素,并在释放键时触发警报函数。
表单事件
表单事件是在表单内的元素绑定到 jQuery 时发生的。当需要处理通过表单输入的数据时,这些事件非常有用。这些事件可以用在<form>标签内的元素上。现在我们将介绍每个表单事件的描述。
submit()
如其名所示,当表单提交时,会触发submit事件。
其语法是$(selector).submit(function)。
参数
传入的参数是表单提交后要运行的功能。
返回值
此事件不返回任何内容。
描述
submit()函数是一个表单事件。它用于将函数绑定到表单元素,每当表单提交时都需要调用该函数。
必需的 HTML 代码:
<form action="">
User ID: <input type="text" name="UsrID" value="KA112"><br>
Password: <input type="password" name="password" value="Password"><br>
<input type="submit" value="Submit">
</form>
必需的 JQuery 代码:
$(document).ready(function() {
$("form").submit(function() {
alert("Form Submitted!");
});
});
.change()
当表单中的元素值更改时,会触发change事件。
其语法是$(selector).change(function)。
参数
传入的参数是当所选元素的值更改时要运行的功能。
返回值
此事件不返回任何内容。
描述
此事件用于将事件绑定到需要在表单元素中的值更改时调用的函数。此函数仅适用于<input>、<textarea>和<select>元素。
必需的 HTML 代码:
<select name="ShadesOfGreen">
<option value="Jade">Jade</option>
<option value="Mint">Mint</option>
<option value="Emerald">Emerald</option>
<option value="Moss">Moss</option>
</select>
必需的 JQuery 代码:
$(document).ready(function() {
$("select").change(function() {
alert("Option Changed");
});
});
blur()
当表单中的元素失去焦点并且用户移动到表单中的下一个元素时,会触发 blur 事件。
其语法是 $(selector).blur(function)。
参数
传入的参数是当元素失去焦点时运行的函数。
返回值
此事件不返回任何内容。
描述
使用 blur 事件在元素失去焦点时调用函数。
必须的 HTML 代码:
User ID: <input type="text">
Gender: <select name="Gender">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
必须的 JQuery 代码:
$(document).ready(function() {
$("input").blur(function() {
alert("User ID lost foucs");
});
});
focus()
当表单中的元素获得焦点时,会触发 focus 事件。
其语法是 $(selector).focus(function)。
参数
传入的参数是当元素获得焦点时运行的函数。
返回值
此事件不返回任何内容。
描述
使用 focus 事件在元素获得焦点时调用函数。一个元素通常在用鼠标选择它或使用 Tab 键导航到它时处于 焦点状态。此事件仅在指定的元素处于焦点时触发,而不是元素的子元素。
通常与 blur 事件一起使用 focus 事件。
必须的 HTML 代码:
User ID: <input type="text" name="UsrID"><br>
Email ID: <input type="text" name="emailID">
必须的 JQuery 代码:
$(document).ready(function() {
$("input").focus(function() {
$(this).css("background-color", "#cccccc");
});
$("input").blur(function() {
$(this).css("background-color", "#ffffff");
});
});
focusin()
当元素或其子元素获得焦点时,会触发此事件。
其语法是 $(selector).focusin(function)。
参数
传入的参数是当元素获得焦点时运行的函数。
返回值
此事件不返回任何内容。
描述
当元素或其子元素获得焦点时,会触发 focusin 事件。此事件也会在子元素获得焦点时被调用。
必须的 HTML 代码:
<div>
Name: <input type="text" name="fullname"><br>
Email: <input type="text" name="email">
</div>
必须的 JQuery 代码:
$(document).ready(function() {
$("div").focusin(function() {
$(this).css("background-color", "#cccccc");
});
});
focusout()
当元素或其子元素失去焦点时,会触发 focusout 事件。
其语法是 $(selector).focusout(function)。
参数
传入的参数是当元素获得焦点时运行的函数。
返回值
此事件不返回任何内容。
描述
当元素或其子元素失去焦点时,会触发此事件。此事件通常与 focusin 事件一起使用。
必须的 HTML 代码:
<div>
Name: <input type="text" name="fullname"><br>
Email: <input type="text" name="email">
</div>
必须的 JQuery 代码:
$(document).ready(function() {
$("div").focusin(function() {
$(this).css("background-color", "#cccccc");
});
$("div").focusout(function() {
$(this).css("background-color", "#ffffff");
});
});
文档事件
文档事件通常在文档加载时触发。在接下来的章节中,我们将介绍每个文档事件的描述。
resize()
当用户调整窗口大小时,会触发 resize 事件。其语法如下:
$(selector).resize(function)
参数
传入的参数是当窗口大小调整后要运行的函数。
返回值
此事件不返回任何内容。
描述
使用 resize 事件在用户调整窗口大小时调用函数。
必须的 HTML 代码:
<p></p>
必须的 JQuery 代码:
$(document).ready(function() {
$(window).resize(function() {
$("p").text("Window resized!!");
});
});
scroll()
当用户在(可滚动的)元素中滚动时,会触发 scroll 事件。我们可以使用此事件将其绑定到函数。其语法如下:
$(selector).scroll(function)
参数
传入的参数是当用户在元素上滚动时运行的函数。
返回值
此事件不返回任何内容。
描述
当用户在元素中滚动时,会触发 scroll 事件。
必须的 HTML 代码:
<div style="border:1px solid black;width:200px;height:100px;overflow:scroll;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vehicula ultrices nulla vel facilisis. Curabitur elementum lorem non massa porttitor accumsan. Cras eu leo tincidunt, pulvinar neque et, tempus dolor. Nam condimentum nisl vel quam posuere, vitae malesuada nunc molestie. Aliquam pulvinar diam eu magna sagittis efficitur. Vestibulum tempor, leo accumsan maximus hendrerit, ex nisi rutrum sapien, nec ultricies tellus nisl ac lacus. Phasellus sed ligula augue.
</div>
<p></p>
必须的 jQuery 代码:
$(document).ready(function() {
$("div").scroll(function() {
$("p").text( "Text Scrolled!");
});
});
特效和动画
可以通过不同的设计和颜色,将自定义动画和效果添加到各种元素中,以增强您的界面。
animate()
animate() 函数使用一些内置动画来在视图中动画化对象。
其语法如下:
(selector).animate({styles},speed,easing,callback)
参数
animate 函数接受 duration、easing 和 callback 参数。
duration 参数是可选的,用于指定隐藏和显示效果的速率。其可能的值是快速、慢速和毫秒。默认是 400ms。
easing 参数是可选的,用于指定动画中要使用的缓动函数。默认是 string。
callback 参数也是可选的,用于指定动画完成后要调用的函数。
返回值
动画返回包含所有修改的修改后的对象。
描述
可以通过不同的设计和颜色,将自定义动画和效果添加到各种元素中,以增强您的界面。
stop()
当 stop() 方法应用于所选元素时,它会停止该元素的动画。
其语法为 $(selector).stop(stopAll,goToEnd);
参数
这接受两个默认设置为 false 的布尔值作为参数。
返回值
这不返回任何内容。
描述
此函数在调用时立即停止动画。如果第一个参数设置为 true,则移除该元素的所有其他动画。如果第二个参数设置为 true,则快速完成当前动画。
这里是它的用法示例。
必须的 HTML 代码:
<div id="sample">
<img id="sample" src="img/myImage.png" alt="" width="1" height="2">
</div>
必须的 jQuery 代码:
$( "#sample" ).hover(function() {
$( this ).find( "img" ).stop( true, true ).fadeOut();
}, function() {
$( this ).find( "img" ).stop( true, true ).fadeIn();
});
上述示例代码创建了一个没有常见问题(多个队列动画)的淡入效果。
隐藏、显示和切换
可以设置元素隐藏和显示,其中隐藏使元素从用户眼中消失,显示则相反。
hide()
当 hide() 函数应用于 HTML 元素时,它会将该元素从视图中隐藏。这可以用于根据用户活动生成动态内容。以下是其语法:
$(selector).hide(speed,callback);
参数
这接受速度(毫秒)和回调函数作为参数。作为参数的值如下:
-
快速
-
慢速
-
毫秒数
返回值
这不返回任何内容。
描述
此函数等同于为所选元素设置 CSS 属性 display: none。它还保存原始的显示属性以供将来使用。
这里是它的用法示例。
必须的 HTML 代码:
<div id="sample">
</div>
<img id="myImage" src="img/myImage.jpeg" alt="" width="1" height="2">
必须的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).hide( "slow", function() {
alert( "Animation complete." );
});
});
show()
如果 show() 函数应用于 HTML 元素,则使隐藏的元素可见。这可以用于根据用户活动控制和操作动态内容,例如,在选中某个复选框后使某些表单选项可见。以下是其语法:
$(selector).show(speed,callback);
参数
这接受速度(毫秒)和回调函数作为参数。作为参数的值如下:
-
快速
-
慢速
-
时间(以毫秒为单位)
返回值
这个函数不返回任何内容。
描述
这个函数会移除元素的 display:none 属性并将其恢复到原始状态。例如,如果一个元素具有 display:inline-block 属性并且被 hide 函数隐藏,它将把显示属性恢复到 inline-block。
这里是它使用的一个示例。
必需的 HTML 代码:
<div id="sample">
</div>
<img id="myImage" src="img/myImage.jpeg" alt="" width="1" height="2">
必需的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).Show( "slow", function() {
alert( "Animation complete." );
});
});
toggle()
如果将 toggle() 函数应用于 HTML 元素,它将切换该元素的可见性:
$(selector).toggle(speed,callback);
参数
这个函数接受速度(以毫秒为单位)和回调函数作为参数。参数值如下:
-
快速 -
慢速 -
时间(以毫秒为单位)
返回值
这个函数不返回任何内容。
描述
这个函数用于切换元素的可见性。
小贴士
这个函数不应与之前解释过的鼠标事件函数 toggle() 混淆。为了确保使用的是哪个 toggle() 函数,请检查传递给函数的参数。
这里是它使用的一个示例。
必需的 HTML 代码:
<div id="sample">
</div>
<img id="myImage" src="img/myImage.jpeg" alt="" width="1" height="2">
必需的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).Show( "slow", function() {
alert( "Animation complete." );
});
});
淡出
淡出可以用来设置元素的可见性。
fadeIn()
fadeIn() 函数在功能上类似于 show() 函数,但 fadeIn() 带有漂亮的淡入过渡效果。
它的语法是 $(selector).fadeIn(speed,callback);。
参数
这接受速度(以毫秒为单位)和回调函数作为参数。参数值如下:
-
快速 -
慢速 -
时间(以毫秒为单位)
返回值
这个函数不返回任何内容。
描述
它与 show() 函数类似,但带有淡入淡出过渡效果。
这里是它使用的一个示例。
必需的 HTML 代码:
<div id="sample">
Click here
</div>
<img id="myImage" src="img/myImage.png" alt="" width="1" height="2">
必需的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).fadeIn( "slow", function() {
// Animation complete
});
});
前面的示例代码选择了具有 sample ID 的 div 元素,并以慢速动画淡入具有 myImage ID 的图像。
fadeOut()
fadeOut() 函数在功能上类似于 hide() 函数,但它带有漂亮的淡出过渡效果。
它的语法如下:$(selector).fadeOut(speed,callback);
参数
这接受速度(以毫秒为单位)和回调函数作为参数。参数值如下:
-
快速 -
慢速 -
时间(以毫秒为单位)
返回值
这个函数不返回任何内容。
描述
fadeOut() 函数与 hide() 函数在功能上类似,但带有淡入淡出过渡效果。
这里是它使用的一个示例。
必需的 HTML 代码:
<div id="sample">
Click here
</div>
<img id="myImage" src="img/myImage.png" alt="" width="1" height="2">
必需的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).fadeOut( "fast", function() {
// Animation complete
});
});
fadeToggle()
fadeToggle() 函数会自动切换元素的显示属性从 none 到 block、inline 等等。
这里是它语法的示例:
$(selector).fadeToggle(speed,callback);
参数
这接受速度(以毫秒为单位)和回调函数作为参数。参数值如下:
-
快速 -
慢速 -
时间(以毫秒为单位)
返回值
这个函数不返回任何内容。
描述
如果一个元素已经隐藏,fadeToggle() 将使其可见,反之亦然。
这里是它使用的一个示例。
必需的 HTML 代码:
<div id="sample">
Click here
</div>
<img id="myImage" src="img/myImage.png" alt="" width="1" height="2">
必需的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).fadeToggle( 2000, function() {
// Animation complete
});
});
fadeTo()
fadeTo() 函数将目标元素的透明度调整到给定的值。
它的语法如下:
$(selector).fadeTo( duration, opacity [, complete ] )
$(selector).fadeTo( duration, opacity [, easing ] [, complete ] )
参数
这以毫秒为单位的持续时间作为参数。作为参数接受的值如下:
-
Fast -
Slow -
时间(毫秒)
另一个参数是目标元素的透明度。值介于 0 和 1 之间,最后一个参数是回调函数。
返回值
这不会返回任何内容。
描述
fadeTo() 函数与 fadeIn() 方法类似。但用户可以在此处指定目标透明度。例如,将元素设置为 50% 透明度,可以将透明度设置为 0.5。
必须的 HTML 代码:
<div id="sample">
Click here
</div>
<img id="myImage" src="img/myImage.png" alt="" width="1" height="2">
必须的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).fadeTo( "Fast", 0.5, function() {
// Animation complete
});
});
滑动
滑动方法用于在向上或向下方向滑动元素。slideDown() 函数将使元素可见,而 slideUp() 函数将隐藏元素的内部内容。
slideDown()
slideDown() 函数以指定的速度滑动选定的元素。
这里是它的语法示例:
$(selector).slideDown(speed,callback);
参数
这需要以毫秒为单位的速度和回调函数作为参数。作为参数接受的值如下:
-
Fast -
Slow -
时间(毫秒)
返回值
这不会返回任何内容。
描述
slideDown() 函数以平滑的滑动效果使隐藏的元素可见。
这里是它用法的一个示例。
必须的 HTML 代码:
<div id="sample">
Click here
</div>
<img id="myImage" src="img/myImage.png" alt="" width="1" height="2">
必须的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).slideDown( "slow", function() {
// Animation complete.
});
});
slideUp()
slideUp() 函数以指定的速度向上滑动(隐藏)选定的元素。
这里是它的语法示例:
$(selector).slideUp(speed,callback);
参数
以毫秒为单位的速度和回调函数作为参数。作为参数接受的值如下:
-
Fast -
Slow -
时间(毫秒)
返回值
这不会返回任何内容。
描述
此函数以向上的滑动效果隐藏选定的元素。
这里是它用法的一个示例。
必须的 HTML 代码:
<div id="sample">
Click here
</div>
<img id="myImage" src="img/myImage.png" alt="" width="1" height="2">
必须的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).slideUp( "fast", function() {
// Animation complete.
});
});
slideToggle()
slideToggle() 函数在选定的元素之间切换 slideUp() 和 slideDown(),并指定速度。
这里是它的语法示例:
$(selector).slideToggle(speed,callback);
参数
这以毫秒为单位的速度和回调函数作为参数。作为参数接受的值如下:
-
Fast -
Slow -
时间(毫秒)
返回值
这不会返回任何内容。
描述
正如 fadeToggle() 在两种状态之间切换过渡一样,slideToggle() 可以滑动元素向上或向下。
这里是它用法的一个示例。
必须的 HTML 代码:
<div id="sample">
Click here
</div>
<img id="myImage" src="img/myImage.png" alt="" width="1" height="2">
必须的 jQuery 代码:
$( "#sample" ).click(function() {
$( "#myImage" ).slideToggle( "fast", function() {
// Animation complete.
});
});
回调
多行语句是排队而不是同时执行。回调函数排队语句并逐个执行。
它的语法如下:
var callbacks = $.Callbacks();
创建的对象可以用来添加、删除、实例化和禁用回调。支持的函数有 callbacks.add()、callbacks.remove()、callbacks.fire() 和 callbacks.disable()。
callbacks.add()
此函数用于添加稍后要调用的数组中的所有函数。
参数
这以字符串形式作为其参数的标志。
返回值
此方法返回与它关联的回调对象(this)。
描述
callbacks.add() 函数将函数添加到回调数组中。
这里是其使用的一个示例。
必要的 jQuery 代码:
function myFunc1( value ) {
console.myLog( value );
}
function myFunc2( value ) {
console.myLog( "myFunc2 says: " + value );
return false;
}
var callbacks = $.Callbacks();
callbacks.add( myFunc1 );
// Outputs: meow!
callbacks.fire( "meow!" );
callbacks.add( myFunc2 );
// Outputs: woof!, myFunc2 says: woof!
callbacks.fire( "woof!" );
callbacks.fire()
callbacks.fire() 函数使用已传递的任何参数调用列表中的回调函数。
参数
这传递一个参数列表,将其传递回回调列表。
返回值
这返回附加到其上的回调对象。
描述
callbacks.fire() 函数用于使用参数调用列表中的回调函数。前一个示例可以参考。
callbacks.remove()
callbacks.remove() 函数用于从数组中删除一个函数。
参数
这以字符串形式作为其参数的标志。
返回值
这返回附加到其上的回调对象。
描述
这从回调数组中删除函数。前一个示例可以参考。
callbacks.disable()
callbacks.disable() 函数用于禁用数组中下一个函数的调用。
参数
这不接收任何参数。
返回值
这返回附加到其上的回调对象。
描述
使用 callbacks.disable() 函数防止执行数组中的下一个函数:
var sound = function( value ) {
console.log( value );
};
var callbacks = $.Callbacks();
// Add the above function to the list
callbacks.add( sound );
// Fire the items on the list
callbacks.fire( "Woof!" );
// Disable further calls being possible
callbacks.disable();
callbacks.fire( "Meow" );
链式操作
可以通过将它们链接到同一元素上执行不同数量的语句。每个语句将依次执行。
从每个链式操作返回的值是一个新的 jQuery 对象。链式操作可以通过将一个操作附加到前一个操作来完成;例如:
$("#p1").css("color", "blue").slideDown(100).slideUp(35);
在这里,slideUp() 和 slideDown() 操作依次执行。
jQuery 和文档对象模型
DOM 定义了访问 HTML 和 XML 文档的标准:
"W3C 文档对象模型 (DOM) 是一个平台和语言中立的接口,允许程序和脚本动态访问和更新文档的内容、结构和样式。"
以下是一些 jQuery 中 DOM 操作的方法:
-
text(): 这用于设置或返回所选元素的文字内容 -
html(): 这用于设置或返回所选元素的内容 -
val(): 这用于设置或返回表单字段的值
jQuery 遍历
您可以按元素组合的顺序遍历元素。所有元素大多以树的形式组合,我们可以从根开始遍历它们。
注意
元素本身并不是组合的,但它们在文档对象中被结构化或建模。
让我们看看以下图片:

让我们看看以下描述:
-
<div>元素是<ul>的父元素,也是其内部所有内容的祖先元素 -
<ul>元素是<li>元素的父元素,也是<div>的子元素 -
左侧
<li>元素是<span>的父元素,是<ul>的子元素,也是<div>的后代。 -
<span>元素是左侧<li>的子元素,也是<ul>和<div>的后代。 -
两个
<li>元素是兄弟元素(它们具有相同的父元素) -
右侧
<li>元素是<b>的父元素,是<ul>的子元素,也是<div>的后代。 -
<b>元素是右侧<li>的子元素,也是<ul>和<div>的后代。
祖先
祖先是父元素!
在接下来的几节中,我们将介绍三个有用的 jQuery 方法,用于在 DOM 树中向上遍历。
parent()
parent() 函数返回选定元素的父元素。
参数
此函数不接收任何参数,但作为 jQuery 对象的函数被调用。
返回值
此函数返回元素的父元素。
描述
此函数返回选定元素的父元素:
$(document).ready(function() {
$("span").parent();
});
parents():
parents(): 函数返回选定元素到根元素的所有父元素数组。
参数
此函数不接收任何参数,但作为 jQuery 对象的函数被调用。
返回值
此函数返回一个元素的所有父元素。
描述
parents(): 函数返回选定元素到根元素的所有父元素数组:
$(document).ready(function() {
$("span").parents();
});
parentsUntil():
$(selector).parentsUntil(stop,filter);
parentsUntil() 方法返回 selector 和 stop 元素之间的所有祖先元素。
祖先元素是父元素、祖父元素、曾祖父元素等。
参数
停止是一个可选参数,表示搜索匹配祖先元素的停止位置。过滤器是一个可选参数,通常是一个表达式,用于在选择器和停止之间缩小搜索范围。
返回值
此函数返回两个选定元素之间的所有父元素。
描述
此函数返回两个选定元素之间的父元素:
$(document).ready(function() {
$("span").parentsUntil("div");
});
后代
父元素的子元素称为其后代。
在接下来的几节中,我们将介绍两个有用的 jQuery 方法,用于在 DOM 树中向下遍历。
children()
children() 函数返回选定元素的所有子元素。
参数
此函数不接收任何参数,但作为 jQuery 对象的函数被调用。
返回值
此函数返回目标元素的所有子元素数组。
描述
此函数返回选定元素的所有子元素:
$(document).ready(function(){
$("div").children();
});
find()
find() 函数返回一个数组,直到没有子元素的子元素,这通常被称为 叶。
参数
find() 函数接受 HTML 元素作为参数。
返回值
此函数返回目标元素的所有子元素。
描述
此函数返回一个数组,直到树中的叶元素:
$(document).ready(function() {
$("div").find("span");
});
兄弟元素
兄弟元素是具有相同父元素的元素。
在 DOM 树中横向遍历有许多有用的 jQuery 方法,我们在这里进行介绍。
siblings()
$(selector).siblings(filter);
siblings() 函数返回选定元素的所有兄弟元素。
参数
过滤器是一个可选参数,通常是一个表达式,用于在所有兄弟元素中缩小搜索范围。
返回值
此函数返回元素的所有兄弟元素。
描述
此函数使用 filter 参数返回所选元素的所有兄弟元素:
$(document).ready(function() {
$("span").siblings("div");
});
next()
$(selector).next(filter);
过滤是一个可选参数,通常是一个表达式,用于缩小搜索下一个兄弟元素的范围。
参数
此函数不接收任何参数,但作为 jQuery 对象的函数被调用。
返回
这返回元素的下一个兄弟元素。
描述
此函数使用 filter 参数返回所选元素的下一个兄弟元素:
$(document).ready(function(){
$("span").next();
});
nextAll()
$(selector).nextAll(filter);
nextAll() 函数返回所选元素的下一个兄弟元素的数组。
参数
过滤是一个可选参数,通常是一个表达式,用于缩小搜索所有下一个兄弟元素的范围。
返回
这返回一个包含目标元素所有下一个兄弟元素的数组。
描述
此函数返回所选元素的下一个兄弟元素的数组,并使用参数:
$(document).ready(function() {
$("span").nextAll();
});
nextUntil()
$(selector).nextUntil(stop, filter);
nextUntil() 函数返回一个数组,包含所选元素在两个指定元素之间的下一个兄弟元素。
参数
停止一个可选参数,表示搜索下一个匹配兄弟元素的停止位置。
过滤一个可选参数通常是一个表达式,用于缩小在选择器和停止之间的兄弟元素的搜索范围。
返回
这返回元素的 所有下一个兄弟元素。
描述
此函数返回两个元素之间的所选元素的下一个兄弟元素的数组:
$(document).ready(function() {
$("span").nextUntil('H4');
});
prev()
$(selector).prev(filter);
prev() 函数返回所选元素的先前兄弟元素。
参数
过滤是一个可选参数,通常是一个表达式,用于缩小搜索前一个兄弟元素的范围。
返回
prev() 函数返回元素的先前兄弟元素。
描述
此函数使用 filter 参数返回所选元素的前一个兄弟元素的数组:
$(document).ready(function() {
$("span").prev();
});
prevAll()
$(selector).prevAll(filter);
prevAll() 函数返回所选元素的前一个兄弟元素的数组。
参数
过滤是一个可选参数,通常是一个表达式,用于缩小搜索所有前一个兄弟元素的范围。
返回
prevAll() 函数返回元素的所有前一个兄弟元素的数组。
描述
此函数使用参数返回所选元素的前一个兄弟元素的数组:
$(document).ready(function() {
$("span").prevAll();
});
prevUntil()
prevUntil() 函数返回一个数组,包含所选元素在两个元素之间的前一个兄弟元素。
参数
这限制了搜索兄弟元素的范围。
返回
这返回元素的 所有前一个兄弟元素的数组。
描述
此函数返回所选元素的前一个兄弟元素的数组,并使用参数:
$(document).ready(function() {
$("span").prevUntil("Div");
});
过滤
过滤方法用于根据其位置定位特定元素。
first()
first() 函数输出所选元素的第一个元素。
参数
first() 函数将所选元素作为参数。
返回
这返回一个 jQuery 对象,存储对匹配提供的选择器字符串的项的数组中第一个项的引用。
描述
这个函数输出所选元素中的第一个元素。以下示例输出 <div> 标签内的第一个 H1 标题:
$(document).ready(function() {
$("div H1").first();
});
最后()
这个函数返回所选元素中的最后一个元素。
参数
last() 函数接受所选元素作为参数。
返回值
这返回一个 jQuery 对象,该对象存储对匹配提供的选择器字符串的项数组中最后一个项的引用。
描述
这个函数输出所选元素中的最后一个元素。以下示例输出 <div> 标签内的最后一个 H1 标题:
$(document).ready(function() {
$("div H1").last();
});
eq()
eq() 函数返回对应索引号指定的元素,前提是我们从 0 开始编号。因此,第一个元素将具有索引号 0,第二个元素将具有索引号 1,依此类推。
参数
eq() 函数接受所选元素和索引号作为参数。
返回值
这返回指定索引号处的元素。
描述
这个函数返回对应索引号指定的元素。以下示例返回第五个 div 元素:
$(document).ready(function() {
$("div").eq(4);
});
过滤()
filter() 函数用于获取满足特定条件的元素列表。所有满足指定条件的元素都将被返回。
参数
在这里,接受的参数是搜索的元素和该元素必须满足的条件。
返回值
这返回满足指定条件的元素列表。
描述
filter() 函数用于搜索并获取满足指定条件的元素列表。在以下示例中,我们将搜索并获取所有具有名为 Feedback 的类的 <div> 元素列表:
$(document).ready(function() {
$("div").filter(".Feedback");
});
注意
not() 方法是 filter() 方法的逆操作。如果你想找到不满足所述条件的元素,可以使用 not()。
在 jQuery 中使用 AJAX
异步 JavaScript 和 XML (AJAX) 是 单页应用程序 (SPA) 的基础构建块。这种方法用于在不重新加载整个页面的情况下更新网页的内容。这种方法有助于节省宝贵的资源,并且可以显著减少页面加载时间,因为只有页面的部分被重新加载,而不是整个页面。
更多的时候,你访问谷歌搜索页面来寻找你问题的答案。你有没有注意到当你在搜索框中输入时,页面是如何显示结果并提供相关搜索的有用建议?或者亚马逊和 eBay 网站上的产品过滤器。这些效果都是通过 AJAX 实现的。
jQuery Ajax 加载
load() 方法从服务器加载数据并将返回的数据放入所选元素中。
其语法如下:
$(selector).load(URL,data,callback);
参数
load() 方法接受 URL、data 和 callback 作为参数。
callback 参数可以有以下参数:
-
responseTxt:此参数包含成功时的结果内容 -
statusTxt:此参数包含请求的状态,即success、notmodified、error、timeout、parsererror -
xhr:此参数包含XMLHttpRequest对象
返回
从 URL 获取的数据放置在选定的元素中。
描述
load() 方法从服务器加载数据并将返回的数据放入选定的元素中。以下示例将 Sample.txt 文件加载到指定的 <div> 标签中:
$("#div1").load("Sample.txt" , function(responseTxt, statusTxt, xhr);
jQuery Ajax Get
Get 请求通过 HTTP GET 请求从服务器获取数据:
GET:此请求从指定的资源请求数据
其语法如下:
$.get(URL,callback);
参数
这接受 URL 和回调作为参数。在这里,callback 参数是可选的。
返回
Get 请求返回从 URL 获取的数据。
描述
Get 请求通过 HTTP GET 请求从服务器获取数据:
$.get("Sample.html", myfunction(data)
所需的 HTML 文件如下:
<p> This is the data from the Sample.html file</p>
上述代码将从 html 文件中获取数据,并在触发时,行 这是从 Sample.html 获取的数据 将在警告框中显示。
jQuery Ajax Post
Post 请求通过 HTTP POST 请求从服务器获取数据:
POST:此请求从指定的资源请求数据
其语法如下:
$.post(URL, data, callback);
参数
这接受 URL、data 和 callback 作为参数。在这里,data 和 callback 参数是可选的。
返回
这返回从 URL 获取的数据。
描述
这通过 HTTP POST 请求从服务器获取数据:
$.post("Sample.html", myfunction(data)
所需的 HTML 文件如下:
<p> This is the data from the Sample.html file</p>
上述代码将从 HTML 文件中获取数据,并在触发时,这是从 Sample.html 获取的数据 将在警告框中显示。
其他 jQuery 函数
这里有一些更多的 jQuery 函数。
noConflict()
不同的脚本不能同时工作。因此,为了消除冲突,我们使用 noConflict() 函数。
其语法如下:
$.noConflict()
参数
此方法的一个可选参数是 removeAll。此参数用于释放对所有 jQuery 变量的控制。它是一个布尔值。如果存在,则表示必须释放对所有值的控制。
返回
此方法不返回任何内容。
描述
$ 符号被各种 JavaScript 库使用,如果与 jQuery 一起使用可能会引起问题。noConflict() 函数将 $ 符号的控制权交回给其他库。
以下代码展示了当一个事件正在处理时,另一个事件必须等待的情况:
$.noConflict();
jQuery(document).ready(function() {
jQuery("button").click(function() {
jQuery("p").text("jQuery is still working!");
});
});
param()
param() 方法用于创建对象的序列化表示。
其语法如下:
$.param(object)
参数
Object 和 trad 是此函数中使用的参数。Trad 是一个可选参数,在需要传统参数序列化时使用。此参数是可选的。
返回
这将返回对象的序列化表示。
描述
param() 方法用于生成对象或数组的序列化表示形式。这主要用于生成查询字符串。以下示例为学生对象创建了一个查询字符串:
$(document).ready(function() {
StudentObj = new Object();
StudentObj.name = "Kate";
StudentObj.age = 21;
StudentObj.class = "Micro-Processors";
$("button").click(function() {
$("div").text($.param(StudentObj));
});
});
index()
index() 方法用于找出元素的位置。
其语法如下:
$(selector).index()
参数
要查找位置的元素被作为参数。
返回值
此方法返回指定元素的第一次出现的位置,相对于选择器或指定元素。
描述
index() 方法用于获取作为参数传递的元素的位置。搜索该元素的第一种出现,并返回其位置。如果找不到特定元素,则返回 -1。位置编号从 0 开始。
以下示例找到 div 元素的位置,并在警告框中返回其索引:
$(document).ready(myfunction() {
$("div").click(myfunction() {
alert($(this).index());
});
});
each()
each() 函数用于为符合标准的每个元素运行特定函数。
其语法如下:
$(selector).each(function(index,element))
参数
此方法仅接受一个参数,即 function(index, element)。在这里,可以在 index 中指定选择器的位置,并在 element 中指定元素。
返回值
此方法不返回任何内容。
描述
each() 函数为符合标准的每个元素运行指定的函数。在以下示例中,每次遇到 <div> 标签时都会创建一个警告框:
$(document).ready(function() {
$("button").click(function() {
$("div").each(function() {
alert($(this).text())
});
});
});
data()
data() 方法用于从所选元素获取数据。它也用于向所选元素提交数据。
其语法如下:$(selector).data(name)
参数
$(selector).data(name,value);
要将数据附加到元素,传递的参数是名称和值。该名称随后用于检索数据值。
返回值
这将从所选元素返回数据。
描述
data() 函数用于将数据附加到或从元素中。在以下示例中,我们首先将数据附加到 <div> 元素:
$(document).ready(function() {
$("#btnAttach").click(function() {
$("div").data("greetingmsg", "Welcome To Alpha Zoo");
});
$("#btnGetAttached").click(function() {
alert($("div").data("greetingmsg"));
});
});
removeData()
removeData() 方法用于使用 data() 方法从元素中删除之前附加的数据。
其语法为 $(selector).removeData(name)。
参数
要删除的数据的名称被作为参数。
返回值
这不返回任何内容。
描述
如其名所示,removeData() 方法用于删除已设置的数据。以下示例删除了设置在 <div> 标签上的数据:
$("#btnRemoveData").click(function() {
$("div").removeData("greetingmsg");
alert("Message from the site" + $("div").data("greetingmsg"));
});
jQuery 插件
插件用于使用可以在多个项目中使用的各种元素创建应用程序的模块化部分。以下是一个简单的演示:
(function( $ ) {
$.myFunc.showLinkLocation = function() {
this.filter( "a" ).append(function() {
return " (" + this.href + ")";
});
return this;
};
}( jQuery ));
注意
如需更多有关创建自定义插件的支持,您可以访问 learn.jquery.com/plugins/basic-plugin-creation/。
jQuery 社区非常庞大。开发者们制作了一些真正优秀的 jQuery 插件和扩展,你可以在你的项目中使用它们。所有这些项目都是免费提供的;然而,也有一些付费选项。以下是一些优秀的 jQuery 插件:
-
NIVO Slider:这是由Dev7Studios开发的最古老且最受欢迎的图片画廊插件之一。它内置了图片裁剪系统,并附带了许多主题和视觉过渡效果。
-
nanoGALLERY:这是另一个优秀的图片画廊插件,它包含了导航、灯箱、懒加载、缩略图和许多其他功能。它还与 Bootstrap 兼容。
-
MixItUp:这个插件将帮助你为你的作品集和画廊制作 AJAX 过滤器,并带有平滑的动画效果。
-
jQuery Knob:这是一个极具创新性的 jQuery 插件,它使得旋钮可触摸和可点击。即使你不在你的项目中使用它,你也应该一定看看它的实现方式。
-
Tubular:这个插件允许你将 YouTube 视频设置为你的网页背景。
-
Arc Text:这个插件可以将你的文本转换为弧形。你可以使用鼠标推动和拉动文本,使其形成弧形。
jQuery 资源
如果你渴望更多的 jQuery 好东西,请访问这个名为jQuery Rain的网站www.jqueryrain.com。他们有超过 3500 个 jQuery 插件和教程,包括工作演示和示例代码。
第十五章。AngularJS – 谷歌的热门框架
Angular 是一个应用程序框架,它帮助您创建 Web 应用程序。它基于 HTML 和 JavaScript,使动态应用程序的创建更加容易。Angular 扩展了 JavaScript,同时也是一个超集。您可以使用纯 JavaScript 和 Angular 来构建您的应用程序。
这把双刃剑。在积极的一面,构建动态用户界面并保持代码可维护和可测试要容易得多。在另一方面,你必须学习 Angular 应用程序构建的整体概念,即 Angular 的哪个部分在哪里。这与您可能构建的任何其他 JavaScript 应用程序都大不相同。
如果你以前只使用过 jQuery、BackBone 或纯 JavaScript 来构建用户界面,那么 Angular 的许多内容都会显得新颖且不同。
我们将以分层的方式尝试涵盖 Angular。我们将从顶部开始,包括包含其他部分和对象的容器,以及可以在许多对象之间使用的函数,然后讨论测试,因为它是 Angular 构建的核心部分。
让我们不要浪费时间,直接进入正题。
所有示例都假设您已经加载了 Angular,因此 angular 对象是可用的。
注意
如果您不确定如何加载 Angular,请访问官方 Angular 页面 angularjs.org/。
模块(ngApp)
这是所有其他应用程序部分的顶层容器。这里列出的功能比这些更多,但它们将在相关部分中描述。例如,您可以使用 module.controller 创建一个控制器,但此函数将在控制器部分中。
模块
模块是 Angular 应用程序的第一个基本构建块:
angular.module(moduleName, [dependencies], [configFunction])
angular.module(moduleName)
参数
-
moduleName:这是一个字符串,将标识模块。它应该是唯一的。 -
dependencies(可选): 这是一个模块名称数组,该模块依赖于这些模块。 -
configFunction(可选): 这是一个将配置模块的函数。请参阅 config 部分。
返回值
这是一个 Angular 模块对象。
描述
此函数将创建一个新模块或检索一个模块。这取决于我们是否传递了一个依赖项数组。如果没有省略依赖项,则检索一个模块。相反,如果我们包含一个要加载的模块数组(该数组也可以为空),则将创建一个模块。
当你有一组协同工作的对象时,将它们放入一个模块是一个好主意。不要担心创建太多的模块。一个模块应该只有一个且只有一个明确的函数。然后,所有它需要完成该功能的对象都将与其打包在一起。
这里有一些创建模块的示例:
-
这将创建一个新模块:
var firstModule = angular.module('firstModule', []); -
这将检索名为
firstModule的模块:var firstModule = angular.module('firstModule'); -
这创建了一个依赖于
firstModule的模块:var secondModule = angular.module('secondModule', ['firstModule']);
config
这允许您配置提供者:
module.config(configFunction)
参数
configFunction函数是将会被执行的函数。
返回值
这是一个 Angular 模块对象。
描述
这是用于配置提供者的函数。我们将在本章后面介绍提供者,但本节中也有一些示例。这允许在模块实际执行之前创建提供者。
当调用此函数时,提供者将被注入到该函数中。例如,您可以使用 $provide 或 $routeProvider,它们将可用。如果您想使用自定义提供者,它必须在 config 之前创建。自定义对象需要在其名称后附加 provider 以在 config 中可用。
这里有一些使用提供者的示例:
-
这个示例使用了
$provide。提供者将在之后作为firstProvider可用:firstModule.config(function ($provide) { $provide.provider('firstProvider', function () { this.$get = function () { return function () { alert('First!'); } } }); }); -
这个示例首先创建了一个提供者。它在
config中作为firstProvider注入,并在之后使用:firstModule.provider('first', function () { this.$get = function () { return function () { alert('First!'); } } }); firstModule.config(function (firstProvider) { console.log(firstProvider); });
run
这个函数在配置之后执行:
module.run(runFunction)
参数
runFunction函数是将会被执行的函数。
返回值
这是一个 Angular 模块对象。
描述
run() 函数在 config 之后执行。此时,所有模块都将被加载。这是在 config 之后初始化模块后第一个被调用的函数。您在这个函数中做的事情将取决于模块。
这里有一个设置作用域变量的示例。该变量将在模块的后续函数中可用:
firstModule.run(function ($rootScope) {
$rootScope.test = 'test';
});
路由(ngRoute)
ngRoute 模块是一个允许您在应用程序中配置路由的模块。路由正在监听位置的变化,然后自动对新控制器和模板做出响应。它使用 ngView、$routeProvider 和 $route。
注意
您的模块需要依赖于 ngRoute 来使用这些指令和服务。我们还需要在我们的 HTML 中包含 Angular 路由 JavaScript。
ngView
这与 $route 服务一起作为内容的位置:
<ng-view [onload=''] [autoscroll='']/>
<element ng-view [onload=''] [autoscroll='']/>
参数
-
onload(Angular 表达式): 在加载时进行评估。 -
autoscroll(Angular 表达式): 是否使用$anchorScroll与此ngView。默认情况下,它是禁用的。否则,它将评估表达式是否为真。
返回值
这是一个指令。
描述
在路由时,您需要标记应用程序中可以加载动态内容的部分。这就是 ngView 所做的。当匹配到路由时,它将在 ngView 的位置加载新内容。本节末尾将提供一个 ngRoute 的示例。
$routeProvider
这是一个允许您配置路由的提供者:
$routeProvider.when(path, route)
$routeProvider.otherwise(route)
参数
-
path(string): 这是位置将与之匹配的内容。它可以使用冒号(:group)包含命名组,可以包含星号以匹配多个部分(:group*),也可以是可选的(:group?)。 -
route(object): 这个对象告诉 Angular 当路由匹配时应该做什么。该对象可以具有以下属性(非详尽列表):-
controller -
template -
templateUrl -
resolve
-
返回值
这将返回$routeProvider,因此它是可链式的。
描述
这是可以用来配置所有路由的提供者。它可以注入到module.config中。
$route
这是提供匹配路由定义的实际服务。这是一个可以直接注入到控制器中的对象。
属性
-
current(object): 这个对象包含基于匹配的路由的当前变量。这将包括$route、loadedTemplateUrl、locals、params和scope。 -
routes(object): 这包含所有配置的路由。
事件
可以监听这些事件的$route对象:
-
$routeChangeStart: 在实际路由更改之前触发此事件 -
$routeChangeSuccess: 在路由解析后触发此事件 -
$routeChangeError: 如果任何路由承诺被拒绝,则触发此事件
描述
这是一个可以注入到每个控制器中的服务。控制器可以查看属性以获取有关匹配路由的信息。路由匹配将在你的干预下发生,然后你可以在路由加载时更新控制器的作用域。
$routeParams
这是一个将返回已加载路由参数的服务。这只会在你解析了路由后提供参数,因此你可能需要使用$route.current.params。这可以注入到控制器中。
这里是一个使用ngRoute中所有指令和服务的示例。首先,我们有一个 HTML body 标签。这还将包括一个名为main.html的内联模板。这个模板将输出$route和$routeParams对象:
<body ng-app="firstModule">
<div ng-view></div>
<a href="#/main/1">Main</a>
<script type="text/ng-template" id="main.html">
<pre>$routeParams = {{$routeParams}}</pre>
<pre>$route = {{$route}}</pre>
</script>
</body>
这里是执行此操作的脚本。首先是创建模块,然后是配置$routeProvider,最后是为提供者定义一个控制器:
var firstModule = angular.module('firstModule', ['ngRoute']);
firstModule.config(function ($routeProvider) {
$routeProvider.when('/main/:id', {
controller: 'MainController',
templateUrl: 'main.html'
});
});
firstModule.controller('MainController', function ($scope, $route, $routeParams) {
$scope.$route = $route;
$scope.$routeParams = $routeParams;
});
依赖注入
Angular 在所有地方都使用了依赖注入。依赖注入是指一个函数不初始化它需要的依赖项。相反,它们作为参数注入到函数中。例如,当模块需要一个路由提供者时,它会请求一个。模块不关心路由提供者是如何或何时被创建的;它只需要一个引用。
你实际上在 Angular 的每一件事中都使用了注入器。Angular 只是为你做了这件事。我们将查看$injector并了解它是如何工作的,但很可能会不需要使用这些函数。
Angular 中的依赖注入
我们将快速介绍在 Angular 中将对象注入函数的常见方法。以控制器为例,我们将介绍两种最常见的方法。这两种方法都是在 Angular 的背后使用注入:
-
在函数中定义变量:你只需传递需要注入的对象的名称。以下是一个使用
$scope和服务的示例:firstModule.controller('DIController', function ($scope, customService) { //$scope and customService are available here console.log($scope); console.log(customService); }); -
使用数组来列出依赖项:你可以使用数组得到相同的结果。数组的元素将是作为字符串需要的对象。最后,你只需要在数组中有一个函数作为最后一个元素。如果需要,函数甚至可以重命名变量。以下是以数组格式相同的示例:
firstModule.controller('DIController', ['$scope', 'customService', function (newScope, custom) { // newScope and custom are available here console.log(newScope); console.log(custom); }]);
注意
只有数组格式是压缩安全的。一旦源代码被压缩,第一个函数将无法工作。
注入器
使用这个方法来获取一个你可以调用的 Angular 注入器:
angular.injector(modules)
参数
modules(array)数组是你想要加载的模块列表。你必须包含ng。
返回值
这将返回一个注入器对象。参见 $injector 部分。
描述
你可以创建这个对象来使用 Angular 的注入器对象。列出你想要的引用,然后调用你的函数。
以下是一个获取 $http 服务引用的示例:
var injector = angular.injector(['ng']);
var injectTest = function ($http) { console.log($http); };
injector.invoke(injectTest);
$injector
在 Angular 中,你几乎很少需要创建一个注入器。它将为你提供。你可以通过注入或从当前模块中检索来获取注入器的引用。以下两种方法的示例:
-
你可以从模块内的任何元素中获取引用:
var injector = angular.element(document.body).injector(); -
你可以将它注入到一个函数中。以下是一个使用
config的示例:firstModule.config(function ($routeProvider, $injector) { console.log($injector); });
方法
-
annotation: 这将返回一个将要注入的对象数组 -
get(name): 这将返回具有其名称的服务 -
invoke(function): 这将执行函数并注入依赖项 -
has(name): 这允许你确定一个服务是否存在
描述
Angular 会自动为你做这件事,但了解正在发生的事情总是好的。这尤其适用于像 $injector 一样工作的东西。每次函数执行时,Angular 都会从注入器中调用函数,如果它们已被创建并注册,则会发送正确的参数。
控制器
控制器是任何 Angular 应用程序的核心单元之一。控制器用于创建一个需要自己作用域的模块的小部分。每个模块可以有多个控制器。控制器应该是小的,专注于一项任务。
每个控制器实际上应该只关注数据和任何修改该数据的事件。这意味着控制器不应该修改 DOM、更改输出或输入,或与其他控制器共享状态。每个都应该使用 Angular 的解决方案,即指令、过滤器和服务,分别。
控制器是从模块引用创建的,因此它们与模块相关联。以下是一个创建简单控制器的示例:
firstModule.controller('SimpleController', ['$scope', function ($scope) {
$scope.hey = "HEY!";
console.log($scope);
}]);
然后可以使用ngController将此模块附加到 DOM 元素:
<div ng-controller="SimpleController">
{{ hey }}
</div>
ngController
这是 Angular 映射到模型-视图-控制器模式的核心部分。
<element ng-controller />
参数
ng-controller(expression)属性是一个字符串,它将告诉 Angular 哪个控制器与这个元素相关联。
描述
控制器需要一个文档的部分来附加。此指令将绑定控制器及其作用域到该元素。
如果控制器已在路由中定义,则不应将此指令添加到页面中。路由器将负责绑定到正确的元素。
这里是使用ngcontroller为控制器创建别名的示例:
<div ng-controller="SimpleController as simple">
{{ simple.hey }}
</div>
$scope
这是控制器最重要的部分。这是你应该放置所有跟踪此控制器的位置的地点。这包括任何修改作用域的函数。
$scope控制器通过声明对其的依赖关系(参见依赖注入)注入到控制器中。有一些内置的函数和属性(参见作用域),但由于它只是一个 JavaScript 对象,你可以添加自己的函数和属性。这些将直接映射到控制器中的模板。
这里是一个控制器示例,它定义了一个属性hey和一个函数changeHey。重要的是要注意,在这个函数中根本没有任何对 DOM 引用的引用:
firstModule.controller('SimpleController', ['$scope', function ($scope) {
$scope.hey = "HEY!";
$scope.changeHey = function () {
$scope.hey = $scope.hey === 'HEY!' ? 'OK!' : 'HEY!';
};
}]);
这里是包含所有数据绑定的 HTML 文档的模板:
<div ng-controller="SimpleController">
{{ hey }}
<input type="text" ng-model="hey"/>
<button ng-click="changeHey()">{{hey}}</button>
</div>
Angular 将知道在这个元素中hey是什么,因为它仅限于SimpleController的作用域。
数据绑定和模板
控制器使用 HTML 作为其模板语言。你只需在双括号({{ }})中包围它,就可以绑定控制器作用域中的值。这就是全部内容!
对于某些元素,如input、select和textarea,你不能仅仅将scope对象的值添加到它们来绑定。你必须使用ngModel指令。
$scope部分有一个绑定作用域值到模板的绝佳示例。
事件绑定
Angular 使用指令来绑定事件。在$scope部分,示例使用ngClick来监听按钮上的点击事件。
请参阅指令、事件绑定部分,以获取最常用的事件指令列表。
作用域
注入到控制器中的$scope对象有一些功能。除了这些,我们还将查看作用域的层次结构和消化周期。
消化周期
这是理解作用域的一个重要概念。从高层次来看,消化周期是一个检查是否有作用域变量被更改的周期。如果有,它将执行一个函数。例如,使用{{variable}}将作用域变量绑定到模板上。现在消化周期将监视这个变量,并且每次它更改时,它都会更新模板。如果变量在其他地方被绑定,它也会被更新。这就是 Angular“神奇地”使值自动更新的方式。
有几点需要注意,作用域中并不是所有内容都被监视。最简单的方法是绑定它。你也可以手动监视值。此外,记住,当你监视许多变量时,可能会出现性能问题。消化周期会遍历所有监视器。
$digest
这是你可以启动消化周期的方法:
scope.$digest()
描述
这将手动启动作用域的消化周期。在大多数情况下,这不需要调用。例如,当通过 Angular 处理点击事件更新值时,不需要调用 $digest。Angular 会为你启动消化周期。一个很好的经验法则是,如果你在控制器中从 Angular 事件或指令更改或更新值,你就不需要调用 $digest。
你可能需要调用它的情况之一是处理自定义指令中的异步调用。
$watch
这允许你在消化周期中监视值或计算值:
scope.$watch(watch, listener)
参数
-
watch(string or function): 这是你要监视的内容。字符串将被评估为表达式。函数将可以通过第一个参数访问作用域。使用函数允许你监视作用域中的值,以及变量的计算值。 -
listener(function): 这个函数将具有function(newVal, oldVal, scope)签名。这是当值改变时将执行的函数。
返回值
这是一个用于注销监视器的函数。
描述
这是手动将监视器添加到消化周期的方法。主要有两个原因要做这件事。第一个是当值改变时,你需要运行一个自定义函数。另一个原因是你需要监视 $scope 中值的组合或计算。
这里有一个例子,它监视一个字符串和一个函数。这个例子的基础来自 控制器,$scope 部分。第一个监视器监听作用域中的 hey 变量。另一个监视器查看 hey 的值是否有三个或更多字符。它只会在这个阈值被越过时触发,并且不会再次触发,直到它以相反方向越过:
$scope.$watch('hey', function (newVal, oldVal, scope) {
alert('Hey was changed from ' + oldVal + ' to ' + newVal);
});
$scope.$watch(function (scope) {
return scope.hey.length >= 3;
}, function (newVal, oldVal, scope) {
console.log('Hey listener');
});
$apply
这是手动启动消化周期的方法:
scope.$apply(func)
参数
func(function or string)属性是一个字符串,它将被评估为表达式。如果它是一个函数,该函数将被执行。
返回值
这是函数或表达式的返回值。
描述
这将手动启动消化周期。与 $digest 类似,在大多数情况下不应调用,除非是特定情况。最常见的情况是当作用域值在 Angular 之外被更改时,例如,一个异步 AJAX 调用,它引用了一个作用域值。更新发生在消化循环之外,Angular 并不知道,因为它没有使用任何 Angular 方法。
这导致了一个最佳实践,即始终使用 Angular 的服务和函数。如果你这样做,你就不需要运行$apply。
另一个最佳实践是在$apply内部运行你的函数。Angular 会捕获抛出的任何错误,你可以用 Angular 的方式处理它们。
这里有一个示例,在 2 秒后更新setTimeout内部的范围。由于消化循环已经完成,除非调用$apply,否则它将看不到这个变化:
setTimeout(function () {
$scope.$apply(function () { $scope.hey = 'Updated from setTimeout'; });
}, 2000);
层次结构
Angular 应用只有一个根作用域,但有许多子作用域。当引用一个变量时,它会检查当前作用域,然后检查父作用域。这会一直发生到根作用域。这与 JavaScript 对象使用原型属性的方式非常相似。你可以在第八章JavaScript 面向对象编程中了解更多关于这个内容。
服务
服务在 Angular 应用中的作用是明确的,但在服务的创建方面可能会有困惑。这是因为 Angular 中有三种非常相似的方式来创建服务。我们将逐一查看这些方法以及为什么应该使用它们。
Angular 中的服务是一个对象,它可以是一个数据权威(意味着它是某些数据的唯一来源)。一个很好的例子是路由提供者,因为它是唯一提供路由信息的对象。它是一个单例,所有模块都使用它,一种在控制器之间保持数据同步的方法,或者所有这些!你可能需要的服务的绝佳例子是$http。它为你执行 AJAX 请求。你可以构建一个服务,从你的 API 返回数据,你不必担心在每个控制器中创建 AJAX 调用。
另一个例子是$route和$routeParams服务。当你有一个对$route服务的引用时,你总能找到已匹配的路由。$routeParams服务会告诉你参数。
应该在任何需要多次编写相同代码的情况下使用服务。你可以将其提取出来并放入一个服务中。除此之外,对于将被多个控制器使用的任何数据,都应该创建服务。控制器可以随后向服务请求数据。这将确保这些数据在多个控制器之间保持一致。
列出的所有函数都可以从模块或$provide可注入对象中调用。
工厂、服务和提供者都将依赖于以下 HTML 模板:
<div ng-controller="SimpleController">
{{ service }}
</div>
工厂
这是创建工厂的方法:
module.factory(name, getFunction)
参数
-
name(string): 这是服务将被知晓的名称。这可以用于依赖注入。 -
getFunction(function or array): 这是将返回服务的函数。这也可以是一个列出依赖项的数组。
返回值
这是一个 Angular 模块对象。
描述
服务工厂在需要单例时很棒。除了在factory()函数中完成的配置之外,没有其他配置。每次注入时对象都是相同的。
这里有一个简单的例子,它将返回服务的名称。该例子还创建了对$http的依赖:
firstModule.factory('firstFactory', ['$http', function ($http) {
var serviceName = 'firstFactory';
return {
getName: function(){return serviceName;}
};
}]);
服务
服务可以用new关键字初始化:
module.service(name, constructor)
参数
-
name(string): 这是服务的名称 -
constructor(function or array): 这将是作为构造函数调用的函数
返回值
这是一个 Angular 模块对象。
描述
服务和工厂之间的关键区别在于它可以使用new初始化。以下是一个依赖于$http的例子:
firstModule.service('firstService', ['$http', function ($http) {
return function (name) {
var serviceName = name;
this.getName = function () {
return serviceName;
};
};
}]);
这里是初始化服务的控制器:
firstModule.controller('SimpleController', ['$scope', 'firstService', function ($scope, firstService) {
var first = new firstService('First Service Name');
var second = new firstService('Second Service Name');
$scope.service = second.getName();
}]);
提供者
提供对服务设置最大控制的函数:
module.provider(name, provider)
参数
-
name(string): 这是提供者的名称 -
provider(function or array)
返回值
这是一个 Angular 模块对象。
描述
这是构建服务的最终和最复杂的方式。它必须返回一个包含$get方法的对象。当你必须为此对象配置时,你应该使用这个。这是唯一可以在应用程序启动配置阶段注入的提供者。单词“提供者”将附加到这个名称上。例如,如果你将你的提供者命名为my,它将使用myProvider注入。以下是一个在配置期间注入其名称的示例提供者。首先是提供者定义:
firstModule.provider('first', function () {
var serviceName;
return {
configSet: function (name) {
serviceName = name;
},
$get: function () {
return {
getName: function () { return serviceName; }
};
}
}
});
接下来是配置。注意它是如何使用firstProvider注入的:
firstModule.config(['firstProvider', function (firstProvider) {
firstProvider.configSet('firstProvider123');
}]);
最后,这里是控制器:
firstModule.controller('SimpleController', ['$scope', 'first', function ($scope, firstProvider) {
$scope.test = firstProvider.getName();
}]);
值
这在模块中设置一个值:
module.value(name, value)
参数
-
name(string): 这是值的名称 -
value(object): 这可以是任何东西
返回值
这是一个 Angular 模块对象。
描述
值是设置后可以稍后注入的东西。值只能注入到控制器或服务中,不能在配置期间注入。
这里是一个简单的值例子:
firstModule.value('appTitle', 'First App');
常量
这在模块中创建了一个常量变量:
module.constant(name, value)
参数
-
name(string): 这是值的名称 -
value(object): 这可以是任何东西
返回值
这是一个 Angular 模块对象。
描述
这与值非常相似,除了它可以在config函数中使用,并且值不能被装饰。
这里是一个简单的常量例子:
firstModule.constant('appTitle', 'First App');
$http
这是用于进行 HTTP 调用的服务:
$http(config)
参数
-
config(object): 此对象具有以下属性:-
method(string): 这是 HTTP 方法。 -
url(string): 这是 URL。 -
params(string or object): 这是请求的参数。一个对象将被映射为键值对。 -
data(string or object): 这是请求中要发送的数据。 -
headers(object): 这设置了请求的头。 -
xsrfHeadername(string): 这是 XSRF 的头名称。 -
xsrfCookieName(string): 这是 XSRF 的 cookie 名称。 -
cache(Boolean):这用于决定是否缓存数据。 -
responseType(string):这用于决定请求的类型。
-
返回值
将返回一个承诺。
描述
如果你熟悉 jQuery 的 AJAX 函数,那么你对这个应该很熟悉。这是 Angular 实现任何XMLHttpRequests的方式。对于大多数事情,你将使用一些方便的方法,这些方法使得使用$http更加容易。
方便方法
你可以使用所有的 HTTP 方法作为函数:GET、POST、HEAD、PUT、DELETE和PATCH。我们只将详细查看GET、POST和JSONP。
注意
GET、POST和JSONP将涵盖大多数人对于$http的需求,如果不是全部的话。如果这还不够,请查看$http的文档:docs.angularjs.org/api/ng/service/$http。
每个函数都将 URL 作为第一个参数,以及一个config对象,这个config对象与$http()获取的是同一个。
GET
这是一个GET请求:
$http.get(url, config)
描述
这执行了一个简单的GET请求。以下是一个使用$http.get的工厂示例:
这里是工厂:
firstModule.factory('httpService', ['$http', function ($http) {
return {
test: function () { return $http.get('test', {params: 'test'}); }
}
}]);
这返回一个承诺,控制器可以使用它:
firstModule.controller('SimpleController', ['$scope', 'httpService', function ($scope, httpService) {
httpService.test().success(function (data, status) {
console.log(data);
})
.error(function (data, status) { console.log('An error occured');});
}]);
POST
这是一个POST请求:
$http.post(url, config)
描述
这将发起一个POST请求。以下是一个创建POST请求的工厂和示例,使用 localhost。请记住,你必须运行一个响应POST请求的服务器,这样它才能工作:
firstModule.factory('httpService', ['$http', function ($http) {
return {
test: function () { return $http.post('http://localhost/post', { data: 'HEY' }); }
}
}]);
jsonp
当你必须发起跨源请求时,你应该使用JSONP。这将允许你使用数据,而不是根据安全原因阻止请求。
显著的服务
我将列出一些可以注入的有用服务,以及每个服务的简要说明:
-
$anchorScroll:此参数允许你滚动到 hash 中的元素 -
$animate:此参数允许 DOM 操作 -
$cacheFactory:这允许缓存 -
$http:见$http -
$interval:这是使用 Angular 的方式调用setInterval -
$location:这获取window.location的信息 -
$rootScope:这返回应用程序的根作用域 -
$route:见路由 -
$q:这允许在我们的项目中添加承诺 -
$timeout:这是使用 Angular 的方式调用setTimout
这不是一个完整的列表,因为 Angular 有很多服务,并且可以创建和包含更多。这些是在你的应用程序中最可能使用的服务。
承诺
在 JavaScript 中,许多操作都是异步的。一个很好的例子是 AJAX 请求。当请求发送时,你不知道何时或甚至是否会有请求返回。这就是承诺出现的地方。
承诺是一个对象,它承诺在异步事件发生后运行一个函数。在我们的例子中,事件将是请求返回。这可能是在几毫秒或更长的时间内,这取决于超时设置。
除了跟踪成功的事件外,promises 还可以被拒绝。这允许等待响应的对象执行不同的操作。
注意
访问 promisesaplus.com/ 获取使用 JavaScript 中 promises 的完整规范。Promises 或类似 promises 的对象几乎适用于你编写的任何 JavaScript 代码。
$q
这是实现 promises 的服务:
$q.defer()
返回值
这返回一个延迟对象。
描述
这是构建和使用 promises 的核心。首先,你需要获取一个延迟对象,它将包含解析和拒绝函数。当操作成功时,调用 resolve 函数;当它失败时,调用 reject。最后,使用 defer.promise 返回 promise。
使用 promise,你可以调用 then,它接受两个函数。第一个函数将在 resolve 被调用时执行,第二个函数将在 reject 被调用时执行。promise 可以被传递并在多次调用 then。
任何你进行异步操作的时候,都应该使用 promises。使用 Angular 时,你应该使用 $q,因为它与 rootscope 相关联。
这里有一个例子,当数字为偶数时函数会成功,当数字为奇数时会失败。然后,它执行两次,在控制台记录成功或失败。注意,函数是在控制器中创建的,但像这样的实用函数应该被放入服务中生产:
firstModule.controller('SimpleController', ['$scope', '$q', function ($scope, $q) {
function qTest(number) {
console.log($q);
var defer = $q.defer();
if (number % 2 === 0) {
defer.resolve(number);
} else {
defer.reject(number);
}
return defer.promise;
};
qTest(2)
.then(function (n) { console.log('succeeded!'); }, function (n) { console.log('failed!'); });
qTest(3)
.then(function (n) { console.log('succeeded!'); }, function (n) { console.log('failed!'); });
}]);
表达式
表达式是 Angular 的一个特性。它们是 JavaScript 命令的子集,除了一些 Angular 函数。表达式在 Angular 的许多地方被使用。例如,每次你绑定数据时,你都可以使用一个表达式。这使得理解表达式变得很重要。
表达式将被评估为一个值,一个真值,一个作用域中的函数,或一个作用域中的变量。这使得它们强大,但它们确实有一些限制。
JavaScript 中的表达式
你可以在表达式中使用一些 JavaScript,但不能使用所有的 JavaScript。以下是一些你可以在表达式中使用和在表达式中不能使用 JavaScript 的事情:
-
你可以使用字符串、数字、布尔值、数组字面量或对象字面量
-
你可以使用任何运算符,例如,
a + b,a && b或a || b -
你可以访问对象上的属性或在数组中查找值
-
你可以调用函数
-
你不能在表达式中使用流程控制语句,例如,一个
if语句
上下文
当在 Angular 中评估表达式时,它将使用其所在的范围。这意味着你可以使用在范围内可访问的任何对象或函数。一个区别是,你将无法访问全局 window。例如,你无法在表达式中使用 window.alert。
指令
指令是 Angular 用来连接到文档对象模型(DOM)的。这允许 Angular 将应用程序每个部分应该做什么的关注点分开。这意味着控制器永远不应该直接操作 DOM。控制器应该只通过指令来改变 DOM。
规范化
当使用指令时,Angular 必须解析 DOM 并确定哪些指令适用于它。这是通过规范化所有元素和标签来完成的。规范化将删除任何";", "," " -", 或" _"。它还将从任何属性的起始位置删除x-和data-。例如,当查找ngModel时,以下所有内容都将匹配:
-
x-ng:model -
data-ng_model -
ng-model -
ng:model
注意
如果你关心 HTML 5 验证,那么你应该使用data-规范化。
作用域
指令内部的范围可能会变得非常复杂。我们将探讨几种使用范围的不同方法。
首先是继承作用域。这意味着指令将使用控制器作用域中变量的值。在这个例子中,test必须在控制器的作用域中设置:
firstModule.directive('firstTest', function () {
return {
template: 'This is the test directive. Test: {{test}}'
};
});
@ 绑定
下一个作用域修改将是隔离作用域。你可以设置返回的指令定义对象(见下一节)的作用域属性。这里使用的将改变作用域的构建方式。一个@符号将按单向绑定读取值到作用域中。一个=符号将创建双向绑定。每个都可以使用它们后面的属性名。
例如,要将单向绑定绑定到属性scope-test,使用:@scopeTest。以下是一个示例:
firstModule.directive('firstTest', function () {
return {
restrict: 'AE',
scope: {
test: '@scopeTest'
},
template: 'This is the test directive. Test: {{test}}'
};
});
这可以像这样使用:
<div first-test scope-test="Scope Test Value"></div>
= 绑定
这是使用=的示例。控制器需要在作用域中有一个变量传递给指令。以下是该指令的示例:
firstModule.directive('firstTest', function () {
return {
restrict: 'AE',
scope: {
test: '='
},
template: 'This is the test directive. Test: {{test}}'
};
});
指令的使用方式如下:
<div first-test test="fromControllerScope"></div>
注意,用于连接作用域的属性被称作test。这是因为我们只使用了=,而没有使用=nameOfVariable。
& 绑定
这是最后一种方式,即传递一个函数。这是通过&完成的。当创建具有隔离作用域的指令时,你会遇到一个问题,即让控制器知道何时采取行动。例如,当按钮被点击时,& 绑定允许控制器传递一个函数的引用,并让指令执行它。
这里是一个示例指令:
firstModule.directive('firstTest', function () {
return {
restrict: 'AE',
scope: {
testAction: '&'
},
template: '<button ng-click="testAction()">Action!</button>'
};
});
模板现在有一个按钮,当点击时会调用testAction。将要执行的testAction参数是从控制器传递过来的,并且存在于指令的作用域中。
这是该指令的 DOM 结构:
<div first-test test-action="functionFromController()"></div>
另一种情况是,你可能需要从指令传递信息到控制器,例如事件对象或作用域中的变量。以下是一个示例,展示了 Angular 如何使$event对象在函数中可用。
这是该指令的示例:
firstModule.directive('firstTest', function () {
return {
restrict: 'AE',
scope: {
testAction: '&'
},
template: '<button>Action!</button>',
link: function ($scope, element) {
element.on('click', function (e) {
$scope.$apply(function () {
$scope.testAction({ $e: e, $fromDirective: 'From Directive' });
});
});
}
};
});
关键是 link 属性。它在指令编译之后运行,并绑定到指令的实例。如果你有一个重复的指令,这一点很重要。接下来,你将使用类似 jQuery 的 API JQLite 监听点击事件。从这里,我们必须调用 $apply,因为我们不在 Angular 中,它将不会检测到这里的任何更改。最后,我们执行了传递的表达式,创建了两个变量 $e 和 $fromDirective,它们将在控制器中的函数中可用。
下面是指令在 DOM 中的样子:
<div first-test test-action="functionFromController($e, $fromDirective)"></div>
两个变量,$e 和 $fromDirective,需要与你在指令中定义的名称相同。
修改 DOM
Angular 对关注点的分离非常明确。这有助于防止难以追踪的错误出现。其中一种分离是控制器不应该修改 DOM。那么在哪里修改 DOM 呢?在指令中。
指令是 Angular 应用程序中唯一应该知道 DOM 中元素的部分。当需要修改 DOM 时,应该由指令来完成。
Angular 包含一个类似 jQuery 的库,称为 jQLite。它具有许多 jQuery 的 DOM 操作函数。如果你熟悉 jQuery,那么你也就熟悉 jQLite。
下面是一个简单的指令示例,当按钮被点击时添加一个 div 元素。该示例使用 jQLite 的 append 函数:
firstModule.directive('firstTest', function () {
return {
restrict: 'AE',
scope: {
testAction: '&'
},
template: '<button>Add a DIV!</button>',
link: function ($scope, element) {
element.on('click', function (e) {
element.append('<div>I was added!</div>');
});
}
};
});
事件绑定
在 Angular 应用程序中,只有指令应该监听 DOM 事件,例如点击事件。这使得处理程序所在的位置非常清晰。
下面是一个绑定到元素点击事件并记录到控制台的示例:
firstModule.directive('firstTest', function () {
return {
restrict: 'AE',
scope: {
testAction: '&'
},
template: '<button>Add a DIV!</button>',
link: function ($scope, element) {
element.on('click', function (e) {
console.log(e);
});
}
};
});
此外,指令还可以让控制器传递一个函数,并在事件发生时执行它(参见 = 绑定)。最后,指令甚至可以将参数从指令传递到控制器。一个很好的例子是事件对象,它是从事件返回的(参见 & 绑定)。
指令定义对象
指令定义对象是告诉 Angular 如何构建指令的对象。
这里列出了最常用的属性及其快速概述:
-
priority: 具有更高优先级的指令将被首先编译。默认值为0。 -
scope: 请参阅 指令,作用域 部分,以获取更深入的概述。 -
controller: 这可能有些令人困惑,但控制器用于在指令之间共享逻辑。另一个指令可以通过使用require并列出所需指令的名称来共享控制器中的代码。那个指令的控制器将被注入到link函数中。该函数将有以下定义:function($scope, $element, $attrs, $transclude)。 -
require: 需要的指令的字符串。在前面加上?将使其成为可选的,^将在元素及其父元素中搜索,如果没有找到则抛出错误,而?^将在元素及其父元素中搜索,但它是可选的。函数实例将在指令之间共享。 -
restrict: 这将限制你可以在 DOM 中定义指令的方式。以下是选项,其中E和A是最常用的:-
E: 这代表元素
-
A: 这代表属性和默认值
-
C: 这代表类
-
M: 这代表注释
-
-
template: 字符串形式的 HTML 或一个返回字符串的函数,该字符串包含function(element, attrs)的定义。 -
templateUrl: 从此 URL 加载模板。 -
link: 这是在放置任何 DOM 操作或监听器的地方。此函数将具有以下定义:function(scope, element, attrs, requiredController, transcludeFunction)。如果需要另一个指令,则其controller属性将是requiredController参数。
控制器 vs 链接
在构建指令时,何时使用 controller 或 link 函数可能会非常令人困惑。你应该将 controller 函数视为其他指令可以使用的接口。当一个指令需要另一个指令时,controller 返回值将被注入到 link 函数中。这将作为第四个参数。然后可以从 link 中访问该对象。link 函数用于任何 DOM 操作或监听器。
关键指令
这里有一些最常用的指令。
ngApp
这是你的 Angular 应用程序的根:
<element ng-app></element>
参数
ng-app(string)属性是默认模块的名称。
描述
这将设置应用程序的根元素。这可以放在任何元素上,包括根 HTML 元素。
这将自动引导 Angular 加载在 ng-app 中定义的模块。
ngModel
这将数据从作用域绑定到元素上:
<input ng-model [ng-required ng-minlength ng-maxlength ng-pattern ng-change ng-trim]></input>
参数
-
ng-model(string): 这将在作用域中成为一个变量 -
ng-required(boolean): 这将此输入设置为必填 -
ng-minlength(int): 这设置最小长度 -
ng-maxlength(int): 这设置最大长度 -
ng-pattern(string): 这是要匹配的值的正则表达式 -
ng-change(expression): 这是在值变化时将执行的 Angular 表达式 -
ng-trim(boolean): 这决定是否要修剪值
描述
这用于将控制器的作用域中的变量绑定到输入元素(文本、选择或文本区域)。这将是一个双向绑定,因此变量的任何更改都将更新其所有实例。
这里有一个简单的文本输入示例:
<input ng-model="test" type="text"/>
{{test}}
ngDisabled
这可以禁用元素:
<input ng-disabled></input>
参数
- 如果
ng-disabled(expression)属性评估为 true,则输入将被禁用。
描述
这允许你通过代码轻松地禁用输入。表达式可以绑定到作用域变量或仅评估表达式中的内容。
这里是一个简单的示例,它禁用了文本输入:
<input ng-disabled="true" type="text"/>
ngChecked
这可以使一个元素被选中:
<input ng-checked></input>
参数
ng-checked(expression)属性是 Angular 表达式,它应该评估为 JavaScript 布尔值。
描述
这是 Angular 根据控制器中的某些内容检查或取消选中复选框的方式。
这里是一个示例:
<input ng-checked="true" type="checkbox"/>
ngClass
这设置了一个元素的类:
<element ng-class></element>
参数
ng-class(expression)属性可以是字符串、数组或对象映射。
描述
当表达式是字符串或数组时,字符串的值或数组的值将作为类应用于元素。当然,这些可以绑定到作用域中的变量。
这里是一个使用字符串设置类的示例。这里是将要应用的风格:
.double { font-size: 2em; }
这里是应用它的代码:
<div ng-class="classString">Text</div>
<input type="text" ng-model="classString" />
类绑定到classString变量的值。输入绑定,以便任何更改都会更新div上的类。一旦你输入双倍,它就会应用这种风格。
这里是一个使用对象映射的示例。对象的属性名是要应用的类,值必须是true。这里是一个使用相同类的类似示例:
<div ng-class="{double: classString}">Text</div>
<input type="text" ng-model="classString" />
你会注意到,一旦你输入任何内容到输入框中,类就会被应用。这是因为非空字符串将是true。你可以使用这来应用所需的任何类,使用更多的属性。
ngClassOdd 和 ngClassEvent
这些分别设置奇数或偶数元素的类:
<element ng-class-odd></element>
<element ng-class-even></element>
参数
ng-class-odd或ng-class-even(expression)属性必须评估为字符串或字符串数组,这些字符串将成为元素的类。
描述
这两个指令相关,甚至可以应用于同一个元素。如果一个重复的元素是奇数,那么ng-class-odd将会被评估,对于ng-class-even也是如此。
这里是一个示例,它将使每个奇数元素的大小加倍,每个偶数元素的大小减半。以下是样式:
.odd { font-size: 2em; }
.even { font-size: .5em; }
这里是元素。ul属性创建要重复的数据,每个span参数静态地将类设置为奇数或偶数。你还可以使用作用域中的变量:
<ul ng-init="numbers=[1,2,3,4]">
<li ng-repeat="number in numbers">
<span ng-class-even="'even'" ng-class-odd="'odd'">{{number}}</span>
</li>
</ul>
ngRepeat
这是一个可以重复的模板:
<element ng-repeat></element>
参数
ng-repeat(repeat_expression)属性类似于表达式,但它有一些语法差异。请参阅描述以获取完整解释。
描述
许多时候,你会有具有相似模板但每行数据都不同的数据。这就是ng-repeat发挥作用的地方。ng-repeat函数将重复重复表达式中的每个项目的 HTML。
重复表达式是一个表达式,它告诉ng-repeat将要循环哪些项目。以下是一些表达式的概述:
-
item in collection:这是一个经典的 foreach 语句。它将遍历集合(例如数组)中的每个项目。item参数将在模板内部可用。 -
(key, value) in collection:如果你的数据在一个对象中,并且你想能够将属性的名称与值关联起来,那么你需要使用这个。 -
item in collection track by grouping:这允许进行分组。分组将只为每个唯一的分组值提供一个项目。 -
repeat expression | filter:你可以过滤这些表达式中的任何一个,以得到数据的一个子集。
这是一个使用无序列表的示例。以下是控制器:
firstModule.controller('SimpleController', ['$scope', function ($scope) {
$scope.items = [{id: 1, name: 'First' }, {id: 2, name: 'Second'}];
}]);
这是控制器的 HTML:
<div ng-controller="SimpleController">
<ul>
<li ng-repeat="item in items track by item.id">
ID: {{item.id}}
Name: {{item.name}}
</li>
</ul>
</div>
ngShow 和 ngHide
这些可以分别显示或隐藏元素:
<element ng-show></element>
<element ng-hide></element>
参数
ng-show或ng-hide(expression)属性将被评估为true或false,元素将相应地显示或隐藏。
描述
这些指令允许您根据作用域内的数据显示或隐藏内容。
这是一个使用计数器来显示或隐藏元素的示例。你可以使用 ng-hide 并使用相反的逻辑。以下是控制器:
firstModule.controller('SimpleController', ['$scope', function ($scope) {
$scope.count = 0;
$scope.increase = function () { $scope.count++; };
}]);
接下来是 HTML:
<div ng-controller="SimpleController">
<div ng-show="count == 0">Count is zero: {{count}}</div>
<div ng-show="count > 0">Count is greater than zero: {{count}}</div>
<button ng-click="increase()">Increase Count</button>
</div>
ngSwitch
这创建了一个 switch 语句:
<element ng-switch>
<element ng-switch-when></element>
<element ng-switch-default></element>
</element>
参数
-
ng-switch(expression):这是一个返回值的表达式。这个值将在评估ng-switch-when时使用。 -
ng-switch-when(expression):当值匹配此表达式时,则此元素将可见。 -
ng-switch-default:当ng-switch-when不匹配时,此元素将显示。
描述
这个指令的工作方式与 JavaScript 的 switch 语句非常相似。不同的案例会被测试,并使用匹配的案例。如果没有案例匹配,则使用默认元素。
这是一个在偶数和奇数之间跳转的示例。以下是控制器:
firstModule.controller('SimpleController', ['$scope', function ($scope) {
$scope.count = 0;
$scope.increase = function () { $scope.count++; };
}]);
然后是 HTML:
<div ng-controller="SimpleController">
<div ng-switch="count % 2">
<div ng-switch-when="0">Count is Even: {{count}}</div>
<div ng-switch-when="1">Count is Odd: {{count}}</div>
</div>
<button ng-click="increase()">Increase Count</button>
</div>
ngClick
这用于定义点击处理器:
<element ng-click></element>
参数
ng-click(expression)属性是在元素被点击时将被评估的内容。可以使用函数,并且可以使用function($event)函数定义来访问事件对象。还可以传递作用域中的任何其他变量,例如,在重复器中的$indexin。
描述
这个指令允许您在元素点击时运行 JavaScript。通常,这会与作用域中的函数一起使用。
这是一个将增加 scope 变量的示例。首先,以下是控制器的 scope 变量:
$scope.counter = 0;
$scope.functionFromController = function (e) { $scope.counter++; };
接下来,这是带有 ng-click 指令的元素。在这个例子中,您没有使用事件对象,但它演示了如何将其传递到控制器函数中:
<button ng-click="functionFromController($event)">Click Me!</button>
{{counter}}
ngDblclick
这用于定义双击处理器:
<element ng-dblclick></element>
参数
ng-dblclick(expression)函数,可以使用函数,并且可以使用function($event)函数定义来访问事件对象。还可以传递作用域中的任何其他变量,例如,在重复器中的$index。
描述
这个指令与 ngClick 非常相似。当元素被双击时,表达式将被评估。
这是一个示例,当双击时将增加计数器的 div。以下是控制器的变量:
$scope.counter = 0;
$scope.functionFromController = function (e) { $scope.counter++; };
这里是元素和指令:
<div ng-dblclick="functionFromController($event)">Double Click Me!</div>
{{counter}}
ngMousedown、ngMouseup、ngMouseover、ngMouseenter 和 ngMouseleave
这些指令用于定义鼠标事件处理器:
<element ng-mousedown></element>
<element ng-mouseup></element>
<element ng-mouseover></element>
<element ng-mouseenter></element>
<element ng-mouseleave></element>
参数
- 在
ng-mouse*(expression)函数中,可以使用语句或函数,并且可以通过function($event)函数定义使用事件对象。还可以传递作用域中的其他变量,例如,在重复器中的$index。
描述
这些指令被分组在一起,因为它们都是相关的。当鼠标执行动作(按下、释放、悬停、进入或离开)时,表达式将被评估。
这个例子有点疯狂,但它演示了如何使用这些事件。这里是控制器中的相关部分:
$scope.counter = 0;
$scope.functionFromController = function (e) { $scope.counter++; };
这里是指令列表:
<div ng-mousedown="functionFromController($event)" ng-mouseup="functionFromController($event)"
ng-mouseenter="functionFromController($event)" ng-mouseleave="functionFromController($event)"
ng-mouseover="functionFromController($event)">Mouse Over Me!</div>
{{counter}}
ngMousemove
这用于定义鼠标移动处理器:
<element ng-mousemove</element>
参数
- 在
ng-mousemove(expression)函数中,可以使用语句或函数,并且可以通过function($event)函数定义使用事件对象。还可以传递作用域中的其他变量,例如,在重复器中的$index。
描述
这个指令在鼠标移动时触发。除非指令应用于整个页面,否则事件将仅限于应用到的元素。
这里是一个示例,它将显示鼠标的x和y坐标。这里是相关的作用域变量:
$scope.x = 0;
$scope.y = 0;
$scope.functionFromController = function (e) {
$scope.x = e.pageX;
$scope.y = e.pageY;
};
然后是指令:
<div ng-mousemove="functionFromController($event)">Move the mouse to see the x and y coordinates!</div>
{{x}}
{{y}}
ngKeydown、ngKeyup 和 ngKeypress
这些指令用于定义按键处理器:
<element ng-keydown></element>
<element ng-keyup></element>
<element ng-keypress></element>
参数
- 在
ng-key*(expression)函数中,可以使用语句或函数,并且可以通过function($event)函数定义使用事件对象。还可以传递作用域中的其他变量,例如,在重复器中的$index。
描述
这些指令会在按键按下或释放时触发。
这里是一个示例,它将检索按下的键的键码。这里是相关的scope变量:
$scope.keyCode = 0;
$scope.functionFromController = function (e) {
$scope.keyCode = e.keyCode;
};
接下来是指令:
<input type="text" ng-keydown="functionFromController($event)"/>
Which key: {{keyCode}}
ngSubmit
这些指令用于定义提交处理器:
<form ng-submit></form>
参数
- 在
ng-submit(expression)函数中,可以使用语句或函数,并且可以通过function($event)函数定义使用事件对象。还可以传递作用域中的其他变量,例如,在重复器中的$index。
描述
这个指令用于捕获表单的submit事件。如果表单没有 action 属性,那么这将防止表单重新加载当前页面。
这里是一个简单的示例,它将事件对象记录到submit时的控制台。这里是相关的指令:
<form ng-submit="functionFromController($event)"><input type="submit" id="submit" value="Submit" /></form>
接下来是控制器代码:
$scope.functionFromController = function (e) {
console.log(e);
};
ngFocus 和 ngBlur
这些指令分别用于定义焦点和失焦处理器:
<input, select, textarea, a, window ng-focus></input>
<input, select, textarea, a, window ng-blurs></input>
参数
- 在
ng-focus(expression)函数中,可以使用语句或函数,并且可以通过function($event)函数定义使用事件对象。还可以传递作用域中的其他变量,例如,在重复器中的$index。
描述
当元素获得焦点时,ngFocus 处理程序将被触发,而当它失去焦点时,ngBlur 将被触发。以下是一个使用文本输入并将事件记录到控制台的示例:
<input type="text" ng-focus="functionFromController($event)"/>
以下是控制器代码:
$scope.functionFromController = function (e) {
console.log(e);
};
ngCopy、ngCut 和 ngPaste
<element ng-copy></element>
<element ng-cut></element>
<element ng-paste></element>
参数
ng-copy、ng-cut或ng-paste(expression):可以使用语句或函数,并且可以使用function($event)函数定义来访问事件对象。还可以将作用域中的其他变量传递,例如,在重复器中的$index。
描述
这些是在文本被剪切、复制或粘贴时将触发的事件。以下是一个使用所有三个事件的示例:
<input type="text" ng-cut="functionFromController($event)" ng-copy="functionFromController($event)" ng-paste="functionFromController($event)" />
以下是控制器代码:
$scope.functionFromController = function (e) {
console.log(e);
};
全局变量
这组函数可以在 Angular 的任何地方执行,而无需注入它们。它们主要是实用函数,允许你更容易地或以 Angular 方式做事。
扩展
这提供了一种合并两个对象的方法:
angular.extend(srcObject, destObject)
参数
-
srcObject(object): 将复制属性的对象 -
Destobject(object): 扩展对象将复制属性到的对象
返回值
这将返回 destObject 的引用。
描述
在 JavaScript 中,没有内置的方法可以使用另一个对象扩展对象。这个函数正是这样做的。
以下是一个简单的示例,它将扩展一个对象以包含另一个对象的属性:
var first = { first: '1' };
var second = { second: '2' };
var extended = angular.extend(first, second);
//extended will be {first:'1', second:'2'}
noop
这是无操作函数:
angular.noop()
参数
any或none函数用作这些函数不执行任何操作,你可以传入零个或任意多个参数。
返回值
这将返回 undefined。
描述
有一个不执行任何操作(noop)的函数很有用。一个很好的例子是当你有一个作为参数的函数,它是可选的。如果没有传入,你可以运行 noop。
这是一个简单的示例,演示了前面解释的场景:
function test(doSomething) {
var callback = cb || angular.noop;
callback('output');
}
isUndefined
这检查某个东西是否未定义:
angular.isUndefined(object)
参数
object(any type)函数可以是任何变量。
返回值
这返回一个布尔值。
描述
这表示变量是否已定义。
复制
这将创建一个对象的副本:
angular.copy(srcObject, [destObject])
参数
-
srcObject(any type): 这是将要被复制的源对象。 -
destObject(same type as srcObject): 这是可选的。如果提供,它将是复制操作的目的地。
返回值
这个函数返回 srcObject 的副本。如果提供了 destObject,则返回它。
描述
当你需要复制一个对象而不是修改原始对象时,请使用此函数。
绑定
这将一个函数绑定到一个对象上:
angular.bind(self, function, [args..])
参数
-
self(object): 这将在函数中设置this(内部自我引用) -
Function(function): 这是正在绑定的函数 -
Args(any type): 这些是绑定到函数的参数
返回值
这是新绑定的函数。
描述
这创建了一个新的绑定函数,它将在 self 的上下文中执行。这允许你定义一个函数,然后在不同的上下文中多次执行它。通过绑定参数,这进一步扩展了。
这是一个虚构的例子,但演示了原理。首先是一个依赖于上下文来执行的函数。它将第一个参数添加到 this 中,并乘以该结果:
function addAndMultiply(toAdd, toMultiply) {
return (this + toAdd) * toMultiply;
}
接下来,你将使用 angular.bind 来创建一个新的函数:
var newFunc = angular.bind(4, addAndMultiply, 1);
这可以执行,并且返回值将是乘数的 5 倍。在 newFunc 中,this 是 4,而 toAdd 是 1,所以内层括号总是 5。例如,这将返回 10:
newFunc(2);
表单
表单是 HTML 中向服务器发送数据的核心部分。因此,Angular 有一些与表单一起工作的额外功能。
ngModel
每个表单输入都需要定义 ngModel 以在作用域中存储值。见 指令、ngModel 了解更多信息。
以下是一个简单的表单,它绑定两个文本输入:
<form name="form">
First Name: <input type="text" name="firstname" ng-model="data.firstName" />
Last Name: <input type="text" name="lastName" ng-model="data.lastName" />
</form>
{{data.firstName}} {{data.lastName}}
CSS 类
Angular 会自动将 CSS 类添加到表单和元素中,然后你可以使用 CSS 选择器来定位它们。以下是 CSS 类及其应用情况列表:
-
ng-valid:表示表单或元素有效 -
ng-invalid:表示表单或元素无效 -
ng-pristine:表示控件尚未更改 -
ng-dirty:表示控件已被更改
验证
Angular 有一些特性使得验证变得非常简单。首先,Angular 会使用任何 HTML 5 输入类型。这允许浏览器执行一些验证,但 Angular 仍然会跟踪任何错误。
接下来,你可以使用 ngModel 的任何内置验证指令。列表包括 required、pattern、minLength、maxLength、min 和 max。见 指令、ngModel 了解每个指令的更多信息。当输入验证失败时,值将不会传递到绑定的作用域变量中。
以下是一个设置 firstName 最小长度的示例:
<form name="form">
First Name: <input type="text" name="firstname" ng-minlength="10" ng-model="data.firstName" />
Last Name: <input type="text" name="lastName" ng-model="data.lastName" />
</form>
{{data.firstName}} {{data.lastName}}
当表单有一个 name 属性时,它将绑定到该名称的作用域。当在表单中给输入赋名时,它们将绑定到该表单。这允许你使用其他指令与这些值一起使用。
以下是一个示例,当文本输入未达到 10 个字符的最小长度时,将显示错误消息:
<form name="form">
First Name: <input type="text" name="firstname" ng-minlength="10" ng-model="data.firstName" />
<div ng-show="form.firstname.$invalid">First name must be 10 characters!</div>
Last Name: <input type="text" name="lastName" ng-model="data.lastName" />
</form>
{{data.firstName}} {{data.lastName}}
验证消息仅在字段无效时显示。
表单将具有 $dirty、$invalid、$pristine 和 $valid 属性,可以在指令或作用域中使用。输入将具有相同的属性,并且还有一个 $error 对象,它将每个失败的验证作为属性。在前面的例子中,这意味着当输入未通过该验证时,form.firstname.$error.minLength 将返回 true,当它有效时返回 false。
自定义验证器
当你需要创建自己的逻辑时,你可以构建一个自定义验证器。你需要创建一个新的指令,引入 ngModel,并在将其传递到 link 函数时,通过 ngModel 控制器的 $parsers 对象传递值。然后,根据传递的值是否通过验证使用 $setValidity。
这里是一个自定义验证器的示例,其中输入的值不能设置为 josh:
firstModule.directive('notJosh', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
if (viewValue.toUpperCase() === 'JOSH') {
ctrl.$setValidity('notJosh', false);
return undefined
}
else {
ctrl.$setValidity('notJosh', true);
return viewValue;
}
});
}
}
});
测试
测试应该始终是任何开发项目的重要组成部分。Angular 从一开始就被设计为可测试的。它具有清晰的关注点分离;例如,你不需要构建完整的 DOM 来测试控制器。Angular 还在所有地方使用依赖注入,这使得模拟对象变得非常容易。
使用 Jasmine 和 Karma 进行单元测试
Jasmine 和 Karma 是两个允许你快速轻松地测试 Angular 代码的工具。
Jasmine
这是我们将使用的实际单元测试库。Jasmine 是一个行为驱动测试框架,编写起来非常简单。
Karma
Karma 是一个测试运行器,它将监视你的文件并在文件发生变化时自动启动测试。它运行在 Node.js 上,因此你必须安装它。然后,你可以使用 npm 安装 Karma:
install karma-jasmine
Karma 可以监视你的测试文件,并在任何文件发生变化时重新运行它们。如果存在任何问题,你还可以在浏览器中调试测试。它是 Jasmine 的绝佳补充,Google 推荐两者都用于测试。
ngMock
ngMock 处理器用于在测试时帮助模拟应用程序。在测试时,你不会想创建一个完整的 DOM 来加载单个模块。这就是 ngMock 可以创建一个控制器实例以供使用的地方,然后我们可以对其进行测试。
模块
这允许你加载一个模块:
module(moduleName)
参数
moduleName(string)函数执行
描述
你没有根元素可以放置 ng-app,因此 module 允许我们加载一个模块以获取其控制器、服务和指令的访问权限。你应该只在加载 ngMock 后在测试中使用此函数。
注入
这获取 Angular 注入服务:
inject(toBeInjected)
参数
toBeInjected(function)函数的工作方式与其他注入函数类似。列出要注入的对象,它们将在函数体中可用。
描述
使用注入来获取内置的 Angular 服务,例如 $controller 和 $compile,或者使用它来获取加载模块的服务。
如果依赖项被下划线包裹,注入可以加载依赖项。例如,如果使用 _$compile_,注入将加载 $compile。这是因为在测试中,我们需要创建 $compile 服务的引用,并且很可能会希望将 $compile 作为变量名。下划线允许你注入它并使用 $compile 变量。
$httpBackend
这可以创建一个模拟响应:
$httpBackend.when(requestType, url, [requestParameters], [headers])
$httpBackend.expect(requestType, url, [requestParameters], [headers])
$httpBackend.respond(response)
参数
-
requestType(string): 这是请求的 HTTP 方法 -
url(string): 这是请求的 URL -
requestParameters(object):这些是请求的参数 -
headers(object):这些是请求的头信息 -
response(string, object):这是请求的响应
返回值
这将返回一个可以调用respond的处理程序。
描述
在单元测试中执行 AJAX 调用是一个不应该做的事情的例子。对于单元测试来说,有太多您无法控制的事情。$httpBackend处理器由ngMock提供,以便您可以创建模拟响应。
处理器至少必须匹配预期的方法和 URL。如果您计划使用它们进行特定请求,还可以匹配可选参数和头信息。
当请求匹配时,您可以发送一个字符串或对象作为响应。这允许您创建一个使用$httpBackend的测试,因为您知道响应将会是什么。
expect和when之间的区别在于expect必须在测试中调用,而when没有这个要求。
单元测试控制器
这里是一个控制器简单单元测试的例子。首先,您必须创建一个控制器,然后在我们的测试中加载它:
var firstModule = angular.module('firstModule', ['ngMock']);
firstModule.controller('SimpleController', ['$scope', function ($scope) {
$scope.test = 'HEY!';
}]);
您现在可以创建测试。在测试中,您必须加载firstModule模块,注入$controller,并创建SimpleController的实例。以下是测试代码:
describe('SimpleController', function () {
var scope = {};
var simpleCtrl;
beforeEach(module('firstModule'));
it("should have a scope variable of test", inject(function ($controller) {
expect(scope.test).toBe(undefined);
simpleCtrl = $controller('SimpleController', { $scope: scope });
expect(scope.test).toBe('HEY!');
}));
});
单元测试指令
这个例子将向您展示如何测试一个指令。首先,创建指令:
firstModule.directive('simpleDirective', function () {
return {
restrict: 'E',
scope:{
test: '@'
},
replace: true,
template: '<div>This is an example {{test}}.</div>'
};
});
接下来,您需要加载模块,注入$compiler和$rootscope,编译指令,并最终至少启动一次消化循环以绑定任何值:
describe('simpleDirective', function () {
var $compile, $rootScope;
beforeEach(module('firstModule'));
beforeEach(inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
}));
it('should have our compiled text', function () {
var element = $compile('<simple-directive test="directive"></simple-directive>')($rootScope);
$rootScope.$digest();
expect(element.html()).toContain('This is an example directive.');
});
});
单元测试服务
最后的测试示例将测试一个服务。首先,创建服务:
firstModule.factory('firstFactory', ['$http', function ($http) {
return {
addOne: function () {
return $http.get('/test', {})
.then(function (res) {
return res.data.value + 1;
});
}
}
}]);
接下来,您需要加载模块,注入$httpBackend和服务工厂,创建一个响应,并加载该响应。注意$httpBackend.flush()的使用。这将把响应发送到任何打开的请求:
describe('firstFactory', function () {
var $httpBackend, testingFactory, handler;
beforeEach(module('firstModule'));
beforeEach(inject(function (_$httpBackend_, firstFactory) {
$httpBackend = _$httpBackend_;
handler = $httpBackend.expect('GET', '/test')
.respond({ value: 1 });
testingFactory = firstFactory;
}));
it('should run the GET request and add one', function () {
testingFactory.addOne()
.then(function (data) {
expect(data).toBe(2);
});
$httpBackend.flush();
});
});





浙公网安备 33010602011771号