整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

移动端用户手册分析

与智能手机刚发布时相比,现如今的手机已经获得长足的发展,无论是功能、操作方式都大大丰富。但随之而来的问题是面对时时更新的功能,如何才能有效让用户及时了解?因此为了更好地宣传手机/系统的特色功能,给用户提供一个了解手机和品牌的窗口,用户手册(玩机技巧、使用技巧等)APP才会被预装在我们的新手机上。

开发实现方式对后期交互体验的影响

在设计第一版用户手册讨论实现方式时,开发建议html套壳的方式,这种方式的优势:只需要开发一个后台管理系统,即可对内容进行管理,并且可在不同版本上使用。而如果开发原生APP,就需要不同版本系统独立维护,同时更新需要发布新版本。这么看来确实是使用html套壳的方式更好。

但是后面开发出来以后发现,html套壳实现的用户手册体验完全无法与原生APP相比。具体体现在:1、对网络依赖强,每次打开都需要重新加载整个页面;2、和手机很难保持视觉和操作的统一,最明显的就是在使用h5组件开发出来的toast很难和系统规范保持一致;3、无法与手机系统交互,竞品通过点击按钮可以轻松调起系统设置,但是h5很难实现;综上,webapp体验无法与原生相比。

首页风格

由于APP本身的属性,用户手册整体的调性可以更前卫、概念,就好比车厂会把最新、最炫酷的技术都应用在概念车上。因此用户手册首页也跟着品牌调性走。例如华为的首页更传统、严谨;VIVO传达的是年轻、探索,因此风格上更多彩、灵活;OPPO没有独立的应用,使用技巧集成在OPPO社区中,因此这一模块带有较重的社交属性,短视频、图文内容等主流媒介辅助用户了解手机新功能。

条目分析

华为采用列表导航的入口方式,算是比较稳妥、传统的布局,既兼顾效率,又方便对比,是一种比较高效的布局;VIVO整体更加年轻,顶部使用的是通栏banner,搜索功能被弱化,同时采用双列的宫格式入口方式,这样虽然牺牲了阅读的效率,但整体更加美观、统一。另外,VIVO入口的文章计数方式使用了两种标准,一种是绝对数值,即内含多少文章,一种是相对数值,即更新数量,但在样式上两种数值没有区分。

详情页

功能介绍详情页可以大致分为五个区域,分别是标题栏、图像区、文字区、功能区以及页面导航。各个竞品可实现的功能大同小异,不同点有:

  1. 华为对功能的文字说明更详细,图像区域也更大,所以页面有时候需要滑动查看,其他两个竞品可以在一屏就展示全
  2. 对比其他两家竞品,VIVO没有反馈的功能
  3. 华为和VIVO设置了快速跳转至该功能的快捷入口,更人性化

折叠菜单与沉浸阅读的思考

竞品分析过程中我们发现,三家竞品都使用了同样的操作路径,即首页>详情页>折叠菜单,但为什么不是首页>折叠菜单>详情页呢?我的思考是,从用户角度出发,两种操作路径背后是两类目标不同的用户。路径二更像一条查找路径,适合带有强烈目的性的用户,路径二则更符合阅读的场景,沉浸感更强。拿市面上的小说APP或者漫画APP举例,在2G、3G网络时代,打开一个页面需要流量,前进后退需要大量加载时间,看小说都是得从目录中选择章节才能看到内容。但是如今网速和硬件都大幅提升,基本上所有的阅读产品都是点击马上进入到内容中去了,因此以最快速度加载内容并呈现到用户眼前才是最优解。


avaScript 是世界上最流行的编程语言之一。

我相信这是您第一个绝佳选择的编程语言。

我们主要使用JavaScript来创建:

  • 网站
  • 网络应用
  • 使用 Node.js 的服务器端应用程序

我们的网站:https://www.icoderoad.com

但 JavaScript 不限于这些东西,它还可以用于:

  • 使用 React Native 等工具创建移动应用程序
  • 为微控制器和物联网创建程序
  • 创建智能手表应用程序

它基本上可以做任何事情。它非常流行,以至于出现的所有新事物都会在某个时候能集成某种 JavaScript。

JavaScript 是一种编程语言,它是:

  • 高级:它提供了允许您忽略运行它的机器细节的抽象。它使用垃圾收集器自动管理内存,因此您可以专注于代码而不是像 C 等其他语言那样管理内存,并提供许多允许您处理非常强大的变量和对象的结构。
  • 动态:与静态编程语言相反,动态语言在运行时执行静态语言在编译时所做的许多事情。这有利有弊,它为我们提供了强大的功能,如动态类型、后期绑定、反射、函数式编程、对象运行时更改、闭包等等。如果您不知道这些事情,请不要担心——在课程结束时您会了解全部相关知识。
  • 动态类型:不强制变量类型。您可以将任何类型重新分配给变量,例如,将整数分配给包含字符串的变量。
  • 松散类型:与强类型相反,松散(或弱)类型语言不强制对象的类型,允许更大的灵活性但拒绝我们类型安全和类型检查(TypeScript - 它建立在 JavaScript 之上 - 提供)
  • 解释:它通常被称为解释语言,这意味着它在程序运行之前不需要编译阶段,这与 C、Java 或 Go 等语言不同。实际上,出于性能原因,浏览器会在执行 JavaScript 之前对其进行编译,但这对您来说是透明的——不涉及额外的步骤。
  • 多范式:该语言不强制执行任何特定的编程范式,例如强制使用面向对象编程的 Java 或强制使用命令式编程的 C。您可以使用面向对象的范型、使用原型和新的(从 ES6 开始)类语法来编写 JavaScript。您可以使用函数式编程风格、一流的函数,甚至是命令式风格(类 C)来编写 JavaScript。

如您所知,JavaScript 与 Java 无关,这是一个糟糕的名称选择,但我们必须忍受它。

手册摘要

  1. 历史
  2. JavaScript
  3. 语法简介
  4. 分号
  5. 值域
  6. 变量
  7. 类型
  8. 表达式
  9. 运算符
  10. 优先规则
  11. 比较运算符
  12. 条件语句
  13. 数组
  14. 字符串
  15. 循环
  16. 函数
  17. 箭头函数
  18. 对象
  19. 对象属性
  20. 对象方法
  21. 继承
  22. 异步编程和回调
  23. Promise
  24. 异步和等待
  25. 变量范围
  26. 结论

历史

JavaScript 创建于 1995 年,自其不起眼的开始以来已经走过了很长的路。

它是 Web 浏览器原生支持的第一种脚本语言,因此它获得了优于任何其他语言的竞争优势,今天它仍然是我们可以用来构建 Web 应用程序的唯一脚本语言。

也存在其他语言,但都必须编译为 JavaScript - 或者最近编译为 WebAssembly,但这是另一回事。

最初 JavaScript 还没有今天那么强大,它主要用于花哨的动画和当时被称为动态 HTML奇迹。

随着 Web 平台(并且继续要求)不断增长的需求,JavaScript也有责任发展,以适应世界上使用最广泛的生态系统之一的需求。

JavaScript 现在也在浏览器之外广泛使用。Node.js 在过去几年的兴起开启了后端开发的大门,曾经是 Java、Ruby、Python、PHP 和更传统的服务器端语言的领域。

JavaScript 现在也是支持数据库和更多应用程序的语言,甚至可以开发嵌入式应用程序、移动应用程序、电视应用程序等等。最初是浏览器中的一种小语言,现在是世界上最流行的语言。

JavaScript

有时很难将 JavaScript 与使用它的环境的特性区分开来。

例如,console.log()您可以在许多代码示例中找到的那行代码不是 JavaScript。相反,它是浏览器中提供给我们的庞大 API 库的一部分。

同样,在服务器上,有时很难将 JavaScript 语言功能与 Node.js 提供的 API 分开。

React 或 Vue 是否提供特定功能?还是通常所说的“普通 JavaScript”?

在本手册中,我将讨论 JavaScript 这种语言。

不会因外部生态系统提供的事物而使您的学习过程复杂化。

JavaScript 语法简介

在这个简短的介绍中,我想告诉大家 5 个概念:

  • 空白
  • 区分大小写
  • 文字
  • 身份标识
  • 注释

空白空间

JavaScript 不认为空白是有意义的。至少在理论上,可以以您可能喜欢的任何方式添加空格和换行符。

在实践中,您很可能会保持明确定义的样式并遵守人们常用的样式,并使用 linter 或Prettier等样式工具强制执行此操作。

例如,我总是为每个缩进使用 2 个空格字符。

区分大小写

JavaScript 区分大小写。一个名为something的变量不同于Something.

其它标识符也是如此。

字面量

我们将字面量定义为在源代码中写入的值,例如,数字、字符串、布尔值或更高级的构造,如 Object 字面量 或 Array 字面量:

5
'Test'
true
['a', 'b']
{color: 'red', shape: 'Rectangle'}

标识符

标识符是可用于标识变量、函数或对象的字符序列。它可以以字母、美元符号$或下划线开头_,并且可以包含数字。使用 Unicode,字母可以是任何允许的字符,例如,表情符号 ?。

Test
test
TEST
_test
Test1
$test

美元符号通常用于引用 DOM 元素。

有些名称是为 JavaScript 内部使用而保留的关键字,我们不能将它们用作标识符。

注释

注释是任何编程语言中最重要的部分之一。它们很重要,因为它们让我们可以注释代码并添加重要信息,否则其他人(或我们自己)阅读代码时无法获得这些信息。

在 JavaScript 中,我们可以使用//进行注释. JavaScript 解释器不会将//之后的所有内容视为代码。

像这样:

// a comment
true //another comment

另一种类型的注释是多行注释。它以 /*开头和*/结尾。

两者之间的所有内容均被认为注释:

/* some kind
of 
comment 

*/

分号

JavaScript 程序中的每一行都可选地使用分号终止。

我说可选,因为 JavaScript 解释器足够聪明,可以为您引入分号。

在大多数情况下,您可以在程序中完全省略分号,甚至无需考虑它。

这个事实是非常有争议的。一些开发人员将始终使用分号,而另一些开发人员则从不使用分号,并且您总是会发现使用分号的代码和不使用分号的代码。

我个人的偏好是避免使用分号,所以我在书中的示例不会包含它们。

值类型

字符串hello是一个。像一个数字12是一个

hello和12是值。string 和 number是这些值的类型

类型是值的种类,它的类别。JavaScript 中有许多不同的类型,稍后我们将详细讨论它们。每种类型都有自己的特点。

当我们需要一个值的引用时,我们将它分配给一个变量。变量可以有一个名称,而值是存储在变量中的内容,因此我们稍后可以通过变量名称访问该值。

变量

变量是分配给标识符的值,因此您可以稍后在程序中引用和使用它。

这是因为 JavaScript 是弱类型的,这是您经常听到的概念。

必须先声明变量,然后才能使用它。

我们有两种主要的方式来声明变量。首先是使用const

const a = 0

第二种方法是使用let

let a = 0

有什么不同?

const定义对值的常量引用。这意味着不能更改引用。不能为其重新分配新值。

使用letp声明的变量可以为其分配一个新值。

例如,不能这样做:

const a = 0
a = 1

因为会得到一个错误:TypeError: Assignment to constant variable..

另一方面,可以使用letp声明变量:

let a = 0
a = 1

const并不像 C 等其他语言那样表示“常量”。特别是,这并不意味着该值不能改变 - 这意味着它不能被重新分配。如果变量指向一个对象或数组(我们稍后会看到更多关于对象和数组的内容),那么对象或数组的内容可以自由改变。

const变量必须在声明时初始化:

const a = 0

let值可以稍后初始化:

let a
a = 0

可以在同一语句中一次声明多个变量:

const a = 1, b = 2
let c = 1, d = 2

但是不能多次重新声明同一个变量:

let a = 1
let a = 2

否则会收到“重复声明”错误。

我的建议是始终使用const声明产量,仅在您知道需要为该变量重新分配值时使用let。为什么?因为我们的代码的功能越少越好。如果我们知道一个值不能被重新分配,那么它就少了一个错误来源。

既然我们已经了解了如何使用constlet,我想提一下var

直到 2015 年,var这是我们在 JavaScript 中声明变量的唯一方法。今天,现代代码库很可能只使用constletp声明变量。我在这篇文章中详细介绍了一些基本差异,但如果你刚刚开始学习JavaScript ,可能不会关心它们。只需使用constletp声明变量即可。

类型

JavaScript 中的变量没有附加任何类型。

它们是无类型的。

将具有某种类型的值分配给变量后,可以稍后重新分配该变量以承载任何其他类型的值,而不会出现任何问题。

在 JavaScript 中,我们有 2 种主要类型:原始类型对象类型

原始类型

原始类型是

  • 数字
  • 字符串
  • 布尔值
  • 符号

还有两种特殊类型:nullundefined

对象类型

任何不是原始类型(字符串、数字、布尔值、null 或未定义)的值都是对象

对象类型有属性,也有可以作用于这些属性的方法。

稍后我们将更多地讨论对象。

表达式

表达式是 JavaScript 引擎可以评估并返回值的单个 JavaScript 代码单元。

表达式的复杂性可能会有所不同。

我们从非常简单的开始,称为初级表达式:

2
0.02
'something'
true
false
this //the current scope
undefined
i //where i is a variable or a constant

算术表达式是接受一个变量和一个运算符的表达式(稍后将详细介绍运算符),并产生一个数字:

1 / 2
i++
i -= 2
i * 2

字符串表达式是产生字符串的表达式:

'A ' + 'string'

逻辑表达式使用逻辑运算符并解析为布尔值:

a && b
a || b
!a

更高级的表达式涉及对象、函数和数组,我稍后会介绍它们。

运算符

运算符允许获得两个简单的表达式并将它们组合成一个更复杂的表达式。

我们可以根据它们使用的操作数对运算符进行分类。一些运算符使用 1 个操作数。大多数使用 2 个操作数。只有一个运算符可以处理 3 个操作数。

在对运算符的第一次介绍中,我们将介绍您最可能熟悉的运算符:具有 2 个操作数的运算符。

我在谈论变量时已经介绍了一个:赋值运算符=。您用=为变量赋值:

let b = 2

现在让我们介绍另一组在基础数学中已经熟悉的二元运算符。

加法运算符 (+)

const three = 1 + 2
const four = three + 1

如果使用字符串,+运算符也会进行字符串连接,因此请注意:

const three = 1 + 2
three + 1 // 4
'three' + 1 // three1

减法运算符 (-)

const two = 4 - 2

除法运算符 (/)

返回第一个运算符和第二个运算符的商:

const result = 20 / 5 //result === 4
const result = 20 / 7 //result === 2.857142857142857

如果除以零,JavaScript 不会引发任何错误,但会返回该Infinity值(或者-Infinity如果该值为负数)。

1 / 0 //Infinity
-1 / 0 //-Infinity

余数运算符 (%)

在许多用例中,余数是非常有用的计算:

const result = 20 % 5 //result === 0
const result = 20 % 7 //result === 6

NaN余数总是为零,这是一个表示“非数字”的特殊值:

1 % 0 //NaN
-1 % 0 //NaN

乘法运算符 (*)

将两个数字相乘

1 * 2 //2
-1 * 2 //-2

幂运算符 (**)

将第一个操作数提高到第二个操作数的幂

1 ** 2 //1
2 ** 1 //2
2 ** 2 //4
2 ** 8 //256
8 ** 2 //64

优先规则

在同一行中包含多个运算符的每个复杂语句都会引入优先级问题。

举个例子:

let a = 1 * 2 + 5 / 2 % 2

结果是 2.5,但为什么呢?

哪些操作先执行,哪些需要等待?

某些操作比其他操作具有更高的优先级。下表列出了优先规则:

操作员

描述

同一级别的操作(如+-)按照它们被发现的顺序从左到右执行。

按照这些规则,上面的操作可以这样解决:

let a = 1 * 2 + 5 / 2 % 2
let a = 2 + 5 / 2 % 2
let a = 2 + 2.5 % 2
let a = 2 + 0.5
let a = 2.5

比较运算符

在赋值和数学运算符之后,我要介绍的第三组运算符是条件运算符。

可以使用以下运算符来比较两个数字或两个字符串。

比较运算符总是返回一个布尔值,即truefalse)。

这些是不等式比较运算符

  • <意思是“小于”
  • <=意思是“小于或等于”
  • >意思是“大于”
  • >=意思是“大于或等于”

例子:

let a = 2
a >= 1 //true

除此之外,我们还有 4 个相等运算符。它们接受两个值,并返回一个布尔值:

  • ===检查相等性
  • !==检查不平等

请注意,我们在 JavaScript 中也有==!=,但我强烈建议只使用===和!==,因为它们可以防止一些微妙的问题。

条件语句

有了比较运算符,我们就可以讨论条件语句了。

if语句用于使程序根据表达式求值的结果选择一条路径或另一条路径。

这是最简单的例子,它总是执行:

if (true) {
  //do something
}

相反,这将永远不会执行:

if (false) {
  //do something (? never ?)
}

条件检查传递给它的表达式的真值或假值。如果传递一个数字,除非它是 0,否则它总是计算为真。如果传递一个字符串,它总是计算为真,除非它是一个空字符串。这些是将类型转换为布尔值的一般规则。

注意到花括号了吗?这称为,它用于对不同语句的列表进行分组。

块可以放在任何可以有单个语句的地方。如果在条件句之后有一条语句要执行,可以省略该块,只写语句:

if (true) doSomething()

但我总是喜欢用花括号,这样的语句更清楚。

else可以为if语句提供第二部分。

if如果条件为假,则附加将要执行的语句:

if (true) {
  //do something
} else {
  //do something else
}

由于else接受一个语句,可以在其中嵌套另一个 if/else 语句:

if (a === true) {
  //do something
} else if (b === true) {
  //do something else
} else {
  //fallback
}

数组

数组是元素的集合。

JavaScript 中的数组本身并不是一种类型

数组是对象

我们可以通过以下两种不同的方式初始化一个空数组:

const a = []
const a = Array()

第一种是使用数组文字语法。第二个使用 Array 内置函数。

您可以使用以下语法预填充数组:

const a = [1, 2, 3]
const a = Array.of(1, 2, 3)

数组可以保存任何值,甚至是不同类型的值:

const a = [1, 'Flavio', ['a', 'b']]

由于我们可以将数组添加到数组中,因此我们可以创建多维数组,这些数组有非常有用的应用(例如矩阵):

const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

matrix[0][0] //1
matrix[2][0] //7

可以通过引用从零开始的索引来访问数组的任何元素:

a[0] //1
a[1] //2
a[2] //3

可以使用以下语法使用一组值初始化一个新数组,该语法首先初始化一个由 12 个元素组成的数组,并用数字0填充每个元素:

Array(12).fill(0)

可以通过检查其length属性来获取数组中元素的数量:

const a = [1, 2, 3]
a.length //3

请注意,可以设置数组的长度。如果分配的数字大于阵列当前容量,则不会发生任何事情。如果分配较小的数字,则在该位置切割数组:

const a = [1, 2, 3]
a //[ 1, 2, 3 ]
a.length = 2
a //[ 1, 2 ]

如何将项目添加到数组

我们可以使用push()方法在数组末尾添加一个元素:

a.push(4)

我们可以使用unshift()方法在数组的开头添加一个元素:

a.unshift(0)
a.unshift(-2, -1)

如何从数组中删除一个项目

我们可以使用pop()方法从数组末尾删除一个项目:

a.pop()

我们可以使用shift()方法从数组的开头删除一个项目:

a.shift()

如何连接两个或多个数组

可以使用concat()方法连接多个数组:

const a = [1, 2]
const b = [3, 4]
const c = a.concat(b) //[1,2,3,4]
a //[1,2]
b //[3,4]

还可以通过使用扩展运算符 ( ...):

const a = [1, 2]
const b = [3, 4]
const c = [...a, ...b]
c //[1,2,3,4]

如何在数组中查找特定项

可以使用数组的find()方法:

a.find((element, index, array) => {
  //return true or false
})

返回第一个返回 true 的项目,如果未找到该元素则返回undefined

一个常用的语法是:

a.find(x => x.id === my_id)

上面的行将返回数组中id === my_id的第一个元素。

findIndex()find()类似,但返回第一个为true 的项目的索引,如果未找到,则返回undefined

a.findIndex((element, index, array) => {
  //return true or false
})

另一种方法是includes()

a.includes(value)

a如果包含则返回真value

a.includes(value, i)

如果在 position 之后包含value,则返回 true 。

字符串

字符串是一个字符序列。

它也可以定义为字符串文字,用引号或双引号括起来:

'A string'
"Another string"

我个人一直更喜欢单引号,只在 HTML 中使用双引号来定义属性。

将字符串值分配给如下变量:

const name = 'Flavio'

length可以使用它的属性来确定字符串的长度:

'Flavio'.length //6
const name = 'Flavio'
name.length //6

''这是一个空字符串. 它的长度属性为 0:

''.length //0

可以使用+运算符连接两个字符串:

"A " + "string"

可以使用+运算符来插入变量:

const name = 'Flavio'
"My name is " + name //My name is Flavio

定义字符串的另一种方法是使用在反引号内定义的模板文字。它们对于使多行字符串更简单特别有用。使用单引号或双引号,您无法轻松定义多行字符串 - 您需要使用转义字符。

使用反引号打开模板文字后,只需按 Enter 键即可创建一个新行,没有特殊字符,并且按原样呈现:

const string = `Hey
this

string
is awesome!`

模板文字也很棒,因为它们提供了一种将变量和表达式插入字符串的简单方法。

您可以使用以下${...}语法来执行此操作:

const var = 'test'
const string = `something ${var}` 
//something test

${}里面可以添加任何东西,甚至是表达式:

const string = `something ${1 + 2 + 3}`
const string2 = `something 
  ${foo() ? 'x' : 'y'}`

循环

循环是 JavaScript 的主要控制结构之一。

使用循环,我们可以自动化并重复一段代码,无论我们希望它运行多少次,甚至无限期地运行。

JavaScript 提供了许多迭代循环的方法。

我想专注于3种方式:

  • while 循环
  • for 循环
  • for..of 循环

while

while 循环是 JavaScript 提供给我们的最简单的循环结构。

我们在关键字之后添加一个条件while,并提供一个运行块,直到条件评估为true

例子:

const list = ['a', 'b', 'c']
let i = 0
while (i < list.length) {
  console.log(list[i]) //value
  console.log(i) //index
  i = i + 1
}

您可以使用关键字中断while循环,如下所示:break

while (true) {
  if (somethingIsTrue) break
}

如果您决定在循环中间跳过当前迭代,则可以使用以下命令跳转到下一个迭代continue

while (true) {
  if (somethingIsTrue) continue

  //do something else
}

非常类似于while,我们有do..while循环。它与 基本相同while,只是在执行代码块之后评估条件。

这意味着块总是至少执行一次

例子:

const list = ['a', 'b', 'c']
let i = 0
do {
  console.log(list[i]) //value
  console.log(i) //index
  i = i + 1
} while (i < list.length)

for

JavaScript 中第二个非常重要的循环结构是for 循环

我们使用for关键字并传递一组 3 条指令:初始化、条件和增量部分。

例子:

const list = ['a', 'b', 'c']

for (let i = 0; i < list.length; i++) {
  console.log(list[i]) //value
  console.log(i) //index
}

就像while循环一样,您可以使用 中断for循环,并且可以使用 快进到循环break的下一次迭代。forcontinue

for...of

这个循环是相对较新的(2015 年引入),它是for循环的简化版本:

const list = ['a', 'b', 'c']

for (const value of list) {
  console.log(value) //value
}

函数

在任何中等复杂的 JavaScript 程序中,一切都发生在函数内部。

函数是 JavaScript 的核心,必不可少的部分。

什么是函数?

函数是一个自包含的代码块。

这是一个函数声明

function getData() {
  // do something
}

一个函数可以通过调用它随时运行,如下所示:

getData()

一个函数可以有一个或多个参数:

function getData() {
  //do something
}

function getData(color) {
  //do something
}

function getData(color, age) {
  //do something
}

当我们可以传递参数时,我们调用传递参数的函数:

function getData(color, age) {
  //do something
}

getData('green', 24)
getData('black')

请注意,在第二次调用中,我将black字符串参数作为color参数传递,但没有传递age. 在这种情况下,age函数内部是undefined.

我们可以使用以下条件检查值是否未定义:

function getData(color, age) {
  //do something
  if (typeof age !== 'undefined') {
    //...
  }
}

typeof是一个一元运算符,它允许我们检查变量的类型。

您也可以通过以下方式检查:

function getData(color, age) {
  //do something
  if (age) {
    //...
  }
}

虽然如果ageis或空字符串null,条件也将为真。0

您可以为参数设置默认值,以防它们未传递:

function getData(color = 'black', age = 25) {
  //do something
}

您可以将任何值作为参数传递:数字、字符串、布尔值、数组、对象以及函数。

一个函数有一个返回值。默认情况下,函数返回undefined,除非您添加return带有值的关键字:

function getData() {
  // do something
  return 'hi!'
}

我们可以在调用函数时将此返回值分配给变量:

function getData() {
  // do something
  return 'hi!'
}

let result = getData()

result现在保存一个带有hi!值的字符串。

您只能返回一个值。

要返回多个值,您可以返回一个对象或数组,如下所示:

function getData() {
  return ['Flavio', 37]
}

let [name, age] = getData()

函数可以在其他函数中定义:

const getData = () => {
  const dosomething = () => {}
  dosomething()
  return 'test'
}

嵌套函数不能从封闭函数的外部调用。

你也可以从一个函数中返回一个函数。

箭头函数

箭头函数是最近对 JavaScript 的介绍。

它们经常被用来代替我在前一章中描述的“常规”函数。您会发现这两种形式随处可见。

从视觉上看,它们允许您使用更短的语法编写函数,来自:

function getData() {
  //...
}

() => {
  //...
}

但是..注意我们这里没有名字。

箭头函数是匿名的。我们必须将它们分配给一个变量。

我们可以将常规函数分配给变量,如下所示:

let getData = function getData() {
  //...
}

当我们这样做时,我们可以从函数中删除名称:

let getData = function() {
  //...
}

并使用变量名调用函数:

let getData = function() {
  //...
}
getData()

这与我们对箭头函数所做的事情相同:

let getData = () => {
  //...
}
getData()

如果函数体只包含一条语句,则可以省略括号并将所有内容写在一行上:

const getData = () => console.log('hi!')

参数在括号中传递:

const getData = (param1, param2) => 
  console.log(param1, param2)

如果您有一个(并且只有一个)参数,则可以完全省略括号:

const getData = param => console.log(param)

箭头函数允许您有一个隐式返回 - 无需使用return关键字即可返回值。

它在函数体中有一行语句时起作用:

const getData = () => 'test'

getData() //'test'

与常规函数一样,我们可以为参数设置默认值,以防它们未传递:

const getData = (color = 'black', 
                 age = 2) => {
  //do something
}

和常规函数一样,我们只能返回一个值。

箭头函数还可以包含其他箭头函数,甚至是常规函数。

这两种函数非常相似,所以你可能会问为什么要引入箭头函数。与常规函数的最大区别在于它们用作对象方法时。这是我们将很快研究的事情。

对象

任何不是原始类型(字符串、数字、布尔值、符号、null 或未定义)的值都是对象

下面是我们定义对象的方式:

const car = {

}

这是对象字面量语法,它是 JavaScript 中最好的东西之一。

您还可以使用以下new Object语法:

const car = new Object()

另一种语法是使用Object.create()

const car = Object.create()

new您还可以在带有大写字母的函数之前使用关键字初始化对象。此函数用作该对象的构造函数。在那里,我们可以初始化我们作为参数接收的参数,以设置对象的初始状态:

function Car(brand, model) {
  this.brand = brand
  this.model = model
}

我们使用以下方法初始化一个新对象:

const myCar = new Car('Ford', 'Fiesta')
myCar.brand //'Ford'
myCar.model //'Fiesta'

对象总是通过引用传递

如果您为一个变量分配与另一个变量相同的值,如果它是像数字或字符串这样的原始类型,则它们是按值传递的:

举个例子:

let age = 36
let myAge = age
myAge = 37
age //36
const car = {
  color: 'blue'
}
const anotherCar = car
anotherCar.color = 'yellow'
car.color //'yellow'

即使是数组或函数,在底层也是对象,因此了解它们的工作原理非常重要。

对象属性

对象具有属性,这些属性由与值关联的标签组成。

属性的值可以是任何类型,这意味着它可以是数组、函数,甚至可以是对象,因为对象可以嵌套其他对象。

这是我们在上一章看到的对象字面量语法:

const car = {

}

我们可以color这样定义一个属性:

const car = {
  color: 'blue'
}

在这里,我们有一个car对象,其属性名为color,其值为blue

标签可以是任何字符串,但要注意特殊字符 - 如果我想在属性名称中包含一个无效的字符作为变量名,我将不得不在它周围使用引号:

const car = {
  color: 'blue',
  'the color': 'blue'
}

无效的变量名字符包括空格、连字符和其他特殊字符。

如您所见,当我们有多个属性时,我们用逗号分隔每个属性。

我们可以使用 2 种不同的语法来检索属性的值。

第一个是点符号

car.color //'blue'

第二个(这是我们唯一可以用于名称无效的属性)是使用方括号:

car['the color'] //'blue'

如果您访问不存在的属性,您将获得以下undefined值:

car.brand //undefined

如前所述,对象可以具有嵌套对象作为属性:

const car = {
  brand: {
    name: 'Ford'
  },
  color: 'blue'
}

在此示例中,您可以使用访问品牌名称

car.brand.name

或者

car['brand']['name']

您可以在定义对象时设置属性的值。

但是您以后可以随时更新它:

const car = {
  color: 'blue'
}

car.color = 'yellow'
car['color'] = 'red'

您还可以向对象添加新属性:

car.model = 'Fiesta'

car.model //'Fiesta'

给定对象

const car = {
  color: 'blue',
  brand: 'Ford'
}

您可以使用从该对象中删除一个属性

delete car.brand

对象方法

我在前一章中谈到了函数。

可以将函数分配给函数属性,在这种情况下,它们称为方法

在这个例子中,start属性分配了一个函数,我们可以使用我们用于属性的点语法来调用它,括号在末尾:

const car = {
  brand: 'Ford',
  model: 'Fiesta',
  start: function() {
    console.log('Started')
  }
}

car.start()

在使用function() {}语法定义的方法中,我们可以通过引用来访问对象实例this

在以下示例中,我们可以使用and访问brandmodel属性值:this.brandthis.model

const car = {
  brand: 'Ford',
  model: 'Fiesta',
  start: function() {
    console.log(`Started 
      ${this.brand} ${this.model}`)
  }
}

car.start()

重要的是要注意常规函数和箭头函数之间的这种区别——this如果我们使用箭头函数,我们就无法访问:

const car = {
  brand: 'Ford',
  model: 'Fiesta',
  start: () => {
    console.log(`Started 
      ${this.brand} ${this.model}`) //not going to work
  }
}

car.start()

这是因为箭头函数没有绑定到对象

这就是为什么经常将常规函数用作对象方法的原因。

方法可以接受参数,如常规函数:

const car = {
  brand: 'Ford',
  model: 'Fiesta',
  goTo: function(destination) {
    console.log(`Going to ${destination}`)
  }
}

car.goTo('Rome')

我们讨论了对象,这是 JavaScript 中最有趣的部分之一。

在本章中,我们将通过介绍类来提升一个层次。

什么是类?它们是一种为多个对象定义通用模式的方法。

让我们看一个人对象:

const person = {
  name: 'Flavio'
}

我们可以创建一个名为Person(注意大写P,使用类时的约定)的类,它有一个name属性:

class Person {
  name
}

现在从这个类中,我们像这样初始化一个flavio对象:

const flavio = new Person()

flavio称为 Person 类的实例

我们可以设置name属性的值:

flavio.name = 'Flavio'

我们可以使用

flavio.name

就像我们对对象属性所做的那样。

类可以保存属性,例如name和方法。

方法是这样定义的:

class Person {
  hello() {
    return 'Hello, I am Flavio'
  }
}

我们可以在类的实例上调用方法:

class Person {
  hello() {
    return 'Hello, I am Flavio'
  }
}
const flavio = new Person()
flavio.hello()

当我们创建一个新的对象实例时,我们可以使用一个特殊的方法 constructor()来初始化类属性。

它是这样工作的:

class Person {
  constructor(name) {
    this.name = name
  }

  hello() {
    return 'Hello, I am ' + this.name + '.'
  }
}

注意我们如何使用this来访问对象实例。

现在我们可以从类中实例化一个新对象,传入一个字符串,当我们调用时,hello我们会得到一条个性化的消息:

const flavio = new Person('flavio')
flavio.hello() //'Hello, I am flavio.'

初始化对象时,将constructor使用传递的任何参数调用该方法。

通常方法是在对象实例上定义的,而不是在类上。

可以定义一个 static 方法以允许它在类上执行:

class Person {
  static genericHello() {
    return 'Hello'
  }
}

Person.genericHello() //Hello

这有时非常有用。

继承

一个类可以扩展另一个类,使用该类初始化的对象继承这两个类的所有方法。

假设我们有一个类Person

class Person {
  hello() {
    return 'Hello, I am a Person'
  }
}

我们可以定义一个新类,Programmer扩展Person

class Programmer extends Person {

}

现在,如果我们用 class 实例化一个新对象Programmer,它就可以访问该hello()方法:

const flavio = new Programmer()
flavio.hello() //'你好, 我是一个人。'

在子类中,可以通过调用 super() 来引用父类方法:

class Programmer extends Person {
  hello() {
    return super.hello() + 
      '我也是一名程序员。'
  }
}

const flavio = new Programmer()
flavio.hello()

上面的程序打印你好,我是一个人。我也是一名程序员。

异步编程和回调

大多数时候,JavaScript 代码是同步运行的。

这意味着执行一行代码,然后执行下一个代码,以此类推。

一切都如您所愿,这是它在大多数编程语言中的工作方式。

但是,有时不能只等待一行代码执行。

不能只等待 2 秒钟来加载一个大文件,然后完全停止程序。

不能只等待下载网络资源后再做其他事情。

JavaScript 通过使用回调解决了这个问题。

如何使用回调的最简单示例之一是使用计时器。计时器不是 JavaScript 的一部分,但它们由浏览器和 Node.js 提供。让我谈谈我们拥有的一个计时器:setTimeout()函数。

setTimeout()函数接受 2 个参数:一个函数和一个数字。该数字是在函数运行之前必须经过的毫秒数。

例子:

setTimeout(() => {
  // 2秒以后执行
  console.log('inside the function')
}, 2000)

包含该console.log('inside the function')行的函数将在 2 秒后执行。

如果在函数之前添加一个 console.log('before') 日志,函数之后添加一个console.log('after')日志:

console.log('before')
setTimeout(() => {
  // runs after 2 seconds
  console.log('inside the function')
}, 2000)
console.log('after')

将在控制台中看到这种情况:

before
after
inside the function

回调函数是异步执行的。

当在浏览器中使用文件系统、网络、事件或 DOM 时,这是一种非常常见的模式。

我提到的所有东西都不是“核心”JavaScript,因此本手册中没有解释它们,但会在https://flaviocopes.com上的其他手册中找到很多示例。

以下是我们如何在代码中实现回调。

我们定义一个接受callback参数的函数,它是一个函数。

当代码准备好调用回调时,我们通过传递结果来调用它:

const doSomething = callback => {
  //do things
  //do things
  const result = /* .. */
  callback(result)
}

使用此函数的代码将像这样使用它:

doSomething(result => {
  console.log(result)
})

Promise

Promise 是处理异步代码的另一种方法。

正如我们在前一章中看到的,通过回调我们将一个函数传递给另一个函数调用,该函数将在函数完成处理时调用。

像这样:

doSomething(result => {
  console.log(result)
})

doSomething()代码结束时,它调用作为参数接收的函数:

const doSomething = callback => {
  //do things
  //do things
  const result = /* .. */
  callback(result)
}

这种方法的主要问题是,如果我们需要在其余代码中使用这个函数的结果,我们所有的代码都必须嵌套在回调中,如果我们必须进行 2-3 次回调,我们输入的是通常定义“回调地狱”,将许多级别的函数缩进到其他函数中:

doSomething(result => {
  doSomethingElse(anotherResult => {
    doSomethingElseAgain(yetAnotherResult => {
      console.log(result)
    })
  }) 
})

Promise 是处理这个问题的一种方法。

而不是这样做:

doSomething(result => {
  console.log(result)
})

我们以这种方式调用基于 Promise 的函数:

doSomething()
  .then(result => {
    console.log(result)
  })

我们首先调用函数,然后我们有一个在函数结束时调用的then()方法。

缩进无关紧要,但为了清晰起见,通常会使用这种样式。

使用以下catch()方法检测错误很常见:

doSomething()
  .then(result => {
    console.log(result)
  })
  .catch(error => {
    console.log(error)
  })

现在,为了能够使用这种语法,doSomething()函数实现必须有点特殊。它必须使用 Promises API。

而不是将其声明为普通函数:

const doSomething = () => {
  
}

我们将它声明为一个 Promise 对象:

const doSomething = new Promise()

我们在 Promise 构造函数中传递一个函数:

const doSomething = new Promise(() => {

})

该函数接收 2 个参数。第一个是我们调用来解析Promise 的函数,第二个是我们调用来拒绝 Promise 的函数。

const doSomething = new Promise(
  (resolve, reject) => {
    
})

解决一个 Promise 意味着成功完成它(这导致then()在任何使用它的地方调用该方法)。

拒绝一个 Promise 味着以一个错误结束它(这导致catch()在任何使用它的地方调用该方法)。

就是这样:

const doSomething = new Promise(
  (resolve, reject) => {
    //some code
    const success = /* ... */
    if (success) {
      resolve('ok')
    } else {
      reject('this error occurred')
    }
  }
)

我们可以将参数传递给我们想要的任何类型的解析和拒绝函数。

异步和等待

异步函数是 Promise 的更高层次的抽象。

一个异步函数返回一个 Promise,如下例所示:

const getData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => 
      resolve('some data'), 2000)
  })
}

任何想要使用此函数的代码都将在函数之前使用 await 关键字:

const data = await getData()

这样做,Promise返回的任何数据都将被分配给data变量。

在我们的例子中,数据是“一些数据”字符串。

有一个特别的警告:每当我们使用await关键字时,我们必须在定义为 async 的函数中这样做。

像这样:

const doSomething = async () => {
  const data = await getData()
  console.log(data)
}

async/await 让我们拥有更简洁的代码和简单的思维模型来处理异步代码。

正如在上面的示例中看到的,我们的代码看起来非常简单。将其与使用Promise或回调函数的代码进行比较。

这是一个非常简单的例子,当代码复杂得多时,主要的好处就会出现。

例如,以下是使用 Fetch API 获取 JSON 资源并使用 Promise 解析它的方法:

const getFirstUserData = () => {
  // get users list
  return fetch('/users.json') 
    // parse JSON
    .then(response => response.json()) 
    // pick first user
    .then(users => users[0]) 
    // get user data
    .then(user => 
      fetch(`/users/${user.name}`)) 
    // parse JSON
    .then(userResponse => response.json()) 
}

getFirstUserData()

这是使用 await/async 提供的相同功能:

const getFirstUserData = async () => {
  // get users list
  const response = await fetch('/users.json') 
  // parse JSON
  const users = await response.json() 
  // pick first user
  const user = users[0] 
  // get user data
  const userResponse = 
    await fetch(`/users/${user.name}`)
  // parse JSON
  const userData = await user.json() 
  return userData
}

getFirstUserData()

变量范围

当我介绍变量时,我谈到了使用constletvar

范围是对程序的一部分可见的变量集。

在 JavaScript 中,我们有全局作用域、块作用域和函数作用域。

如果变量是在函数或块之外定义的,它会附加到全局对象并且它具有全局范围,这意味着它可以在程序的每个部分中使用。

let 、const 和var声明变量之间有一个非常重要的区别。

在函数内部定义的变量var仅在该函数内部可见,类似于函数的参数。

另一方面,定义为const或 let 的变量仅在定义它的内可见。

块是组合成一对花括号的一组指令,就像我们可以在if语句、for循环或函数中找到的指令一样。

重要的是要理解一个块没有为 定义一个新的范围var,但它为let和 const 定义了一个新的范围。

这具有非常实际的意义。

假设在函数的 if 条件内定义了一个 var 变量

function getData() {
  if (true) {
    var data = 'some data'
    console.log(data) 
  }
}

如果调用此函数,ome data打印到控制台。

如果尝试将 console.log(data) 移动到if语句之后,它仍然有效:

function getData() {
  if (true) {
    var data = 'some data'
  }
  console.log(data) 
}

但是如果切换var datalet data

function getData() {
  if (true) {
    let data = 'some data'
  }
  console.log(data) 
}

会得到一个错误:ReferenceError: data is not defined

这是因为var是函数作用域,这里发生了一种特殊的事情,称为提升。简而言之,JavaScript 在运行代码之前将声明var移动到最近的函数的顶部。这或多或少是这个函数在 JS 内部的样子:

function getData() {
  var data
  if (true) {
    data = 'some data'
  }
  console.log(data) 
}

这就是为什么也可以console.log(data)在函数的顶部,甚至在它被声明之前,会得到undefined该变量的值:

function getData() {
  console.log(data) 
  if (true) {
    var data = 'some data'
  }
}

但是如果切换到let,会得到一个错误ReferenceError: data is not defined,因为 let 声明不会发生提升。

const和let 遵循相同的规则:它们是块范围的。

一开始可能会很棘手,但一旦你意识到这种差异,你就会明白为什么var现在被认为是一种不好的做法——它们的活动部件更少,而且它们的范围仅限于块,这也使它们非常好作为循环变量,因为它们在循环结束后不再存在:

function doLoop() {
  for (var i = 0; i < 10; i++) {
    console.log(i)
  }
  console.log(i)
}

doLoop()

当您退出循环时,i将是一个值为 10 的有效变量。

如果切换到let,当你尝试切换到时console.log(i)会导致错误ReferenceError: i is not defined

结论

非常感谢您阅读完本手册。

我希望它能激发您更多地了解 JavaScript。


用html标签使用介绍

本文主要记录常用的html标签使用说明,用起来的时候偶尔查查。

常用html标签列表

标签

英文全拼

作用

特点

​<html></html>​

html

网页的根标签

所有的标签都要写在这一对根标签里面

​<head></head>​

head

网页的头标签

包括完档的属性和信息

​<body></body>​

body

网页的主题

包含文档的所有内容

​<div></div>​

division

定义一个区域

浏览器通常会在​​<div>​​前后放置一个换行符

​<!-- 注释 -->​

-

注释

单标签

​<br>或<br/>​

break

换行

单标签,不会在其前后创建空白行

​<hr>或<hr/>​

horizontal rule

添加水平线

单标签

​<img src="">​

image

添加图片

单标签

​<embed src="">​

embed

嵌入外部应用

单标签

​<meta>​

meta

提供有关页面的元信息

单标签,​​<meta>​​​标签通常位于​​<head>​​区域内

​<link>​

link

定义文档与外部资源的关系

单标签,​​<link>​​​标签只能存在于​​<head>​​区域内,不过它可出现任何次数。

​<p></p>​

paragraph

定义段落

自动在其前后创建空白行

​<h1> to <h6>​

Header 1 to Header 6

定义标题

h1在一个页面里只能出现一次

​<strong></strong>​

strong

文本加粗

加粗标记该文本

​<b></b>​

bold

文本加粗

加粗显示文本,不推荐使用

​<em></em>​

emphasize

文本倾斜

倾斜标记文本

​<i></i>​

italic

文本倾斜

倾斜显示文本,不推荐使用

​<del></del>​

delete

文本添加删除线

-

​<s></s>​

strike

文本添加删除线

不推荐使用

​<ins></ins>​

insert

文本添加下划线

-

​<u></u>​

underline

文本添加下划线

不推荐使用

​<a href="">填写内容</a>​

anchor

添加超链接

最好使用CSS来改变链接的样式

​<ul></ul>​

unordered list

定义无序列表

通常与​​<li>​​标签一起使用

​<ol></ol>​

ordered list

定义有序列表

通常与​​<li>​​标签一起使用

​<li></li>​

list item

创建列表项

可与各种列表定义标签一起使用

​<dl></dl>​

definition list

定义描述列表

通常与​​<dt>​​​和​​<dd>​​一起使用

​<dt></dt>​

definition term

定义条目

定义描述列表的项目

​<dd></dd>​

definition description

定义描述

对描述列表中的项目进行描述

​<table></table>​

table

定义HTML表格

尽可能通过样式改变表格外观

​<tr></tr>​

table row

定义表格的行

一个​​<tr>​​​标签包含一个或多个​​<th>​​​或​​<td>​​标签

​<th></th>​

table headline

定义表格每一列的标题

该标签的文本通常呈现为粗体且居中

​<td></td>​

table data

定义表格中的单元格数据

该标签的文本呈现为普通且左对齐

​<caption>表格标题</caption>​

caption

定义整个表格的标题

​<caption>​​​标签必须直接放在​​<table>​​标签后

​<input type="">​

input

定义输入控件

输入字段可通过多种方式改变,取决于type属性

​select​

select

定义下拉列表

​<select>​​​中的​​<option>​​标签定义了列表中的可用选项

​<option></option>​

option

定义下拉列表中的可用项

​<option>​​标签不可自由定义宽高

​<optgroup></optgroup>​

options group

定义选项组

​<optgroup>​​标签用于把相关的选项组合在一起

​<textarea></textarea>​

textarea

定义多行的文本输入控件

文本的默认字体是等宽字体

​<form></form>​

form

定义表单

​<form>​​可以包含多个元素

​<fieldset></fieldset>​

field set

定义围绕表单中元素的边框

​<legend>​​​为​​<fieldset>​​定义标题

​<legend></legend>​

legend

为​​<fieldset>​​定义标题

​<legend>​​通过css设定样式

​<progress></progress>​

progress

定义运行中的任务进度

​<progress>​​​是HTML5中的新标签,​​<progress>​​标签不适合用来表示度量衡

​<meter></meter>​

meter

度量衡

​<meter>​​​是HTML5的新标签,​​<meter>​​标签不适合用来表示进度条

​<audio></audio>​

audio

添加音频

​<audio>​​标签是HTML5的新标签

​<video></video>​

video

添加视频

​<video>​​标签是HTML5的新标签

​<source>​

source

定义媒介资源

​<source>​​标签是HTML5中的新标签

常用标签使用说明

  • 常用写法:​​<img src="" alt="" title=""width="" height=""​​>
  • src:图片的来源(必写属性)
  • alt:图像不显示时的替代文本
  • title:鼠标在移动到元素上的文本提示
  • width/height:图片宽高,没有定义宽高的时候,图片按照百分之百比例显示,更改图片的宽度或者高度,图片等比例缩放

普通用法

  • 常用写法:​​<a href="" title="" target="">填写内容</a>​
  • href:去往的路径(必写属性)
  • title:鼠标在移动到元素上的文本提示
  • target:规定在何处打开路径
  • _blank:新页面打开
  • _parent:在父窗口中打开链接
  • _self:当前页面跳转(默认值)
  • _top:在当前窗体打开链接,并替换当前的整个窗体
  • 当href的值为javascript:void(0); 或 javascript:; ,表示超链接不做任何事情,不做任何跳转
  • 当href的值为#,表示超链接为空链接,点击此链接时会跳转到页首的位置

锚点链接

锚点链接通过点击超链接,自动跳转到我们设置锚点的位置,类似于word的目录导航。建立锚点的元素必须要有id或name属性,最好两个都有。这里只跳转本页面元素,其他页面跳转自行搜索。
具体做法如下:

  1. 给目标元素设置id值,如​​<p id="id1"></p>​
  2. 设置锚点超链接,锚点的超链接路径一定包含"#",后面紧跟元素的id或者name,如​​<a href="#id1"></a>​

示例如下。为了显示效果,通过使用lorem自动生成随机文本(具体使用方法搜索,一般直接输入就行),lorem*50表示重复lorem15次。

<a href="#id2">a</a>

  <p id="id1">
    (lorem*15)
  </p>

     (lorem*15)

  <p id="id2">
     (lorem*15)
  </p>

超链接全局设置

在页面head中写入代码可以设置超链接的全局跳转设置

<head>
  <!-- 让页面所有的超链接新页面打开 -->
  <base target="_blank">  
</head>

charset编码

  • 常用写法: ​​<meta charset="UTF-8">​
  • charset:定义文档的字符编码
  • ASCII/ANSI/Unicode:英语
  • GBK:亚洲通用字符集
  • GB2312:中文简体
  • Big5:台澳港繁体
  • UTF-8:世界通用字符集

name

  1. 关键字
  • 常用写法: ​​<meta name="keywords" content="">​
  • 描述:告诉搜索引擎网页的关键字,尽量将重要的关键词放在前面
  1. 网页描述
  • 常用写法: ​​<meta name="keywords" content="">​
  • 描述:告诉搜索引擎网页的主要内容
  1. 作者
  • 常用写法: ​​<meta name="author" content="">​
  • 描述:告诉搜索引擎网页的作者
  1. 文件检索
  • 常用写法: ​​<meta name="robots" content="all | none | index | noindex | follow | nofollow">​
  • 描述:有时候会有一些站点内容,不希望被ROBOTS抓取而公开。为了解决这个问题,ROBOTS开发界提供了两个办法:一个是robots.txt,另一个是The Robots META标签。
  • content: 文件检索方式
  • all:文件将被检索,且页面上的链接可以被查询 (默认值)
  • none:文件将不被检索,且页面上的链接不可以被查询
  • index:文件将被检索;
  • noindex:文件将不被检索,但页面上的链接可以被查询
  • follow:页面上的链接可以被查询
  • nofollow:文件将不被检索,页面上的链接可以被查询

网页自动跳转

  • 常用写法: ​​<meta http-equiv="Refresh" content="3;url=http://www.baidu.com" />​
  • 描述:网页5秒后自动跳转到谷歌主页
  • url:为空则刷新本页
  • 常用写法:
  • 描述:规定当前文档与被链接文档/资源之间的关系
  • rel:定义当前文档与被链接文档之间的关系。rel 是 relationship的英文缩写(必写属性)
  • type:规定被链接文档的类型
  • href:链接的文件路径
  • 示例:
  • 链接外部样式表:​​<link rel="stylesheet" type="text/css" href="a.css">​
  • 设置网页icon图标:​​<link rel="icon" href="a.ico">​

列表

无序列表

无序列表使用粗体圆点进行标记。简单示例如下。

<ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        ...
    </ul>

有序列表

有序列表使用数字进行标记,我们可以通过整数值start指定列表编号的起始值。简单示例如下。

<ol start="2">
        <li>a</li>
        <li>b</li>
        <li>c</li>
        ...
    </ol>

描述列表

通过描述列表自定义列表,列表项内部可以使用段落、换行符、图片、链接以及其他列表等等。简单示例如下。

<dl>
        <dt>A</dt> <!-- 小标题 -->
            <dd>A1</dd> <!-- 解释标题 -->
            <dd>A2</dd> <!-- 解释标题 -->
        <dt>B</dt> <!-- 小标题 -->
            <dd>B1</dd> <!-- 解释标题 -->
            <dd>B2</dd> <!-- 解释标题 -->
    </dl>

表格

基础表格

  • 常用写法:​​<table width="" height="" border="" cellspacing="" cellpadding=""></table>​
  • width:表格宽度
  • height:表格高度
  • border:边框宽度
  • cellspacing:单元格间距
  • cellpadding:内容与边框间距

简单示例如下。

<table width="300px" height="100px" border="2" cellspacing="5px" cellpadding="0">
<caption>表格标题</caption> <!-- 定义表格标题 -->

<tr>
    <!-- 定义表格的行 -->
    <td>A1</td> <!-- 定义表格该行第一列中的数据 -->
    <td>B1</td>
    <td>C1</td>
</tr>
<tr>
    <!-- 定义表格的行 -->
    <th>A</th> <!-- 定义表格每一列的标题 -->
    <th>B</th>
    <th>C</th>
</tr>
<tr>
    <td>A2</td>
    <td>B2</td>
    <td>C2</td>
</tr>
</table>

单元格合并

  • 常用写法:​​<td colspan=“” rowspan=“”></td>​
  • 描述:告诉表格该单元格可以横跨colspan列,纵跨rowspan行

简单示例如下。

<table border="2" cellspacing="1px" width="400px" height="100px">
<caption><strong>表格标题</strong></caption> <!-- 定义表格标题 -->
<tr height="100">
    <!-- 定义表格的行 -->
    <td colspan="2">A1</td> <!-- 定义该行可以横跨两列 -->
    <td>B1</td>
</tr>

<tr height="100">
    <td>A2</td>
    <td>B2</td>
    <td rowspan="2">C</td> <!-- 定义该行可以横跨两行 -->
</tr>

<tr height="100">
    <td>A3</td>
    <td>B3</td>
</tr>
</table>

对于​​<input>​​不同的type属性值,输入字段拥有很多种形式。输入字段可以是文本字段、复选框、掩码后的文本控件、单选按钮、按钮等等。

文本输入框

  • 常用写法:​​<input type="text" name="" maxlength="" readonly="" disabled="" value="">​
  • type:规定输入字段的类型
  • name:输入框的名字
  • maxlength:输入文本长度
  • readonly:输入框是否只读
  • disabled:输入框是否未激活
  • value:输入框默认值

简单示例如下。

<input type="text" name="username" maxlength="6" readonly="readonly" disabled="disabled" value="用户名">

密码输入框

  • 常用写法:​​<input type="password" name="">​
  • type:规定输入字段的类型
  • name:输入框的名字
  • 密码输入框的其他参数和文本输入框一样

简单示例如下。

<input type="password" name="pwd" maxlength="6" readonly="readonly" disabled="disabled" value="密码">

单选框

  • 常用写法:​​<input type="radio" name="" checked="checked">​
  • type:规定输入字段的类型
  • name:输入框的名字
  • checked:设定该输入框被预先选定
  • 想要多个单选框只能有一个被选中,设置所有单选框的name值相同即可实现

示例一,两个单选框都可以被选中

<div>
    <input type="radio" name="man" checked="checked">男
</div>
<div>
    <input type="radio" name="woman">女
</div>

示例二,两个单选框只能有一个被选中

<div>
    <input type="radio" name="gender" checked="checked">男
  </div>
  <div>
    <input type="radio" name="gender">女
  </div>

下拉列表

​<select>​

  • 常用写法:​​<select multiple=""></select>​
  • multiple:当该属性为true时,可选择多个选项。

​<optgroup>​

  • 常用写法:​​<optgroup label=""></optgroup>​
  • label:设定选项组的描述。

​<option>​

  • 常用写法:​​<option value="" selected="">选项值</option>​
  • value:定义送往服务器的选项值。
  • selected:当该属性为true时,该选项被默认选择。

示例一,单选下拉列表

<select>
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c" selected='selected'>c</option>  <!-- 默认选中 -->
  </select>

示例二,带组合的单选下拉列表

<select>
    <optgroup label="A">
      <option value="a1">a1</option>
      <option value="a2" selected='selected'>a2</option>
    </optgroup>
    <optgroup label="B">
      <option value="b1">b1</option>
      <option value="b2">b2</option>
    </optgroup>
  </select>

示例三,带组合的多选下拉列表

<select multiple=”multiple”>
    <optgroup label="A">
      <option value="a1">a1</option>
      <option value="a2" selected='selected'>a2</option>
    </optgroup>
    <optgroup label="B">
      <option value="b1" selected='selected'>b1</option>
      <option value="b2">b2</option>
    </optgroup>
  </select>

多选框

  • 常用写法:​​<input type="checkbox" checked="">​
  • type:规定输入字段的类型
  • checked:设定该输入框被预先选定

简单示例如下。

<input type="checkbox"  checked="checked">A
  <input type="checkbox">B

文本框

  • 常用写法:​​<textarea cols="" rows="" placeholder=""></textarea>​
  • cols:控制可见文本的列数
  • rows:控制可见文本的行数
  • placeholder:提示字符

简单示例如下。

<textarea cols="5" rows="2" placeholder="text"></textarea>

文本上传控件

  • 常用写法:​​<input type="file" accept=""/>​
  • accept:规定提交的文件的类型

简单示例如下。

<input type="file" accept="image/gif, image/jpeg"/>

其他类型按钮

<input type="submit">文件提交按钮
  <input type="button" value="">普通按钮
  <input type="image" src="">图片按钮
  <input type="reset">重置按钮
  <input type="url">网址控件
  <input type="date">日期控件 
  <input type="time">时间控件
  <!--email提供了邮箱的完整验证,必须包含@和后缀,如果不满足验证,会阻止表单提交-->
  <input type="email">邮件控件
  <input type="number" step="3">数字控件
  <input type="range" step="100">滑块控件
  <input type="color">颜色控件

表单

示例一,普通表单

<form>
    First name: <input type="text" name="fname"><br>
    Last name: <input type="text" name="lname"><br>
    <input type="submit" value="提交">
  </form>

示例二,带分组信息表单

<form>
    <fieldset>
      <legend>Personalia:</legend>
      First name: <input type="text" name="fname"><br>
      Last name: <input type="text" name="lname"><br>
      <input type="submit" value="提交">
    </fieldset>

    First nameA: <input type="text" name="fname"><br>
    Last nameB: <input type="text" name="lname"><br>
  </form>

​<progress>​​​与​​<meter>​​主要区别和用法见​​HTML5 progress和meter控件​​

​<progress>​

  • 常用写法:​​<progress value="" max=""></progress>​
  • value:规定进程的当前值
  • max:规定需要完成的值

简单示例如下。

<progress value="60" max="100"></progress>

​<meter>​

  • 常用写法:​​<meter min="" low="" high="" max="" value="" optimum=""></meter>​
  • value:规定度量的当前值
  • max:规定被界定为高的值的范围
  • min:规定被界定为低的值的范围
  • low:规定被界定为低的值的范围
  • high:规定被界定为高的值的范围
  • optimum:规定度量的最优值
  • 具体使用见meter标签改变颜色规则

简单示例如下

<meter min="0" low="40" high="90" max="100" value="91"></meter>
<meter min="0" low="40" high="90" max="100" value="90"></meter>

多媒体资源

​<audio>​

  • 常用写法:​​<audio src="" controls autoplay loop></audio>​
  • src:规定音频文件的url
  • controls:如果出现该属性,显示音频播放器的控制面板(比如播放/暂停按钮)
  • autoplay:如果出现该属性,自动播放音频
  • loop:如果出现该属性,循环播放音频

简单示例如下

<audio src="demo.mp3" controls autoplay></audio>

​<video>​

  • 常用写法:​​<video src="" width="" height="" poster="" controls autoplay loop></video>​
  • src:规定视频文件的url
  • width:设置视频播放器的宽度(pixels)
  • height:设置视频播放器的高度(pixels)
  • poster:设置视频未播放时展示的画面
  • controls:如果出现该属性,显示音频播放器的控制面板(比如播放/暂停按钮)
  • autoplay:如果出现该属性,自动播放音频
  • loop:如果出现该属性,循环播放音频

简单示例如下

<video src="demo.mp4" controls autoplay height="500px" poster="0.jpg"></video>

​<source>​

  • 常用写法:​​<source src="" type="">​
  • src:规定媒体文件的url
  • type:规定媒体文件的类型
  • 因为不同浏览器支持的媒体格式不同,当添加媒体文件时,需要考虑浏览器是否支持它们。我们可以准备多种不同格式的媒体文件,然后使用source 标签,让浏览器从上到下选择支持的媒体格式

简单示例如下

<video controls>
    <source src="demo.mp3" type="audio/mp3">
    <source src="demo.mp4" type="video/mp4">
    您的浏览器不支持video元素。
  </video>

特殊字符

​​HTML特殊字符编码对照表​​

参考

  • ​​HTML基础​​
  • ​​HTML 参考手册​​
  • HTML中标签对应的英文
  • meter标签改变颜色规则
  • HTML5 progress和meter控件