HTML(Hyper Text Markup Language)指超文本标记语言,是最基础的网页开发语言,用于展示页面的内容。
HTML文档由标签、标签体和标签属性组成,文档后缀为.html
或者.htm
。
标签根据有无标签体可分为围堵标签(<html>some text</html>)
和自闭和标签(<hr/>)
。
标签可以嵌套,但必须注意,需要正确嵌套,不能你中有我,我中有你,如<a><b></a></b>
。
在开始标签中可以定义属性。属性由键值对构成,值需要用单引号或双引号引起来。
标签不区分大小写,但是建议使用小写。
一个简单的HTML示例如下:
x1
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>Hello</title>
6</head>
7<body>
8 <h1>Hello, HTML!</h1>
9</body>
10</html>
11
标签名 | 描述 | |
---|---|---|
<!DOCTYPE html> | 文档声明,声明该文档是HTML文档 | |
<html> | 文档根标签 | |
<head> | 文档头部 | |
<body> | 文档主体 | |
<meta> | 文档元数据 | charset |
<title> | 文档标题 | |
<header> | 主体页眉(语义化标签) | |
<footer> | 主体页脚(语义化标签) | |
<link> | 引入外部资源 | rel、type、href |
<script> | 引入客户端脚本文件 | src、type |
<style> | 定义样式 | type |
<!-- 注释内容 --> | 编写注释 |
291
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>文档标签</title>
6 <link rel="stylesheet" type="text/css" href="mystyle.css">
7 <style type="text/css">
8 header {background-color:red}
9 body {background-color:yellow}
10 footer {background-color:blue}
11 </style>
12</head>
13<body>
14 <header>
15 这是页面主体页眉......
16 </header>
17
18 这是页面主体......
19
20 <footer>
21 这是页面主体页脚......
22 </footer>
23</body>
24<script>
25 <!-- 这里可以写JS脚本 -->
26</script>
27</html>
28
29
标签名 | 描述 | 常用属性 |
---|---|---|
<h1>...<h6> | 标题标签 | |
<p> | 段落标签 | |
<div> | 行标签 | |
<span> | 块标签 | |
<br> | 换行 | |
<hr> | 水平线 | color、width、size、align |
251
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>文本布局标签</title>
6</head>
7<body>
8 <h1>这是标题1......</h1>
9 <h2>这是标题2......</h2>
10 <h3>这是标题3......</h3>
11 <h4>这是标题4......</h4>
12 <h5>这是标题5......</h5>
13 <h6>这是标题6......</h6>
14
15 <!--这是一条水平线-->
16 <hr color='blue' width='100%' size='3px' align='center' />
17
18 <p>
19 <div>账户:<span>18974865155</span></div>
20 <div>密码:<span>123456</span></div>
21 </p>
22
23</body>
24</html>
25
标签名 | 描述 | 常用属性 |
---|---|---|
<font> | 字体样式 | color、size、face(字体) |
<center> | 居中 | |
<b> | 加粗 | |
<i> | 斜体 | |
<em> | 着重 | |
<strong> | 加重语气 | |
<small> | 小号字 | |
<ins> | 插入字 | |
<del> | 删除字 | |
<sub> | 下标字 | |
<sup> | 上标字 |
151
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>文本样式标签</title>
6</head>
7<body>
8
9<center>
10 <font size="10" color="red" face="verdana">This is some text!</font>
11</center>
12
13</body>
14</html>
15
标签名 | 描述 | 常用属性 |
---|---|---|
<img> | 展示图片 | src、align、alt、width、height |
<map> | 展示图像地图 | |
<area> | 定义图像地图中的可点击区域 |
131
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>图片标签</title>
6</head>
7<body>
8
9<img src="https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF" align="left" alt="插画01" width="500" height="500"/>
10
11</body>
12</html>
13
标签名 | 描述 | 常用属性 |
---|---|---|
<a> | 超链接 | href(URL)、target(打开资源的方式,可选_selef、_blank等) |
<base> | 页面中超链接的默认URL(不常用) |
301
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>链接标签</title>
6</head>
7<body>
8
9<!-- 普通超链接 -->
10<a href="http://www.baidu.com">普通超链接</a>
11<br/>
12
13<!-- 图片超链接 -->
14<a href="http://www.baidu.com">
15 <img src="https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF" alt="图片超链接" width="30" height="30">
16</a>
17<br/>
18
19<!-- 打开邮箱 -->
20<a href="mailto:2030201403@qq.com">打开邮箱</a>
21<br/>
22
23
24<!-- 指定跳转方式 -->
25<a href="http://www.baidu.com" target="_self">当前页面跳转</a>
26<a href="http://www.baidu.com" target="_blank">新页面跳转</a><br/>
27
28</body>
29</html>
30
标签名 | 描述 | 常用属性 |
---|---|---|
<ol> | 有序列表 | type(序号类型)、start(序号起始值)、list-style-type: none |
<ul> | 无序列表 | type(列表形状,可选disc、square、circle等)、list-style-type: none |
<li> | 列表项 |
251
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>列表标签</title>
6</head>
7<body>
8
9 有序列表:
10 <ol type="A" start="5">
11 <li>列表项01</li>
12 <li>列表项02</li>
13 <li>列表项03</li>
14 </ol>
15
16 无序列表:
17 <ul type="disc">
18 <li>列表项01</li>
19 <li>列表项02</li>
20 <li>列表项03</li>
21 </ul>
22
23</body>
24</html>
25
标签名 | 描述 | 常用属性 |
---|---|---|
<table> | 表格 | width、border、bgcolor、align、cellpadding(格线与内容距离)、 cellspacing(格线之间距离) |
<tr> | 表格行 | bgcolor、align |
<td> | 单元格 | colspan(占N列)、rowspan(占N行) |
<caption> | 表格标题 | |
<th> | 标题行(语义化标签,与普通的<tr>类似) | |
<thead> | 内部行视为表格的头部分(语义化标签) | |
<tbody> | 内部行视为表格的体部分(语义化标签) | |
<tfoot> | 内部行视为表格的脚部分(语义化标签) |
781
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>表格标签</title>
6 <style>
7 th,td{
8 text-align:center
9 }
10
11 th{
12 font-weight:bold;
13 }
14 </style>
15</head>
16<body>
17
18<!-- 表格(居中、占30%宽度、格线与内容距离为0、格线之间距离为0) -->
19<table border="1" align="center" width="30%" cellpadding="0" cellspacing="0">
20
21 <!-- 表格标题 -->
22 <caption>学生成绩表</caption>
23
24 <!-- 表格头部分 -->
25 <thead>
26
27 <!-- 标题行 -->
28 <tr>
29 <th>编号</th>
30 <th>姓名</th>
31 <th>性别</th>
32 <th>成绩</th>
33 </tr>
34
35 </thead>
36
37 <!-- 表格体部分 -->
38 <tbody>
39
40 <!-- 表格行01 -->
41 <tr>
42 <td>1</td>
43 <td>小龙女</td>
44 <td>女</td>
45 <td>100</td>
46 </tr>
47
48 <!-- 表格行02 -->
49 <tr>
50 <td>2</td>
51 <td>杨过</td>
52 <td>男</td>
53 <!-- 占2行 -->
54 <td rowspan="2">90</td>
55 </tr>
56
57 <!-- 表格行03 -->
58 <tr>
59 <td>3</td>
60 <td>金轮法王</td>
61 <td>男</td>
62 </tr>
63
64 </tbody>
65
66 <!-- 表格脚部分 -->
67 <tfoot>
68 <tr>
69 <td>总成绩</td>
70 <!-- 占3列 -->
71 <td colspan="3">280</td>
72 </tr>
73 <tfoot>
74</table>
75
76</body>
77</html>
78
标签名 | 描述 | 常用属性 |
---|---|---|
<form> | 表单 | action(指定提交数据的URL)、method(指定提交方式,GET、POST等) |
<input> | 表单项 | type(表单项类型) |
<select> | 下拉列表 | |
<option> | 下拉列表项 | value(提交值) |
<textarea> | 文本域 | rows(默认行)、cols(默认列) |
<label> | 焦点绑定 | for(绑定的表单项id) |
常用的表单项类型如下:
表单项类型(type) | 描述 | 相关属性 |
---|---|---|
text | 文本输入框 | placeholder(提示信息) |
password | 密码输入框 | |
number | 数字输入框 | |
邮件输入框 | ||
date | 日期输入框 | |
radio | 单选框 | value(提交值)、checked(选中状态) |
checkbox | 复选框 | value(提交值)、checked(选中状态) |
file | 文件选择框 | |
hidden | 隐藏域 | |
button | 普通按钮 | |
submit | 提交表单按钮 | |
image | 图片提交按钮 | src |
注意:表单项中的数据要想被提交,必须指定其
name
属性。
1011
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>表单标签</title>
6</head>
7<body>
8
9<!-- 表格表单 -->
10<form action="" method="post">
11
12 <!-- 表格 -->
13 <table border="1" align="center" width="500">
14
15 <caption>用户注册</caption>
16
17 <tr>
18 <!-- 文本输入框 -->
19 <td><label for="username">用户名</label></td>
20 <td><input type="text" name="username" id="username" placeholder='请输入用户名'></td>
21 </tr>
22
23 <tr>
24 <!-- 密码输入框 -->
25 <td><label for="password">密码</label></td>
26 <td><input type="password" name="password" id="password"></td>
27 </tr>
28
29 <tr>
30 <!-- 数字输入框 -->
31 <td><label for="tel">手机号</label></td>
32 <td><input type="number" name="tel" id="tel"></td>
33 </tr>
34
35 <tr>
36 <!-- 邮箱输入框 -->
37 <td><label for="email">Email</label></td>
38 <td><input type="email" name="email" id="email"></td>
39 </tr>
40
41 <tr>
42 <!-- 日期输入框 -->
43 <td><label for="birthday">出生日期</label></td>
44 <td><input type="date" name="birthday" id="birthday" placeholder='2020/01/01'></td>
45 </tr>
46
47 <tr>
48 <!-- 单选框 -->
49 <td><label>性别</label></td>
50 <td>
51 <input type="radio" name="gender" value="male" checked > 男
52 <input type="radio" name="gender" value="female"> 女
53 </td>
54 </tr>
55
56 <tr>
57 <!-- 复选框 -->
58 <td><label>爱好</label></td>
59 <td>
60 <input type="checkbox" name="habby" value="chang" checked > 唱
61 <input type="checkbox" name="habby" value="tiao" checked> 跳
62 <input type="checkbox" name="habby" value="rap"> Rap
63 <input type="checkbox" name="habby" value="lanqiu"> 篮球
64 </td>
65 </tr>
66
67 <tr>
68 <!-- 文件选择框 -->
69 <td><label>附件</label></td>
70 <td>
71 <input type="file" name="fileName" >
72 </td>
73 </tr>
74
75 <tr>
76 <!-- 文本输入框+图片 -->
77 <td><label for="checkcode">验证码</label></td>
78 <td>
79 <input type="text" name="checkcode" id="checkcode">
80 <img src="https://img2.baidu.com/it/u=1414007613,970007709&fm=253&fmt=auto&app=138&f=PNG?w=1000&h=370" width="50" height="10">
81 </td>
82 </tr>
83
84 <tr>
85 <td colspan="2" align="center">
86 <!-- 隐藏域 -->
87 <input type="hidden" name="mac" value="隐藏数据"/>
88
89 <!-- 普通按钮 -->
90 <input type="button" value="重置"/>
91
92 <!-- 提交按钮 -->
93 <input type="submit" value="注册">
94 </td>
95 </tr>
96 </table>
97</form>
98
99</body>
100</html>
101
视频标签、音频标签、内联框架标签等,基础阶段暂不学习!
属性 | 取值说明 |
---|---|
color | 1) 英文单词:red 、green 、blue 等。 2) RGB范围:如 rgb(0,0,0) ,取值范围为0~255。 3) 颜色编码:如 #FF00FF ,取值的范围为00~FF之间。 |
width | 1) 数值:如width='20' ,默认单位为px (像素)。 2) 百分比:如 50% ,表示占比相对于父元素的比例。 |
align | 可选center 、left 、right 等。 |
显示结果 | 描述 | 实体名称 | 实体编号 |
---|---|---|---|
空格 | |   | |
< | 小于号 | < | < |
> | 大于号 | > | > |
& | 和号 | & | & |
" | 引号 | " | " |
' | 撇号 | ' (IE不支持) | ' |
¢ | 分 | ¢ | ¢ |
£ | 镑 | £ | £ |
¥ | 人民币/日元 | ¥ | ¥ |
€ | 欧元 | € | € |
§ | 小节 | § | § |
© | 版权 | © | © |
® | 注册商标 | ® | ® |
™ | 商标 | ™ | ™ |
× | 乘号 | × | × |
÷ | 除号 | ÷ | ÷ |
注意:虽然HTML不区分大小写,但实体字符对大小写敏感。
CSS(Cascading Style Sheet)中文名为层叠样式表,用来对HTML页面进行美化和布局控制。使用CSS可以降低耦合度,让分工协作更加容易,进而提高开发效率。
CSS的格式如下:
61选择器 {
2 /*注释*/
3 属性名1:属性值1;
4 属性名2:属性值2;
5 ...
6 }
内联样式指直接在HTML标签的style属性中写CSS样式代码。
41<div style="color:red;">
2 hello css
3</div>
4
文档样式指在HTML文档的 <head>
标签内定义一个<style>
标签,并用选择器选择元素后进行样式控制。
161
2<html>
3<head>
4 <meta charset="utf-8">
5 <title>Hello</title>
6 <style>
7 div{
8 color:blue;
9 }
10 </style>
11</head>
12<body>
13 <div>show css</div>
14</body>
15</html>
16
在外部定义CSS资源文件,并在<head>
标签内,定义<link>
标签,通过ref属性引入外部的资源文件。
191<!-- a.css文件 -->
2div{
3 color:green;
4 }
5
6
7<!-- a.html文件 -->
8
9<html>
10<head>
11 <meta charset="utf-8">
12 <title>Hello</title>
13 <link rel="stylesheet" type="text/css" href="css/a.css">
14</head>
15<body>
16 <div>show css</div>
17</body>
18</html>
19
提示:外部样式还可以使用
<style>@import "css/a.css";</style>
方式引入,简单了解即可。
如果存在多个同名的CSS样式,那么后引入的样式将会覆盖前面的样式(注:在特异性相同的情况下)。
121<head>
2 <!-- 引入外部样式 -->
3 <link rel="stylesheet" type="text/css" href="mystyle.css">
4
5 <!-- 后定义的color属性将会覆盖前面引入的同名属性 -->
6 <style>
7 h1 {
8 color: orange;
9 }
10 </style>
11</head>
12
201/* id选择器: 根据id属性选择元素 */
2#id001 {
3 color: red;
4}
5
6/* 标签选择器: 根据标签名称选择元素 */
7p {
8 color: red;
9}
10
11/* 类选择器: 根据class属性选择元素 */
12.center {
13 color: red;
14}
15
16/* 通用选择器: 选择当前HTML页面中的所有元素 */
17* {
18 color: blue;
19}
20
301/* 选择器并集: 多个简单选择器的并集 */
2h1, h2, p {
3 color: red;
4}
5
6/* 选择器交集: 多个简单选择器的交集。例: 选择class属性有center的p元素 */
7p.center {
8 color: red;
9}
10
11/* 子代选择器: 选择A元素下的B元素。例: 选择h1标签下的em元素 */
12h1 > em {
13 color: red;
14}
15
16/* 后代选择器: 选择A标签内部的B元素,且可以隔代。例: 选择h1标签内部的em元素 */
17h1 em {
18 color: red;
19}
20
21/* 兄弟选择器: 选择A元素同级的B元素。 */
22div ~ p {
23 background-color: yellow;
24}
25
26/* 兄弟(跟班)选择器: 选择A元素后紧接的那个B元素,中间不能间隔其它元素。*/
27div + p {
28 background-color: yellow;
29}
30
261/*选择包含href属性的a元素*/
2a[href] {
3 color:red;
4}
5
6/*选择包含href属性和title属性的a元素*/
7a[href][title] {
8 color:red;
9}
10
11/*选择class属性为"important warning"的p元素(注意,必须完全匹配)*/
12p[class="important warning"] {
13 color: red;
14}
15
16/*选择class属性包含"important"的p元素,等价于p.important*/
17p[class~="important"] {color: red;}
18
19/*分别选择href属性值以"com"开头、以"com"结尾和包含"com"的a元素*/
20a[href^="com"] {color: red;}
21a[href$="com"] {color: red;}
22a[href*="com"] {color: red;}
23
24/*选择lang属性等于en或以en-开头的a元素*/
25a[lang|="en"] {color: red;}
26
伪元素用于对虚拟元素添加CSS效果。虚拟元素是一种逻辑概念,并非是某个确定的元素。
381/* 选择每个段落的首字母。
2 注意:只适用于块级元素和部分属性。 */
3p::first-letter {
4 color: #ff0000;
5 font-size: xx-large;
6}
7
8/* 选择每个段落的第一行。
9 注意:只适用于块级元素和部分属性。*/
10p::first-line {
11 color: #0000ff;
12 font-variant: small-caps;
13}
14
15/* 在h1元素体内容的前方插入一个虚拟元素,内容为一张图片。
16 F12显查看如下:
17 <h1>
18 ::before
19 "标题内容"
20 </h1>
21*/
22h1::before {
23 content: url(smiley.gif);
24}
25
26/* 在h1元素体内容的后方插入一个虚拟元素,内容为"" */
27.clearFix::after{
28 content: "";
29 clear: both;
30 display: block;
31}
32
33/* 选择用户选中的部分。可以使用color、background、cursor、outline属性 */
34::selection {
35 color: red;
36 background: yellow;
37}
38
伪类用于对特定状态的元素添加CSS效果。
191/*选择点击之前的a标签、点击之后的a标签*/
2a:link{color: aqua;}
3a:visited{color: chartreuse;}
4
5/*悬停时的h2标签、激活(按住不放)时的h3标签、获取焦点后的input标签*/
6h2:hover{color: cyan;font-size: 25px;}
7h3:active{color:darkmagenta;font-size: 10px;}
8input[type="text"]:focus{background-color: green;}
9
10/* p元素内部的第一个i元素 */
11p i:first-child {
12 color: blue;
13}
14
15/* 最后一个p元素内部的所有i元素 */
16p:last-child i {
17 color: blue;
18}
19
特异性是选择器的权重指标,当多个选择器操作的CSS属性发生冲突时,以权重较大者为准,如果权重相同,则覆盖掉先引入的样式。
选择器类型 | 权重 |
---|---|
行内样式 | 1000 |
ID选择器 | 100 |
类选择器、属性选择器和伪类 | 10 |
元素选择器和伪元素 | 1 |
通用选择器 | 0 |
!important | 无穷大 |
121/* 行内样式,特异性为1000 */
2<h1 style="color: #ffffff">Heading</h1>
3
4/*1个元素选择器和1个类选择器,特异性为11*/
5h1.aclss {}
6
7/*1个元素选择器,特异性为1*/
8h1 {}
9
10/*!important: 无视权重,强行覆盖 */
11div {background-color: blue !important;}
12
161<!-- 文本颜色 -->
2<p style="color:DodgerBlue;">China is a great country!</p>
3
4<!-- 背景颜色 -->
5<h1 style="background-color:DodgerBlue;">China</h1>
6
7<!-- 边框颜色 -->
8<h1 style="border:2px solid Tomato;">Hello World</h1>
9
10<!-- 颜色的表示方式 -->
11<h1 style="background-color:#ff6347;">...</h1>
12<h1 style="background-color:rgb(255, 99, 71);">...</h1>
13<h1 style="background-color:hsl(9, 100%, 64%);">...</h1>
14<h1 style="background-color:rgba(255, 99, 71, 0.5);">...</h1>
15<h1 style="background-color:hsla(9, 100%, 64%, 0.5);">...</h1>
16
191/*背景颜色、不透明度*/
2div {
3 background-color: green;
4 opacity: 0.3;
5}
6
7/*背景图片*/
8body {
9 background-image: url("tree.png");
10 background-repeat: no-repeat; /*背景图片重复,可选:no-repeat、repeat-x、repeat-y*/
11 background-position: right top; /*背景图像的位置*/
12 background-attachment: fixed; /*背景固定或滚动(scroll)*/
13}
14
15/*简写方式*/
16body {
17 background: #ffffff url("tree.png") no-repeat left top;
18}
19
101/*透明度。1-为完全透明 0-完全不透明 */
2img:hover {
3 opacity: 0.5;
4}
5
6/* 背景的透明度 */
7div {
8 background: rgba(76, 175, 80, 0.3)
9}
10
651/*文本颜色*/
2body {
3 color: blue;
4}
5
6/*文本背景*/
7h1 {
8 background-color: black;
9}
10
11/*水平对齐*/
12h1 {
13 text-align: center;/*center-居中 left-左对齐 right-右对齐 justify-拉伸*/
14}
15
16/*垂直对齐*/
17img.top {
18 vertical-align: top;/*top middle bottom*/
19}
20
21/*文字方向*/
22p {
23 direction: rtl;
24 unicode-bidi: bidi-override;
25}
26
27/*文字装饰*/
28a {
29 text-decoration: none; /*none-无装饰,一般用于删除链接的下划线 underline overline line-through */
30}
31
32/*文字转换*/
33p.uppercase {
34 text-transform: uppercase; /*uppercase-文本转大写 lowercase-文本转小写 capitalize-首字母大写*/
35}
36
37/*段落缩进*/
38p {
39 text-indent: 50px;
40}
41
42/*字符间距(同一个单词的字母之间)*/
43h1 {
44 letter-spacing: 3px; /*可以是负数*/
45}
46
47/*行高*/
48p.small {
49 line-height: 0.8;
50}
51
52/*单词间距(不同单词之间)*/
53h1 {
54 word-spacing: 10px;
55}
56
57/*指定元素内部空白的处理方式*/
58p {
59 white-space: nowrap; /*nowrap-禁用元素内的文本换行*/
60}
61
62/*文本阴影*/
63h1 {
64 text-shadow: 2px 2px 5px red;/*水平阴影 垂直阴影 模糊效果 阴影颜色*/
65}
301/*字体种类*/
2.p1 {
3 font-family: "Times New Roman", Times, serif;
4}
5
6/*字体样式*/
7p.normal {
8 font-style: normal; /*italic-斜体 oblique-倾斜(很少用)*/
9}
10
11/*字体粗细*/
12p.normal {
13 font-weight: normal; /*bold-加粗*/
14}
15
16/*字体变体*/
17p.normal {
18 font-variant: normal; /*small-caps-以 small-caps 字体(小型大写字母)显示文本*/
19}
20
21/*字体大小,默认为16px,即1em*/
22h1 {
23 font-size: 40px;/*可用单位有px、em、%、vw(视口宽度,浏览器窗口大小的百分比)*/
24}
25
26/*字体属性简写(注意:font-size和font-family的值是必需的)*/
27p.b {
28 font: italic small-caps bold 12px/30px Georgia, serif; /*斜体 small-caps变体 加粗 大小 字体种类*/
29}
30
在盒子模型中,所有HTML元素都可以视为方框,它包括外边距
、边框
、内边距
以及实际的内容
。
注意:内边距、边框和外边距都是可选的,默认值是零。但是,许多元素将由用户代理样式表设置外边距和内边距。
141/*内容宽度与高度(单位可以是px、pt、cm、%等,除此之外,还可写auto、initial、inherit等)*/
2div {
3 width: 50%;
4 height: 200px;
5 background-color: powderblue;
6}
7
8/*最大宽度max-width:用于替代width属性,当浏览器宽度不够时进行换行,而非出现左右滑动条*/
9div {
10 max-width: 500px;
11 height: 100px;
12 background-color: powderblue;
13}
14
注意:
height
和width
属性指的是内容区域的宽度和高度,不包括内边距、边框或外边距。增加内边距、边框和外边距不会影响内容的尺寸,但是会增加元素框的总尺寸。
591/* 边框(轮廓)类型:border-style、outline-style */
2p.dotted {border-style: dotted;} /* 点线边框 */
3p.dashed {border-style: dashed;} /* 虚线边框 */
4p.solid {border-style: solid;} /* 实线边框 */
5p.double {border-style: double;} /* 双边框 */
6p.groove {border-style: groove;} /* 3D凹槽边框 */
7p.ridge {border-style: ridge;} /* 3D垄状边框 */
8p.inset {border-style: inset;} /* 3D inset 边框 */
9p.outset {border-style: outset;} /* 3D outset 边框 */
10p.none {border-style: none;} /* 无边框 */
11p.hidden {border-style: hidden;} /* 隐藏边框 */
12p.mix {border-style: dotted dashed solid double;} /* 隐藏边框 */
13
14/* 边框(轮廓)宽度:border-width、outline-width*/
15p.one {
16 border-style: solid;
17 border-width: 5px; /*也可用thin、medium 或 thick*/
18}
19p.two {
20 border-style: solid;
21 border-width: 20px 5px; /* 上边框和下边框为 20px,其他边为 5px */
22}
23p.three {
24 border-style: solid;
25 border-width: 25px 10px 4px 35px; /* 上边框 25px,右边框 10px,下边框 4px,左边框 35px */
26}
27
28/* 边框(轮廓)颜色:border-color、outline-color */
29p.one {
30 border-style: solid;
31 border-color: red green blue yellow; /* 上红、右绿、下蓝、左黄 */
32}
33p.one {
34 border-style: solid;
35 border-color: #ff0000; /* 红色 */
36}
37
38/* 圆角边框 */
39p {
40 border: 2px solid red;
41 border-radius: 5px;
42}
43
44/*单独某边(border-width 和 border-color 也同样适用)*/
45p {
46 border-top-style: dotted;
47 border-right-style: solid;
48 border-bottom-style: dotted;
49 border-left-style: solid;
50}
51
52/* 简写形式:宽度 类型 颜色 */
53p {
54 border: 5px solid red;
55}
56p.ex3 {
57 outline: 5px solid yellow;
58}
59
注意:
边框/轮廓必须设置
border-style/outline-style
属性,否则其他CSS 边框/轮廓属性都不会有任何作用。轮廓是在元素边框之外绘制的,并且可能与其他内容重叠。
outline-offset
属性在元素的轮廓与边框之间添加透明空间。
551/*分别设置"上右下左"外边距(外边距单位可以是px、pt、cm、%等,可以为负值)*/
2p {
3 margin-top: 100px;
4 margin-bottom: 100px;
5 margin-right: 150px;
6 margin-left: 80px;
7}
8
9/*分别设置"上右下左"内边距(内边距单位可以是px、pt、cm、%等,但不可以为负值)*/
10div {
11 padding-top: 50px;
12 padding-right: 30px;
13 padding-bottom: 50px;
14 padding-left: 80px;
15}
16
17
18/*简写形式一*/
19p {
20 margin: 25px 50px 75px 100px;
21 padding: 25px 50px 75px 100px;
22}
23
24
25/*简写形式二*/
26p {
27 margin: 25px;
28 padding: 25px;
29}
30
31
32/*继承父元素的外边距*/
33p.ex1 {
34 margin: inherit;
35}
36
37/*通过外边距实现"水平居中"效果*/
38div {
39 width: 300px;
40 margin: auto;
41 border: 1px solid red;
42}
43
44
45/*DIV宽度固定:默认情况下,DIV的宽度为内容宽度(width)+内边距(padding)*2,
46 你可以使用"box-sizing: border-box"属性使DIV宽度固定为内容宽度,然后内边距会挤占可用的内容空间。
47*/
48div {
49 width: 300px;
50 padding: 25px;
51 box-sizing: border-box;
52}
53
54
55
注意:内边距用于呈现元素的背景。外边距是透明的,不会遮挡其后的任何元素。
当两个垂直外边距相遇时,它们将合并成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
注意:只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。
默认情况下,元素按文档顺序从上到下、从左到右依次展示(文档流),展示效果取决于display
属性。
381/* inline: 内联元素。
2 仅占用所需的宽度,如:`<span>`、`<a>`、`<img>`等。*/
3span.a {
4 display: inline;
5 width: 100px;
6 height: 100px;
7 padding: 5px;
8 border: 1px solid blue;
9 background-color: yellow;
10}
11
12/* block: 块级元素。
13 从新行开始,并占据可用的全部宽度(尽可能向左和向右伸展)。如:`<div>`、`<h1>`、`<p>`、`<form>`、`<header>`、`<footer>`、`<section>`等。 */
14span.c {
15 display: block;
16 width: 100px;
17 height: 100px;
18 padding: 5px;
19 border: 1px solid blue;
20 background-color: yellow;
21}
22
23/* inline-block: 内联块。
24 允许设置宽度和高度的内联元素(不换行),并且支持上下外边距和内边距。 */
25span.b {
26 display: inline-block;
27 width: 100px;
28 height: 100px;
29 padding: 5px;
30 border: 1px solid blue;
31 background-color: yellow;
32}
33
34/* none-不展示该元素(元素还在,但不影响布局) */
35span.d {
36 display: none;
37}
38
注意:行内元素不能包含块级元素。
visibility属性与display属性相似,表示元素的可见性。
51/*元素可见性*/
2h1.hidden {
3 visibility: hidden;/*hidden-隐藏(元素也在,但影响布局,依旧占用空间,类似于完全透明)*/
4}
5
默认情况下,块级元素将占用该行的全部宽度。你可以通过width
属性来固定,如500px,防止其延伸到其容器的边缘,并可将外边距设置为auto,来实现元素水平居中的效果。
但是,当浏览器窗口不足500px时,下方将会出现水平滚动条,可以使用max-width
替代width属性来改善该问题。
141/* 固定宽度,当浏览器窗口小于该宽度时,将会出现水平滚动条 */
2div.ex1 {
3 width: 500px;
4 margin: auto;
5 border: 3px solid #73AD21;
6}
7
8/* 最大宽度,当浏览器窗口小于该宽度时,将会换行显式 */
9div.ex2 {
10 max-width: 500px;
11 margin: auto;
12 border: 3px solid #73AD21;
13}
14
内容溢出指元素的内容区域无法展示元素的全部内容,可通过overflow
属性指定进行隐藏或滚动。
191/*内容溢出:
2 visible-可见(默认值),在元素外展示
3 hidden-隐藏,元素外的内容将会被隐藏
4 scroll-滚动,始终添加滚动条
5 auto-自动适配,需要的时候添加滚动条
6*/
7div {
8 width: 200px;
9 height: 50px;
10 background-color: #eee;
11 overflow: visible;
12}
13
14/*针对某边的写法*/
15div {
16 overflow-x: hidden; /* 隐藏水平滚动栏 */
17 overflow-y: scroll; /* 添加垂直滚动栏 */
18}
19
元素定位指确定元素在浏览器中的位置。先通过position
属性指定定位方式,再通过top
、right
、bottom
和left
调整偏移距离。
511/* 静态定位:按默认布局展示,即从上到下、从左到右,不受top、bottom、left和right属性的影响。*/
2div.static {
3 position: static;
4 border: 3px solid #73AD21;
5}
6
7/* 相对定位:相对正常位置进行定位。
8 注意:其它元素不会因为该元素的调整而发生任何变化 */
9div.relative {
10 position: relative;
11 left: 30px;
12 border: 3px solid #73AD21;
13}
14
15/* 固定定位:相对浏览器的可视窗口进行定位,即使滚动页面,也始终位于同一位置。
16 注意:固定定位的元素不会在页面中通常应放置的位置上留出空隙 */
17div.fixed {
18 position: fixed;
19 bottom: 0;
20 right: 0;
21 width: 300px;
22 border: 3px solid #73AD21;
23}
24
25/* 绝对定位:相对父元素进行定位。如果没有父元素,则相对文档主体(body)进行定位,这将随页面滚动一起移动。
26 注意:父元素不能是使用static定位的元素 */
27div.relative {
28 position: relative;
29 width: 400px;
30 height: 200px;
31 border: 3px solid #73AD21;
32}
33div.absolute {
34 position: absolute;
35 top: 80px;
36 right: 0;
37 width: 200px;
38 height: 100px;
39 border: 3px solid #73AD21;
40}
41
42/* 粘性定位:根据用户的滚动位置进行定位。起先它会被相对定位,直到在视口中遇到给定的偏移位置为止,然后将其“粘贴”在适当的位置(固定定位)。
43 注意:部分浏览器不支持粘性定位,Safari浏览器需要-webkit-前缀 */
44div.sticky {
45 position: sticky; /* Safari */
46 position: sticky;
47 top: 0;
48 background-color: green;
49 border: 2px solid #4CAF50;
50}
51
浮动就是使元素脱离文档流,按照指定的方向(向左或右)发生移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。
41img {
2 float: right; /* left-向左浮动 right-向右浮动 none-不浮动 */
3}
4
注意:
浮动后的元素不会超出父元素的范围(内边距)。
多个浮动的块状元素可能会在同一行显示。
如果父容器不设高度,当子元素浮动时,子元素脱离文档流,父容器高度不能被内容撑开,此时会造成“高度塌陷”。
221<style>
2 /*父元素(黄底黑边):不设高度*/
3 .father{
4 width: 400px;
5 background-color: yellow;
6 border: 1px solid black;
7 }
8
9 /*子元素(红底):左浮动 100×100 */
10 .son{
11 width: 100px;
12 height: 100px;
13 background-color: red;
14 float: left;
15 }
16</style>
17
18<!--父元素与子元素-->
19<div class="father">
20 <div class="son"></div>
21</div>
22
可以使用如下方式来解决该问题。
221/*父元素设置溢出属性为auto或hidden*/
2overflow:hidden; /
3
4/*父元素设置固定高度*/
5height: 100px;
6
7/*最后一个浮动元素之后添加一个空的div标签,并添加clear:both样式*/
8<div class="father">
9 <div class="son"></div>
10 <div style="clear: both"></div>
11</div>
12
13/*使用 ::after 伪元素:.clearFix::after*/
14.clearFix::after{
15 content: "";
16 clear: both;
17 display: block;
18}
19<div class="father clearFix">
20 <div class="son"></div>
21</div>
22
151/* 元素水平居中(margin: auto) */
2.center {
3 margin: auto;
4 width: 50%;
5 border: 3px solid green;
6 padding: 20px;
7}
8
9/* 文本水平居中(text-align) */
10.center {
11 text-align: center;
12 border: 3px solid green;
13}
14
15
231/*使用absolute实现(注意:绝对定位的元素将从正常流中删除,并可能出现元素重叠。)*/
2.right {
3 position: absolute;
4 right: 0px;
5 width: 300px;
6 border: 3px solid #73AD21;
7 padding: 20px;
8}
9
10/*使用float实现*/
11.right {
12 float: right;
13 width: 300px;
14 border: 3px solid #73AD21;
15 padding: 10px;
16}
17/* 注意:如果一个元素比包含它的元素高,并且它是浮动的,它将溢出其容器。您可以使用 clearfix hack 来解决此问题。*/
18.clearfix {
19 overflow: auto;
20}
21
22
23
491/*使用padding实现*/
2.center {
3 padding: 70px 0;
4 border: 3px solid green;
5}
6.center {
7 padding: 70px 0;
8 border: 3px solid green;
9 text-align: center; /*文本居中*/
10}
11
12/*使用line-height实现*/
13.center {
14 line-height: 200px;
15 height: 200px;
16 border: 3px solid green;
17 text-align: center;
18}
19
20/*使用line-height实现(多行文本)*/
21.center p {
22 line-height: 1.5;
23 display: inline-block;
24 vertical-align: middle;
25}
26
27/*使用使用position和transform实现*/
28.center {
29 height: 200px;
30 position: relative;
31 border: 3px solid green;
32}
33.center p {
34 margin: 0;
35 position: absolute;
36 top: 50%;
37 left: 50%;
38 transform: translate(-50%, -50%);
39}
40
41/*使用Flexbox实现*/
42.center {
43 display: flex;
44 justify-content: center;
45 align-items: center;
46 height: 200px;
47 border: 3px solid green;
48}
49
如果元素的内容发生重叠,则后渲染的元素将会在上方展示。你可以通过z-index
属性调整展示顺序,值越大则越先展示,默认值为0。
71/* 将图片置于普通内容之下 */
2img {
3 position: absolute;
4 left: 0px;
5 top: 0px;
6 z-index: -1;
7}
JavaScript是一门运行在浏览器上的客户端脚本语言,用来控制HTML页面的元素,让页面有一些动态的效果,从而增强用户的体验。
它由如下三部分组成:
ECMAScript:ECMA(欧洲计算机制造商协会)制定的客户端脚本语言标准,包括编程语法和基本核心知识。
DOM:文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。
BOM:浏览器对象模型(Browser Object Model,简称BOM)提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。
171<!-- 方式一(内联JS):将单行或少量JS代码写在HTML标签的属性中。-->
2<button onclick="alert('Hello World')">点我弹窗</button>
3<a href="javascript:alert('Hello World');">点我弹窗</a>
4
5<!-- 方式二(文档JS):将多行JS代码写到<script>标签中。-->
6<script type="text/javascript">
7 window.onload = function() {
8 alert('Hello World');
9 };
10
11</script>
12
13<!-- 方式三(外部JS):把大段JS代码独立到HTML页面之外,有利于HTML页面代码结构化,也方便文件级别的复用。-->
14<script src="https://notes.huangyuanxin.com/js/my.js"></script> <!-- 引用指定网络路径的脚本 -->
15<script src="/js/my.js"></script> <!--引用当前网站指定目录下的脚本-->
16<script src="my.js"></script> <!--引用当前文件夹下的脚本-->
17
注意:
script标签可以定义多个,执行顺序取决于其定义位置。
外部JS方式一般采用自闭和标签,标签体不再写其它的JS代码。
JavaScript是一种弱类型语言,其语言结构与C语言类似,语句严格区分大小写,一般以分号结尾,自动忽略多个空格和换行。
标识符可以由字母
、数字
、下划线
和美元符号($)
组成,使用时需注意:
不能以数字开头。
不能使用关键字或保留字。
对大小写敏感
推荐使用小驼峰样式命名。
121// 使用var定义变量(变量将会进行提升,并且会覆盖之前定义的变量)
2var a = 0;
3
4// 使用let定义变量(变量不会提升,在同一作用域,变量不能重复定义)
5let x = 'a';
6
7// 定义const变量
8const PI = 3.141592653589793;
9
10// 定义全局变量(不推荐)
11global_name = 'hyx';
12
注意事项:
在函数外定义的变量,将成为全局变量。
变量未初始化时的值为
undefined
,而非其它语言常见的null。
241// 赋值运算符: = += *=
2var a = 1;
3var b += a;
4
5// 算数运算符: + - * / % ++ --
6var a = 1/2; // 0.5
7
8// 比较运算符: > < >= <= != ==(自动类型转换后比较) ===(全等于,要求值和类型都相同)
9var isEqual = (1 == '1'); // true
10var isEqual = (1 === '1'); // false
11
12// 逻辑运算符: && || !
13var a = 5;
14var isTrue = (a > 1 && a < 10);
15
16// 三元运算符: 布尔表达式?表达式1:表达式2
17var age = 22;
18var info = (age < 18) ? '未成年':'成年';
19
20// 位运算符: & | ~ ^ << >>
21var x = 5 & 1; // 0101 & 0001 => 0001
22var x = 8 >> 3; // 1
23var x = 1 << 3; // 8
24
471// 选择语句
2var score = 70;
3if (score < 60) {
4 console.log('不及格');
5} else if (score < 80) {
6 console.log('及格');
7} else {
8 console.log('优秀');
9}
10
11// 分支语句(可以使用任意的原始数据类型)
12switch (new Date().getDay()) {
13 case 4:
14 case 5:
15 text = "周末快到了:)";
16 break;
17 case 0:
18 case 6:
19 text = "今天是周末~";
20 break;
21 default:
22 text = "期待周末!";
23}
24
25// for循环
26for (let i = 0; i < 5; i++) {
27 console.log("数字是 " + i);
28}
29
30// while循环
31let i = 0;
32while (i < 4) {
33 console.log("数字是 " + i);
34 i++;
35};
36
37// do-while循环
38let i = 0;
39do{
40 console.log("数字是 " + i);
41 i++;
42} while (i < 4);
43
44// 跳出循环
45continue;
46break;
47
111// 浏览器弹窗输入输出
2var p = prompt('请输入用户名: ');
3alert(p); // 警告框
4
5// 控制台输出
6console.log(msg):浏览器控制台打印输出信息
7
8// 文档输出
9document.write(); // 重写文档输出流
10element.innerHTML = 'hello word!'; // 重写元素标签体
11
JavaScript使用双精度浮点数来存储所有的数值,而不区分整型、长整型、小数等,最大精度为15位。
291// 数值表示方式
2var num = 1; // 整数
3var num = 1.1; // 小数
4var num = 123e5; // 指数
5var num = 07; // 八进制
6var num = 0xA; // 十六进制
7var num = 999999999993452357; // 变为999999999993452400(精度为15位)
8
9// 特殊的数值
10var num = Number.MAX_VALUE; // 1.7976931348623157e+308
11var num = Number.MIN_VALUE; // 5e-324
12var num = Infinity; // 无穷大(用1/0可以生成),相应的也有-Infinity。
13var num = NaN; // Not a Number,表示非法数值
14
15// 字符串形式
16var numStr = (9.656).toString(); // 9.656
17var numStr = (9.656).toFixed(2); // 9.66 指定小数位数(默认为0,四舍五入),不足补0
18var numStr = (9.656).toPrecision(2); // 9.7 四舍五入到指定长度,不足在后面补0
19var numStr = (9.656).toExponential(2); // 9.66e+0 四舍五入到指定小数位(默认为0),不足在后面补0
20
21// 判断是否为NaN
22var isNan = isNaN('a'); // 是否非数字,isNaN('1')-false、isNaN('a')-true
23
24// 转换为数值
25var num = Number('123'); // 无参数-0,空白字符串-0,数字字符串-对应数字,非法数字-NaN,true-1,false-0,null-0,undefined-NaN,new Date()-毫秒值,'10 20'-NaN,[]-0,[20]-20
26var num = parseInt('123.456px'); // 从字符串起始位置解析出一个整型,如果无法解析出任何数值,返回NaN
27var num = parseFloat(123.456px); // 从字符串起始位置解析出一个浮点数,如果无法解析出任何数值,返回NaN
28var num = +'123'; // 通过隐式类型转换为数值
29
571// 字符串表示形式
2var str='Hello'; // 单引号方式(推荐)
3var str="Hello"; // 双引号方式
4var str = '这是一个包含"引号"的字符串'; // 单引号嵌双引号
5var str = "这是一个包含'引号'的字符串"; // 双引号嵌单引号
6var str = "回车:\n 换行:\t 空格:\b 反斜杠:\\ 单引号:\' 双引号:\""; // 转义字符
7let text = `Hello`; // 模板字符串
8
9// 转换为字符串
10var str = (123).toString(); // 不适用于null和undefined,会报错
11var str = new String('123'); // 默认调用toString(),null-'null',undefined-'undefined',NaN-'NaN'
12var str = '' + 123; // 通过隐式类型转换为字符串,类似String()
13
14
15// 获取字符串长度
16var len = str.length;
17
18// 字符串拼接
19var newStr = str.concat('abc');
20var newStr = 'a' + 'b'; // 注意:"8" + 3 + 5 ==> "835" 3 + 5 + "8" ==> 88
21
22// 获取字符串字符或ASCII码
23var char = str.charAt(0);
24var charCode = "hello".charCodeAt(0); // 104
25
26// 转换大小写
27var lowerCase = str.toLowerCase();
28var lowerCase = str.toLocaleLowerCase();
29var upperCase =str.toUpperCase();
30var upperCase =str.toLocaleUpperCase();
31
32// 去除左右空格
33var trimedStr = str.trim();
34
35// 子串查找(未找到返回-1)
36var index = str.indexOf('abc',0); // 子串,起始索引
37var lastIndex = str.lastIndexOf('abc',0);
38
39// 子串截取
40var subStr = str.substr(1,3); // 起始索引,截取长度
41var subStr = str.subString(1,3); // 起始索引,结束索引
42var subStr = str.slice(1,3); // 起始索引,结束索引(索引允许负值)
43
44// 字符串替换(不修改原字符串)
45var replacedStr = str.replace('车','ddd'); // 原字符串正则,目的字符串
46
47// 字符串拆分
48var str = str.split(','); // 'a,b,c'.split(',') ==> ['a','b','c']
49
50// 判断是否包含子串
51var isInclude = 'abcd'.includes('abc', 0); // 子串,起始索引
52var isStartsWith = 'abcd'.startsWith('abc', 0); // 子串,起始索引
53var isEndsWith = 'abcd'.endsWith('bcd', 0); // 子串,结束索引
54
55// 字符串匹配(正则匹配)
56var matchedStrs = '1 plus 2 equal 3'.match(/\d+/g); // ['1', '2', '3']
57
71// 布尔表示形式
2var b = true; // true(1),false(0)
3
4// 转换为布尔(JS中,有且只有0、NON、null、undefined、''五个false值)
5var b = Boolean('true');
6var b = !!123; // 通过隐式类型转换来转换为布尔
7
在JS中,null表示一个空对象,undefined表示未初始化值,它们类型不同,但数值相等。
181// 表示形式
2var a = null;
3var b = undefined; // 如果一个变量没有初始化,则默认为undefined
4
5// 比较
6var b = (null==undefined); // true
7var b = (null===undefined); // false
8
9// null参与的运算
10var a = null + 1; // 1
11var a = null + true; // 1
12var a = null + '1'; // 'null1'
13
14// undefined参与的运算
15var a = undefined + 1; // NaN
16var a = undefined + true; // NaN
17var a = undefined + '1'; // 'undefined1'
18
121// 基本数据类型
2typeof 'Bill' // 'string'
3typeof 3.14 // 'number',特殊的NAN、Infinity也返回number
4typeof true // 'boolean'
5typeof null // 'object'
6typeof undefined // 'undefined'
7
8// 对象与函数
9typeof {name:'Bill', age:62} // 'object'
10typeof ['a','b','c'] // 'object', 并非'array'
11typeof function myFunc(){} // 'function'
12
instanceof运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上。
41function Person(){};
2var p = new Person();
3console.log(p instanceof Person);//true
4
71// 方式一:通过字面量创建
2var arr = ['a', 'b', 'c'];
3
4// 方式二:通过new Array创建
5var arr = new Array(3); // 创建长度为3的数组,内容为空,不推荐使用
6var arr = new Array(1,2,3); // 创建元素为1,2,3的数组,不推荐使用
7
581// 获取数组元素
2var a0 = arr[0];
3
4// 判断是否为数组类型
5var isArr = arr instanceof Array;
6var isArr = Array.isArray(arr);
7
8// 获取数组长度
9var len = arr.length;
10
11// 转换为逗号分隔的字符串
12var arrStr = arr.toString();
13
14// 在尾部添加或删除元素
15var len = arr.push('d'); // 返回添加后的数组长度
16var deleted = arr.pop(); // 返回被删除的元素
17
18// 在头部添加或删除元素
19var len = arr.unshift('d'); // 返回添加后的数组长度
20var deleted = arr.shift(); // 返回被删除的元素
21
22// 获取元素最大值或最小值(要求元素为数值类型)
23var max = Math.max.apply(null,[1,2,3]);
24var min = Math.min.apply(null,[1,2,3]);
25
26// 数组排序、乱序、翻转(修改原数组)
27arr.sort(); // 按字典顺序排序
28([3,2,1]).sort(function(a,b){return a - b;}); // 按数值升序
29([1,2,3]).sort(function(a, b){return 0.5 - Math.random()}); // 乱序
30arr.reverse(); // 翻转
31
32// 数组元素查找(不存在返回-1)
33var i = arr.indexOf('a');
34var i = arr.lastIndexOf('a');
35
36// 截取子数组
37var subArr = arr.slice(0,2); // 参数为索引,含左不含右
38
39// 数组拼接
40var joinStr = arr.join('-');
41
42// 数组合并
43var newArr = arr.concat(['x','y','z']);
44
45// 数组元素替换(修改原数组)
46var deleteds = arr.splice(0,1,'x','y','z'); // 从第0个位置开始,删除1个元素,并添加参数中的3个元素。返回值为被删除的元素。
47
48// 数组压缩
49var result = ([1,2,3,4]).reduce((result,item)=>{return result + item}, 0); // 依次对相邻的两个元素进行运算.当存在第二个参数时,作为第一次运算的左值.
50
51// 数组过滤(返回通过测试的元素)
52arr.filter(item=>{return item.length === 1})
53
54// 条件查找
55arr.find(item=>{return item.length === 1}); // 返回第一个通过测试的元素
56arr.findIndex(item=>{return item.length === 1}); // // 返回第一个通过测试的元素的索引
57arr.findLastIndex(item=>{return item.length === 1}); // 返回最后一个通过测试的元素的索引
58
201// for循环方式
2for(let i = 0; i < arr.length; i++){
3 console.log(arr[i]);
4}
5
6// foreach/map方式
7arr.forEach((val, index, arr) => {
8 console.log(val, index, arr)
9});
10
11// for-in方式
12for(index in arr){
13 console.log(index + "=" + arr[index]);
14};
15
16// for-of方式
17for(item of arr){
18 console.log(item);
19};
20
181// 定义函数
2function func(arg1,arg2='a'){console.log(arg1, arg2)}; // 普通函数, 参数默认值
3var func = function(arg1,arg2){console.log(arg1, arg2);}; // 匿名函数
4var func = new Function('arg1', 'arg2', 'console.log(arg1, arg2);'); // 不推荐
5
6// 调用函数
7var result = func(1); // 调用func函数,第二个参数不传,使用默认值
8var result = func(1,2); // 当实参数大于等于形参数时,函数正常调用,当小于形参数时,多余的形参值为undefined
9
10// 字符串形式
11func.toString(); // 'function(arg1,arg2){console.log(arg1, arg2);}'
12
13// 函数形参
14var funcArgNum = func.length; // 形参个数
15
16// 函数实参(被封装在一个伪数组arguments中, 可通过该数组来遍历和操作实参)
17var func = function(arg1, arg2){console.log(arguments)};
18
构造函数是一种用于构建对象的特殊函数,一般以大写字母开头,并与new运算符一起使用。
301// 创建构造函数
2function Person(firstName, lastName, age, eyeColor) {
3 // 对象属性(必须通过this关键字初始化)
4 this.firstName = firstName;
5 this.lastName = lastName;
6 this.age = age;
7 this.eyeColor = eyeColor;
8
9 // 对象方法(也必须通过this关键字初始化)
10 this.changeName = function(name) {
11 this.lastName = name;
12 };
13
14 // this无需return
15}
16
17// 使用new关键字调用构造函数
18var myFather = new Person("Bill", "Gates", 62, "blue");
19var myMother = new Person("Steve", "Jobs", 56, "green");
20
21// 内置的构造函数
22var x1 = new Object(); // 一个Object对象,类似于 var x1 = {};
23var x2 = new String(); // 一个String对象,类似于 var x2 = "";
24var x3 = new Number(); // 一个Number对象,类似于 var x3 = 0;
25var x4 = new Boolean(); // 一个Boolean对象,类似于 var x4 = false;
26var x5 = new Array(); // 一个Array对象,类似于 var x5 = [];
27var x6 = new RegExp(); // 一个RegExp对象,类似于 var x6 = /()/;
28var x7 = new Function(); // 一个Function对象,类似于 var x7 = function(){};
29var x8 = new Date(); // 一个Date对象
30
91var add = (function () {
2 var counter = 0;
3 return function () {return counter += 1;}
4})();
5
6add();
7add();
8add(); // 计数器目前是 3
9
31对象.方法名.call(方法名,多个参数); // 编写用于不同对象的方法,分别接受参数,如person.fullName.call(person1, "Seattle", "USA");
2对象.方法名.apply(方法名,参数列表); // 编写用于不同对象的方法,接受数组形式的参数。Math.max.apply(null, [1,2,3]);
3
321// 创建对象 方式一:通过字面量创建
2var person = {
3 // 对象属性
4 name: '张三',
5 age: 18,
6 language : 'en',
7
8 // 对象方法
9 sayHello: function(){console.log('hello!');},
10
11 // getter/setter
12 get lang() {
13 return this.language;
14 },
15 set lang(lang) {
16 this.language = lang;
17 }
18};
19
20
21// 创建对象 方式二:通过构造函数创建
22var bulidPerson = function Person(){
23 this.username = '张三';
24 this.age = 18;
25 this.sayHello = function(){console.log('hello!')}
26};
27var person = new bulidPerson();
28
29
30// 创建对象 方式三:通过new Object()创建(不推荐)
31var person = new Object();
32
381// 字符串形式
2var objStr = JSON.stringify(person); // '{"name":"张三","age":18,"language":"en","lang":"en"}'
3
4// 添加属性或方法
5person.name = '张三';
6person.age = 18;
7person.sayHello = function(){console.log('hello!')};
8
9// 获取属性或调用方法
10console.log(person.name);
11console.log(person['name']); // 名称索引方式
12console.log(person.lang); // Getter
13person.sayHello(); // 调用对象方法
14
15// 设置属性
16person.name = '黄原鑫';
17person['name'] = '黄原鑫'; // 名称索引方式
18person.lang = 'zh'; // Setter
19
20// 删除属性
21delete person.name;
22delete person['name'];
23
24// 遍历对象
25for(k in person){
26 console.log(k + "=" + person[k]);
27};
28
29// 判断属性是否存在
30console.log('name' in person);// 如果在对象中含有该属性,则返回true,否则返回false
31person.hasOwnProperty('name'); // 检查对象自身中是否含有某个属性
32
33// 对象原型(JS对象会继承构造函数原型的属性和方法,保存在对象的__proto__属性中,它相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象)
34// Date对象继承Date.prototype,Person对象继承Person.prototype,Object.prototype位于原型继承链的顶端
35Person.prototype.nationality = "English"; // JS的 prototype 属性允许您为对象构造器添加新属性和方法
36
37// 更多对象操作请查看Object类......
38
151// 常用方法
2Object.keys(person); // 获取可枚举的属性名和方法名 ['name', 'age', 'language', 'sayHello', 'lang']
3Object.values(对象) // keys()对应的属性值和方法定义 ['张三', 18, 'en', ƒ, 'en']
4Object.create(person); // 以某个对象为原型创建新对象
5Object.defineProperty(person, 'sex', {value: '男'}); // 添加或修改对象属性(writable:true、enumerable:true、configurable:true、get: function(){return this.sex;}、set: function(sex){this.sex = sex;})
6Object.getOwnPropertyDescriptor(person, 'sex'); /获取属性相关信息(值、是否可配置、是否可枚举、是否可写)
7Object.getOwnPropertyNames(person); // 获取对象的属性和方法,类似于Object.keys(person);
8Object.getPrototypeOf(person); // 获取原型
9Object.preventExtensions(person); // 防止向对象添加属性
10Object.isExtensible(person); // 如果属性可以添加到对象,则返回 true
11Object.seal(person); // 防止更改对象属性(不是值)
12Object.isSealed(person); // 如果对象被密封,则返回 true
13Object.freeze(person); // 防止对对象进行任何更改
14Object.isFrozen(person); // 如果对象被冻结,则返回 true
15
221// 创建Map
2const map = new Map();
3const map = new Map([['k4','v4'],['k5','v5'],['k6','v6']]);
4map.set('k1', 'v1');
5map.set('k2', 'v2');
6map.set('k3', 'v3');
7
8// Map常用属性和方法
9set()、get()、entries()、keys()、values()、size、clear()、delete()、has()、forEach()
10
11// 创建Set
12const set = new Set();
13const set = new Set(["a", "b", "c"]);
14set.add(1);
15set.add(2);
16set.add(3);
17
18// Set常用属性和方法
19clear()、delete()、entries()、has()、forEach()、keys()、values()、size
20typeof set // object
21set instanceof Set // true
22
Date实例用来处理日期和时间。
301// 创建
2var date = new Date(); // 当前时间
3var date = new Date(毫秒值);
4var date = new Date(2018, 11, 24, 10, 33, 30, 0); // new Date(year, month, day, hours, minutes, seconds, milliseconds)
5var date = new Date('2022-07-05');
6var date = new Date("2018-02-19T12:00:00");
7var date = new Date("October 13, 2014 11:13:00");
8
9// 常用方法
10Date.now() // 当前毫秒数
11date.toLocaleString() //返回当前date对象对应的时间本地字符串格式,如'2022/9/6 16:58:06'。
12date.getTime() // 当前毫秒数。返回当前如期对象描述的时间到1970年1月1日零点的毫秒值差。
13date.getFullYear() // 获取当年
14date.getMonth() // 获取当月(0-11)
15date.getDate() // 获取当天日期
16date.getDay() // 获取星期几(周日0到周六6)
17date.getHours() // 获取当前小时
18date.getMinutes() // 获取当前分钟
19date.getSeconds() // 获取当前秒钟
20
21date.setFullYear(2020, 11, 3); // 设置年(,月,日)
22date.setMonth(11); // 设置月份
23date.setDate(15); // 设置日
24date.setDate(d.getDate() + 50); // +N天,内置会自动调整
25date.setHours(22);
26date.setMinutes(30);
27date.setSeconds(30);
28
29someday > today // 日期比较
30
Math中定义了数学常数和跟数学相关的运算(求绝对值、取整、最大值等)。
211// 常用属性和方法
2Math.PI //返回圆周率
3Math.ceil(x) //对数进行上舍入。
4Math.floor(x) //对数进行下舍入。
5Math.round(x) //把数四舍五入为最接近的整数。
6Math.abs(x) // 绝对值
7Math.max(x1, x2) // 最大值
8Math.min(x1, x2) // 最小值
9Math.pow(x, y) 的返回值是 x 的 y 次幂:
10Math.random() //返回 0 ~ 1 之间的随机数。 含0不含1
11
12// 返回介于 min(包括)和 max(不包括)之间的随机数:
13function getRndInteger(min, max) {
14 return Math.floor(Math.random() * (max - min) ) + min;
15}
16
17// 返回介于 min 和 max(都包括)之间的随机数:
18function getRandom(min,max){
19 return Math.floor(Math.random()*(max - min + 1)) + min;
20}
21
71// 创建
2var reg = /正则表达式/;
3var reg = new RegExp("正则表达式","匹配模式"); // 不推荐
4
5// 常用属性和方法
6reg.test(参数); // 可以用来检查一个字符串是否符合正则表达式
7
有关JS中的正则表达式:
有关JS中的正则表达式:
单个字符:[a]表示a、[ab]表示a或b、表示[a-zA-Z0-9_]字母或数字或下划线。
特殊符号:\d表示单个数字字符,等同[0-9]、\w表示单个单词字符,等同[a-zA-Z0-9_]。
量词符号:{n}表示正好n次、{m,n}表示m-n次、{m,}表示至少m次、+表示至少1次,等同于{1,}、?表示0次或1次,等同于{0,1}、*表示0次或多次,等同于{0,}。
开始结束:^表示正则表达式的开始,$表示正则表达式的结束。
匹配模式:i表示忽略大小写、g表示全局匹配模式。
封装一些全局使用的属性和方法,无需使用Global也可直接调用。
81Global.encodeURI(); // url编码
2Global.decodeURI()(); // url解码
3Global.encodeURIComponent()(); // url编码,编码更多字符
4Global.decodeURIComponent()(); // url解码
5Global.parseInt(); // 从字符串中解析整型
6Global.isNaN(); // 判断一个值是否是NaN
7Global.eval(); // 将字符串参数作为JS脚本来执行
8
Promise用来执行异步任务,在异步方法内部通过myResolve或myReject返回成功或失败,并触发对应的回调函数。
411// 创建(new Promise方式)
2let myPromise = new Promise(function(myResolve, myReject) {
3 let retCode = 0;
4
5 if (retCode == 0) {
6 // 成功
7 myResolve("OK");
8 } else {
9 // 失败
10 myReject("Error");
11 }
12});
13myPromise.then(
14 // 成功时回调
15 function(value) {console.log(value);},
16
17 // 失败时回调
18 function(error) {console.log(error);}
19);
20
21
22// 创建(async函数方式)
23async function myFunction() {
24 return "Hello";
25}
26myFunction().then(
27 function(value) {console.log(value);},
28 function(error) {console.log(error);}
29);
30
31
32// 与await关键字一起使用
33async function myDisplay() {
34 let myPromise = new Promise(function(myResolve, myReject) {
35 setTimeout(function() { myResolve("I love You !!"); }, 3000);
36 });
37 document.getElementById("demo").innerHTML = await myPromise;
38}
39
40myDisplay();
41
注意:await关键字只能在async函数中使用。
BOM(Browser Object Model,浏览器对象模型)是对浏览器窗口的一种抽象,核心部分由Window(窗口对象)
、Document(文档对象,DOM)
、Navigator(浏览器对象)
、Screen(显示器屏幕对象)
、History(历史记录对象)
和Location(地址栏对象)
等组成。
Window是浏览器窗口的抽象,同时也是全局变量和全局函数的载体。
401// 属性(一般用于获取窗口内的其它对象)
2window.document; // 文档对象
3window.location; // 地址栏对象
4window.history; // 历史对象
5window.Navigator; // 导航对象
6window.Screen; // 屏幕对象
7
8// 关闭与打开窗口
9window.close(); // 关闭当前浏览器窗口
10window.open('/index.html'); //打开一个新的浏览器窗口,并返回新的Window对象
11
12// 操作弹框
13window.alert('警告消息'); // 警告框,显示带有一段消息和一个确认按钮的警告框
14var isConfirm = window.confirm('确认信息'); // 确认框,显示带有一段消息以及确认按钮和取消按钮的对话框,返回true或false。
15var input = window.prompt('输入提示'); // 输入框,显示可提示用户输入的对话框,返回用户的输入。
16
17// 操作定时器
18var timeoutId = window.setTimeout(回调函数, 延时毫秒数); // 在指定的毫秒数后调用函数或计算表达式,参数为方法对象(也可以是一段js代码)和毫秒值,返回定时器的唯一标识,用于取消定时器。
19window.clearTimeout(定时器ID); // 取消由 setTimeout() 方法设置的 timeout。
20var intervalId = window.setInterval(回调函数, 间隔毫秒数); // 按照指定的周期(以毫秒计)来调用函数或计算表达式。
21window.clearInterval(定时器ID); // 取消由setInterval()设置的timeout。
22
23// 会话存储
24sessionStorage.setItem('key1', JSON.stringify({username:'张三', age: 14}))
25sessionStorage.getItem('key1')
26sessionStorage.removeItem('key1')
27sessionStorage.clear()
28
29// 本地存储
30localStorage.setItem('key1', JSON.stringify({username:'张三', age: 14}))
31localStorage.getItem('key1')
32localStorage.removeItem('key1')
33localStorage.clear()
34
35// 相关事件
36window.onload = function(){}; // 窗口(页面)加载完成事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等)
37window.DOMContentLoaded; // DOM加载完成事件,当DOM加载完成时触发,不包括样式表、图片、flash等
38window.onresize; // 窗口大小调整事件,当窗口大小发生像素变化,就会触发这个事件。我们经常利用这个事件完成响应式布局。
39
40
121// 属性
2location.href // 设置或返回完整的 URL。
3location.host // 返回主机(域名),如:www.huangyuanxin.com
4location.port // 返回端口号如果未写返回空字符串
5location.pathname // 返回路径
6location.search // 返回参数
7
8// 方法
9location.reload(是否强制刷新) // 重新加载当前文档。相当于F5,如果参数为true,则相等于CTRL+F5
10location.assign() // 跟href一样,可以跳转页面(也称为重定向页面)
11location.replace() // 替换当前页面,因为不记录历史,所以不能后退页面
12
81// 属性
2history.length // 返回当前窗口历史列表中的 URL 数量。
3
4// 方法
5history.back() // 加载 history 列表中的前一个 URL。
6history.forward() // 加载 history 列表中的下一个 URL。
7history.go(参数) // 加载history列表中的某个具体页面,参数为正数则前进几个历史记录,为负数则后退。
8
Navigator包含浏览器的相关信息,最常用的是userAgent
属性,该属性返回由客户机发送服务器的请求头user-agent
的值。
21navigator.userAgent; // 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.50'
2
DOM(Document Object Model,文档对象模型)是对标记语言文档(如HTML、XML等)的一种抽象,核心部分由Document(文档对象)
、Element(元素对象)
、Attribute(属性对象)
、Text(文本对象)
、Comment(注释对象)
和Node(节点对象,其他5个的父对象)
等组成。扩展部分根据不同的文档类型扩展不同的内容。
Node是其它DOM对象的父对象,所有DOM对象都可以被认为是一个Node。Node一般有节点类型(nodeType)
、节点名称(nodeName)
、节点值(nodeValue)
三个基本属性。
221// 父节点、子节点、兄弟节点
2document.body.parentNode; // 获取父节点。如果没有父节点,则返回null
3document.body.childNodes; // 获取子节点列表
4document.body.firstChild; // 第一个子节点
5document.body.lastChild; // 最后一个子节点
6document.body.previousSibling; // 上一个兄弟节点
7document.body.nextSibling; // 下一个兄弟节点
8
9// 元素节点
10document.body.children; // 获取子节点列表(仅元素节点)
11document.body.previousElementSibling; // 上一个兄弟节点(仅元素节点)
12document.body.nextElementSibling; // 下一个兄弟节点(仅元素节点)
13
14// 添加或移除节点
15document.body.insertBefore(newChildNode, childNode); // 在指定的子节点元素之前添加一个新的子节点
16document.body.appendChild(newChildNode); // 向节点的子节点列表的结尾添加新的子节点。
17document.body.removeChild(childNode); //删除(并返回)当前节点的指定子节点。
18document.body.replaceChild(); //用新节点替换一个子节点。
19
20// 复制节点
21document.body.cloneNode(true); // 克隆当前节点,如果参数为true,则进行深拷贝
22
Document是window对象的子属性,表示HTML文档对象,可以用来获取元素和创建其它DOM对象等。
521// 属性
2document.documentElement; // 获取 <html> 元素
3document.title; // 返回 <title> 元素
4document.body; // 获取<body>元素
5document.scripts; // 返回所有 <script> 元素
6document.images; // 获取所有 <img> 元素
7document.cookie; // 获取文档的 cookie 对象
8document.URL; // 返回文档的完整 URL
9document.documentURI; // 返回文档的 URI
10document.baseURI; // 返回文档的绝对基准 URI
11
12// 获取元素
13document.getElementById('id值'); // 根据id属性值获取元素对象。id属性值一般唯一
14document.getElementsByTagName('标签名'); // 根据元素名称获取元素对象们。返回值是一个数组
15document.getElementsByClassName('class属性值'); // 根据Class属性值获取元素对象们。返回值是一个数组
16document.getElementsByName('name属性值'); // 根据name属性值获取元素对象们。返回值是一个数组
17document.querySelector('CSS选择器'); // 通过选择器来查询元素,返回第一个元素
18document.querySelectorAll('CSS选择器'); // 通过选择器来查询元素,返回所有元素
19
20// 创建其他DOM对象
21document.createAttribute(name); // 创建属性节点
22document.createComment(); // 创建注释节点
23document.createElement(); // 创建元素节点
24document.createTextNode(); // 创建文本节点
25
26// 操作cookie
27document.cookie; // 查看所有Cookie
28function setCookie(cname, cvalue, exdays) {
29 var d = new Date();
30 d.setTime(d.getTime() + (exdays*24*60*60*1000));
31 var expires = "expires="+ d.toUTCString();
32 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
33}
34setCookie('hyx', 'hyx666', 1); // 设置Cookie
35function getCookie(cname) {
36 var name = cname + "=";
37 var decodedCookie = decodeURIComponent(document.cookie);
38 var ca = decodedCookie.split(';');
39 for(var i = 0; i <ca.length; i++) {
40 var c = ca[i];
41 while (c.charAt(0) == ' ') {
42 c = c.substring(1);
43 }
44 if (c.indexOf(name) == 0) {
45 return c.substring(name.length, c.length);
46 }
47 }
48 return "";
49}
50getCookie('hyx'); // 获取Cookie
51
52
Element是元素的抽象,通过它可以修改元素的innerText
、innerHTML
、style
、class
、src
、type
、value
、checked
、selected
、disabled
等元素内置属性或其它自定义属性。
271// 元素属性操作
2document.images[0].src; // 获取元素属性 'http://10.201.84.9:8080/devops/static/common/img/index-logo.svg'
3document.images[0].getAttribute('src'); // 获取元素属性 'devops/static/common/img/index-logo.svg'
4document.images[0].src = 'https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE4wyTs?ver=59ec'; // 设置元素属性
5document.images[0].setAttribute('src', 'https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE4wyTs?ver=59ec'); // 设置元素属性
6document.images[0].removeAttribute('src'); // 移除元素属性
7
8// 通过style属性修改元素的样式
9var div1 = document.getElementById("div1");
10div1.onclick = function(){
11 div1.style.border = "1px solid red";
12 div1.style.width = "200px";
13 div1.style.fontSize = "20px"; //font-size--> fontSize
14}
15
16// 通过class属性修改元素的样式
17var div2 = document.getElementById("div2");
18div2.onclick = function(){
19 div2.className = "d1";
20}
21
22// 修改元素内容
23var div = document.getElementById("div1");
24var innerHTML = div.innerHTML;
25div.innerHTML = "<input type='text'>"; // 替换标签体
26div.innerHTML += "<input type='text'>"; // 追加标签体
27
事件包含事件源
、事件类型
和事件回调函数
三个基本要素。常用的事件如下:
311// 点击事件
2onclick //单击事件
3ondblclick //双击事件
4
5// 焦点事件
6onblur //失去焦点
7onfocus //元素获得焦点
8
9// 加载事件
10onload //一张页面或一幅图像完成加载
11
12// 鼠标事件
13onmousedown //鼠标按钮被按下。
14onmouseup //鼠标按键被松开。
15onmousemove //鼠标被移动。
16onmouseover //鼠标移到某元素之上
17onmouseout //鼠标从某元素移开。
18
19// 键盘事件(触发顺序为:onkeydown->onkeypress->onkeyup)
20onkeydown //某个键盘按键被按下。
21onkeypress //某个键盘按键被按下并松开(ctril、shift、箭头等功能键无法使用)。
22onkeyup //某个键盘按键被松开。
23
24// 选择和改变
25onchange //域的内容被改变。
26onselect //文本被选中。
27
28// 表单事件
29onsubmit //确认按钮被点击。
30onreset //重置按钮被点击。
31
301<!-- 绑定方式一:直接在html标签上,指定事件的属性(操作),属性值就是js代码 -->
2<img id="light" src="img/off.gif" onclick="func();">
3
4<!-- 绑定方式二:通过js获取元素对象,指定事件属性,设置一个函数 -->
5<body>
6 <img id="light2" src="img/off.gif">
7
8 <script>
9
10 function fun2(){
11 alert('Hello');
12 }
13
14 var light2 = document.getElementById("light2");
15
16 // 绑定方式二
17 light2.onclick = fun2;
18
19 // 绑定方式二:另一种写法
20 light2.addEventListener('click', fun2); // 另一种写法
21
22 // 解绑方式一
23 light2.onclick = null;
24
25 // 解绑方式二:
26 light2.removeEventListener('click', fun2);
27
28 </script>
29</body>
30
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。事件流描述的是从页面中接收事件的顺序。
DOM事件流分为3个阶段:捕获阶段 -> 当前目标阶段 -> 冒泡阶段。
事件捕获最早由网景提出,由DOM最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。事件冒泡最早由IE提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程。
JS代码中只能执行捕获或者冒泡(默认)中的一个阶段,在注册事件监听时可通过addEventListener(type, listener[, useCapture])
的第三个参数进行设置。
在实际开发中我们很少使用事件捕获,我们更关注事件冒泡。特殊的,onclick
和attachEvent
事件只能得到冒泡阶段,也有些事件是没有冒泡的,比如onblur
、onfocus
、onmouseenter
、onmouseleave
等。
事件处理函数的第一个形参表示事件对象,它封装了跟当前事件相关的一系列状态信息和相关事件处理方法。
251// 获取事件对象
2eventTargt.onclick = function(event){} // 这个event就是事件对象,可以写成e或evt等,浏览器自动注入,无需传递实参
3eventTargt.addEvenetListener('click',function(event){});
4
5// 事件对象的一些常用方法
6e.target // 返回触发事件的对象
7e.type // 返回事件的类型比如click、mouseover(不带on)
8e.preventDefault() // 该方法阻事件的默认行为(比如不让链接跳转)
9e.stopPropagation() // 阻止事件冒泡
10
11// 案例
12document.body.oncontextmenu = function(e){e.preventDefault()} // 阻止右键菜单
13document.body.onselectstart = function(e){e.preventDefault()} // 禁止选中
14
15// 针对鼠标事件的一些特殊方法
16e.clientX // 返回鼠标相对于浏览器窗口可视区的X坐标
17e.clientY // 返回鼠标相对于浏览器窗口可视区的Y坐标
18e.pagex // 返回鼠标相对于文档页面的X坐标1E9+支特
19e.pageY // 返回鼠标相对于文档页面的Y坐标E9+支特
20e.screenX // 返回鼠标相对于电脑屏幕的X坐标
21e.screenY // 返回鼠标相对于电脑屏幕的Y坐标
22
23// 针对键盘事件的一些特殊方法
24e.key // 返回键值
25
401// 创建类
2class Car {
3 // 构造方法
4 constructor(name, year) {
5 this.name = name;
6 this.year = year;
7 }
8
9 // 普通方法
10 age() {
11 let date = new Date();
12 return date.getFullYear() - this.year;
13 }
14
15 // 静态方法
16 static hello() {
17 return "Hello!!";
18 }
19
20}
21
22// 使用类创建对象
23let myCar = new Car("Ford", 2014);
24
25// 使用对象
26document.getElementById("demo").innerHTML = "My car is " + myCar.age() + " years old.";
27
28// 使用静态方法
29document.getElementById("demo").innerHTML = Car.hello();
30
31
32// 使用extends关键字继承父类,并使用super()方法引用父类构造器
33class Model extends Car {
34 constructor(name, year, mod) {
35 super(name, year);
36 this.model = mod;
37 }
38
39}
40
151var x = "A";
2try {
3 if(x == "") throw "是空的";
4 if(isNaN(x)) throw "不是数字";
5 x = Number(x);
6 if(x > 10) throw "太大";
7 if(x < 5) throw "太小";
8}
9catch(err) {
10 console.log('err:', err);
11}
12finally {
13 console.log('--finally--');
14}
15
351// JSON对象
2{
3"employees":[
4 {"firstName":"Bill", "lastName":"Gates"},
5 {"firstName":"Steve", "lastName":"Jobs"},
6 {"firstName":"Alan", "lastName":"Turing"}
7]
8}
9
10
11// JSON数组
12"employees":[
13 {"firstName":"Bill", "lastName":"Gates"},
14 {"firstName":"Steve", "lastName":"Jobs"},
15 {"firstName":"Alan", "lastName":"Turing"}
16]
17
18
19// 对象转换JSON
20var person = {name:'黄原鑫', age: 18};
21JSON.stringify(person); ==> '{"name":"黄原鑫","age":18}'
22
23// JSON转对象
24var personJsonStr = '{"name":"黄原鑫","age":18}'
25JSON.parse(personJsonStr); ==> {name: '黄原鑫', age: 18}
26
27// 处理日期属性
28var text = '{ "name":"Bill Gates", "birth":"1955-10-28", "city":"Seattle"}';
29var obj = JSON.parse(text, function (key, value) {
30 if (key == "birth") {
31 return new Date(value);
32 } else {
33 return value;
34 }});
35
Ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。传统的网页如果需要更新内容,必须重载整个网页页面。
461//发送异步请求
2function func() {
3 //1.创建核心对象
4 var xmlhttp;
5 if (window.XMLHttpRequest)
6 {// code for IE7+, Firefox, Chrome, Opera, Safari
7 xmlhttp=new XMLHttpRequest();
8 }
9 else
10 {// code for IE6, IE5
11 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
12 }
13
14 //2. 建立连接
15 /*
16 参数:
17 1. 请求方式:GET、POST
18 * get方式,请求参数在URL后边拼接。send方法为空参
19 * post方式,请求参数在send方法中定义
20 2. 请求的URL:
21 3. 同步或异步请求:true(异步)或 false(同步)
22
23 */
24 xmlhttp.open("GET","ajaxServlet?username=tom",true);
25
26 //3.发送请求
27 xmlhttp.send();
28
29 //4.接受并处理来自服务器的响应结果
30 //获取方式 :xmlhttp.responseText
31 //什么时候获取?当服务器响应成功后再获取
32
33 //当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
34 xmlhttp.onreadystatechange=function()
35 {
36 //判断readyState就绪状态是否为4,判断status响应状态码是否为200
37 if (xmlhttp.readyState==4 && xmlhttp.status==200)
38 {
39 //获取服务器的响应结果
40 var responseText = xmlhttp.responseText;
41 alert(responseText);
42 }
43 }
44
45}
46
变量:新增let和var关键字用于定义变量。
字符串:新增includes()、startsWith()、endsWith()等方法,以及支持模板字符串。
数组:新增find()、findIndex()、includes()、map()、reduce()等方法。
函数:支持参数默认值、箭头函数。
271var print = obj => console.log(obj); // 一个参数
2
3var sum = (a,b) => a + b; // 二个参数
4
5// 函数体有多行语句
6var printAndSum = (a,b) => {
7 console.log(a);
8 console.log(b);
9 return a + b;
10}
11
12// 对象中使用箭头函数
13let person = {
14 name: "jack",
15 // 以前
16 eat: function (food) {
17 console.log(this.name + "在吃" + food);
18 },
19
20 // 箭头函数版
21 eat2: food => console.log(person.name + "在吃" + food), // 注意:箭头函数的this不是对象本身,应再向外找一层
22
23 // 简写版
24 eat3(food){
25 console.log(this.name + "在吃" + food);
26 }
27}
对象:新增keys(obj)、values(obj)、entries(obj)、assign(dest, ...src)等方法。
解构表达式:
191// 解构数组
2let arr = [1,2,3];
3const [x,y,z] = arr; // x,y,z将与arr中的每个位置对应来取值
4
5// 解构对象
6const person = {name:"jack",age:21,language: ['java','js','css']};
7const {name,age,language} = person;
8const {name:Name} = person;
9
10// 解构表达式做函数形参
11function hello({name}) {
12 console.log("hello," + name)
13}
14hello(person); // 传对象给结构表达式形参
15
16// 解构表达式做箭头函数形参
17var hi = ({name}) => console.log("hello," + name);
18hi(person);
19
TypeScript 是微软开发的一个 JavaScript 扩展语⾔,它是 JavaScript 的超集,包含了 JavaScript 的所有内容,并增加了静态类型检查、接口、 泛型等很多现代开发特性,更适合⼤型项⽬的开发。
21const person = { name: '李四', age: 18 }
2console.log(`我叫${person.name},我今年${person.age}岁了`)
111
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Document</title>
6</head>
7<body>
8 <!-- 引入 index.js 文件-->
9 <script src="./index.js"></script>
10</body>
11</html>
21# TypeScript Compiler
2npm i typescript -g
21# 编译后会生成一个 index.js 文件,被 index.html 页面引入
2tsc index.ts
使用浏览器打开 index.html 文件,控制台便会打印输出:
首先需初始化编译目录,生成 tsconfig.json
配置文件:
11tsc --init
然后使用监听命令自动编译当前目录下的所有 .js
文件:
81# 监听当前目录下所有js文件的变动,进行自动编译
2tsc --watch
3
4# 简写形式
5tsc -w
6
7# 配置:当编译出错时不生成 .js 文件
8tsc --noEmitOnError --watch
提示:
自动编译相关配置一般在
tsconfig.json
中修改。实际开发时,会使用一些脚手架,自动编译会默认配置好,无需特殊关注。
JavaScript中的数据类型:boolean、number、bigint、string、null、undefined、symbol、object(Array、Function、Date、Error等)。
TypeScript新增数据类型:any、unknown、never、void、tuple、enum。
TypeScript自定义类型方式:type、interface。
使⽤ :
来对变量或函数形参,进⾏类型声明:
241// 1. 类型声明
2let a: string //变量a只能存储字符串
3let b: number //变量b只能存储数值
4let c: boolean //变量c只能存储布尔值
5
6// 2. 使用声明的类型
7a = 'hello'
8a = 100 //警告:不能将类型“number”分配给类型“string”
9b = 666
10b = '你好'//警告:不能将类型“string”分配给类型“number”
11c = true
12c = 666 //警告:不能将类型“number”分配给类型“boolean”
13
14// 3. 在函数中声明类型
15// 参数x必须是数字,参数y也必须是数字,函数返回值也必须是数字
16function demo(x:number,y:number):number{
17 return x + y
18}
19
20// 4. 调用函数必须遵守声明的类型
21demo(100,200)
22demo(100,'200') //警告:类型“string”的参数不能赋给类型“number”的参数
23demo(100,200,300) //警告:应有 2 个参数,但获得 3 个
24demo(100) //警告:应有 2 个参数,但获得 1 个
在 :
后也可以写字⾯量类型,不过实际开发中⽤的不多:
71// 1. 使用字面量声明类型
2let a: '你好' //a的值只能为字符串“你好”
3let b: 100 //b的值只能为数字100
4
5// 2. 字面量声明的类型会限制变量的值
6a = '欢迎' //警告:不能将类型“"欢迎"”分配给类型“"你好"”
7b = 200 //警告:不能将类型“200”分配给类型“100”
在大多数情况下,TypeScript也可以进行类型推断:
51// 1. 类型推断
2let d = -99 //TypeScript会推断出变量d的类型是数字
3
4// 2. 类型推断后,后续在使用时必须遵守类型规则
5d = false //警告:不能将类型“boolean”分配给类型“number”
但类型推断不是万能的,⾯对复杂类型时推断容易出问题,所以尽量还是明确的编写类型声明!
注意:
在TypeScript中,可以将基本类型赋值给包装类型(自动装箱),但不能将包装类型赋值给基本类型(自动拆箱):
71// 基础类型可以赋值给包装类型
2let str2: String str2 = 'hello'
3
4// 包装类型不能赋值给基础类型
5let str1: string str1 = 'hello'
6str1 = new String('hello') //报错
7
any
指任意类型,⼀旦将变量类型限制为 any ,那就意味着放弃了对该变量的类型检查,可以接收任意类型。
131// 1. 显示声明为any
2let a: any
3// 可以接收任意类型
4a = 100
5a = '你好'
6a = false
7
8// 2. 自动推断为any(声明时未初始化,不知道是什么类型)
9let b
10// 可以接收任意类型
11b = 100
12b = '你好'
13b = false
并且可以读取任意类型的属性:
61// 1. 声明 str1 为 any 类型
2let str2: any
3
4// 2. 可以接收任意类型,并读取任意属性
5str2 = 'hello'
6str2.toUpperCase() //⽆警告
缺陷:any类型可以赋值给任意类型的变量,这会破坏被赋值变量的结构:
61// 1. 声明一个any类型,赋值一个数值9
2let c:any
3c = 9
4
5// 2. 通过 any 类型,可以将数值9赋值给string类型的变量x
6let x: string x = c // ⽆警告
unknown
指未知类型,适⽤于起初不确定数据的具体类型,要后期才能确定的情形。
unknown 可以理解为⼀个类型安全的any,它不能随便的赋值给任意类型。
111// 1. 声明a的类型为unknown
2let a: unknown
3
4// 2. 和any一样,可以接收任意类型
5a = 100
6a = false
7a = '你好'
8
9// 3. 但是不能将 unknown 类型的变量随便赋值给其他类型
10let x: string
11x = a //警告:不能将类型“unknown”分配给类型“string”
但是,如果检查后确实类型匹配,还是可以赋值的:
141// 1. 声明a的类型为unknown
2let a: unknown
3a = 'hello'
4
5// 2. 通过 if 语句检查类型匹配后,允许赋值
6if(typeof a === 'string'){
7 x = a
8 console.log(x)
9}
10
11// 3. 通过 强转 进行类型赋值(强转前会触发断言,检查类型是否匹配)
12x = <string>a
13x = a as string
14
类似的,unknown类型不能随便读取属性,只有在检查类型匹配后,才能读取相应类型的属性:
91// 1. 声明 str3 的类型为 unknown
2let str3: unknown
3
4// 2. unknown类型不能随便读取属性
5str3 = 'hello';
6str3.toUpperCase() //警告:“str3”的类型为“未知”
7
8// 3. 在类型检查后可以读取对应类型的属性
9(str3 as string).toUpperCase() //⽆警告
never
指不是任何类型,即不能有任何值,包括 undefined 、 nul l 、 '' 、 0 都不⾏!
一般⽤于限制函数的返回值:
41// 限制 throwError 函数不需要有任何返回值,任何值都不⾏,像undeifned、null都不⾏
2function throwError(str: string): never {
3 throw new Error('程序异常退出:' + str)
4}
直接限制变量毫无意义:
71// 1. 声明 a 的类型为never(意味着 a 以后不能存任何的数据了)
2et a: never
3
4// 2. 以下对a的所有赋值都会有警告
5a = 1
6a = true
7a = undefined a = null
特殊情况下,可能由 TypeScript 主动推断出 never 类型的变量,例如:
101// 1. 声明一个string类型的变量并赋值
2let a: string
3a = 'hello'
4
5// 2. 进行类型判断
6if (typeof a === 'string') {
7 console.log(a.toUpperCase()) // 由于 a 的类型唯一确定,因此必会进入该逻辑
8} else {
9 console.log(a) // 此处不可能进入,因此推断此处的 a 为never
10}
void
指空类型,即函数不许返回任何值(undefined除外),调⽤者也不应依赖其返回值进⾏任何操作!
一般⽤于函数返回值声明:
51// 1. 声明函数返回空类型,表示函数无返回值
2function logMessage(msg:string):void{
3 console.log(msg)
4}
5
特殊的,由于JS函数默认会返回一个undefined,因此 TS 对返回 ndefined 的函数作了特殊处理,不会报错,而是直接丢弃返回值:
141// ⽆警告
2function logMessage(msg:string):void{
3 console.log(msg)
4}
5// ⽆警告
6function logMessage(msg:string):void{
7 console.log(msg)
8 return;
9}
10// ⽆警告
11function logMessage(msg:string):void{
12 console.log(msg)
13 return undefined
14}
但是,声明返回值为 void 和声明返回值为 undefined 的函数还是不一样的:
171// 1. 声明返回值为 undefined 的函数,可以对返回值进行操作
2function logMessage(msg:string):undefined{
3 console.log(msg)
4}
5let result = logMessage('你好')
6if(result){ // 此⾏⽆警告
7 console.log('logMessage有返回值')
8}
9
10// 2. 声明返回值为 void 的函数,不能对返回值进行操作
11function logMessage(msg:string):void{
12 console.log(msg)
13}
14let result = logMessage('你好')
15if(result){ // 此⾏报错:⽆法测试 "void" 类型的表达式的真实性
16 console.log('logMessage有返回值')
17}
object
指所有非原始类型,可存储对象、函数、数组等,由于限制的范围⽐较宽泛,在实际开发中使⽤的相对较少。
171// 1. 声明 object 类型
2let a:object
3
4// 2. 可以接收任意非原始类型
5a = {}
6a = {name:'张三'}
7a = [1,3,5,7,9]
8a = function(){}
9a = new String('123') class Person {}
10a = new Person()
11
12// 3. 但不能接收原始类型
13a = 1 // 警告:不能将类型“number”分配给类型“object”
14a = true // 警告:不能将类型“boolean”分配给类型“object”
15a = '你好' // 警告:不能将类型“string”分配给类型“object”
16a = null // 警告:不能将类型“null”分配给类型“object”
17a = undefined // 警告:不能将类型“undefined”分配给类型“object”
Object
指所有可以调⽤ Object⽅法的类型,即可以接收 undefined 和 null 之外的任何值,实际开发中使⽤频率极低。
181// 1. 声明 Object 类型
2let b:Object
3
4// 2. 可以接收除去undefined和null的任何值
5b = {}
6b = {name:'张三'}
7b = [1,3,5,7,9]
8b = function(){}
9b = new String('123') class Person {}
10b = new Person()
11b = 1 // 1不是Object的实例对象,但其包装对象是Object的实例
12b = true // truue不是Object的实例对象,但其包装对象是Object的实例
13b = '你好' // “你好”不是Object的实例对象,但其包装对象是Object的实例
14
15// 3. 不能接收undefined或null
16b = null // 警告:不能将类型“null”分配给类型“Object”
17b = undefined // 警告:不能将类型“undefined”分配给类型“Object”
18
实际开发中,声明普通对象,一般不使用上述的 object 或 Object 类型,通常使⽤以下形式:
181// 1. 限制person1对象必须有name属性,age为可选属性
2let person1: { name: string, age?: number }
3
4// 2. 含义同上,也能⽤分号做分隔
5let person2: { name: string; age?: number }
6
7// 3. 含义同上,也能⽤换⾏做分隔
8let person3: { name: string age?: number
9}
10
11// 4. 如下赋值均可以
12person1 = {name:'李四',age:18}
13person2 = {name:'张三'}
14person3 = {name:'王五'}
15
16// 5. 如下赋值不合法,因为person3的类型限制中,没有对gender属性的说明
17person3 = {name:'王五',gender:'男'}
18
如需允许定义的对象可以具有任意数量的属性,则需添加索引签名,这些属性的键和类型是可变的。
141// 1. 限制person对象必须有name属性,可选age属性但值必须是数字,同时可以有任意数量、任意类型的其他属性
2let person: {
3 name: string
4 age?: number
5 [key: string]: any // 索引签名,完全可以不⽤key这个单词,换成其他的也可以
6}
7
8// 2. 赋值合法
9person = {
10 name:'张三',
11 age:18,
12 gender:'男' // OK
13}
14
声明函数类型使用如下形式:
81// 1. 声明函数类型,2个number类型的入参,返回值为number类型
2let count: (a: number, b: number) => number
3
4// 2. 赋值
5count = function (x, y) {
6 return x + y
7}
8
声明数组类型使用如下形式:
71// 1. 声明数组类型
2let arr1: string[]
3let arr2: Array<string> // 泛型
4
5// 2. 赋值
6arr1 = ['a','b','c']
7arr2 = ['hello','world']
tuple
是一种特殊的数组类型,可以存储固定数量的元素,并且每个元素的类型是已知的且可以不同。
171// 1. 声明元组类型
2// 第⼀个元素必须是 string 类型,第⼆个元素必须是 number 类型。
3let arr1: [string,number]
4// 第⼀个元素必须是 number 类型,第⼆个元素是可选的,如果存在,必须是 boolean 类型。
5let arr2: [number,boolean?]
6// 第⼀个元素必须是 number 类型,后⾯的元素可以是任意数量的 string 类型
7let arr3: [number,string[]]
8
9// 2. 赋值
10arr1 = ['hello',123]
11arr2 = [100,false]
12arr2 = [200]
13arr3 = [100,'hello','world']
14arr3 = [100]
15
16// 3. 不可以赋值
17arr1 = ['hello',123,false] // arr1声明时是两个元素,赋值的是三个
enum
可以定义⼀组命名常量,它能增强代码的可读性,也让代码更好维护。
数字枚举:最常⻅的枚举类型,其成员的值会⾃动递增,且数字枚举还具备反向映射的特点。
481// 1. 定义⼀个描述【上下左右】⽅向的枚举Direction
2enum Direction {
3 Up, Down, Left, Right
4}
5
6// 2. 打印枚举
7console.log(Direction)
8/*
9{
10 0:'Up',
11 1:'Down',
12 2:'Left',
13 3:'Right',
14 Up:0,
15 Down:1,
16 Left:2,
17 Right:3
18}
19*/
20
21// 3. 反向映射
22console.log(Direction.Up)
23console.log(Direction[0])
24
25// 4. 不能修改枚举值
26Direction.Up = 'shang' // 此⾏代码报错,枚举中的属性是只读的
27
28// 5. 枚举值可在声明时指定,后续会依次递增
29enum Direction {
30 Up = 6, Down, Left, Right
31}
32
33// 6. 使用枚举
34function walk(n: Direction) {
35 if (n === Direction.Up) {
36 console.log("向【上】⾛");
37 } else if (n === Direction.Down) {
38 console.log("向【下】⾛");
39 } else if (n === Direction.Left) {
40 console.log("向【左】⾛");
41 } else if (n === Direction.Right) {
42 console.log("向【右】⾛");
43 } else {
44 console.log("未知⽅向");
45 }
46}
47walk(Direction.Up)
48walk(Direction.Down)
字符串枚举:指枚举值是字符串的枚举。
91enum Direction {
2 Up = "up",
3 Down = "down",
4 Left = "left",
5 Right = "right"
6}
7
8let dir: Direction = Direction.Up;
9console.log(dir); // 输出: "up"
常量枚举:⼀种特殊枚举类型,它使⽤ const
关键字定义,在编译时会被内联,避免⽣成⼀些额外的代码。
91// 1. 声明常量枚举
2const enum Directions { Up,Down, Left, Right}
3
4// 2. 使用常量枚举
5let x = Directions.Up;
6
7// 3. 生成后的JS文件,枚举值被内联
8"use strict";
9let x = 0 /* Directions.Up */;
type
可以为任意类型创建别名,让代码更简洁、可读性更强,同时能更⽅便地进⾏类型复⽤和扩展。
基本使用:类型别名使⽤ type 关键字定义, type 后跟类型名称:
81// 1. 给 number 类型起别名 num
2type num = number;
3
4// 2. 使用 num 类型声明变量
5let price: num
6
7// 3. 使用该变量
8price = 100
联合类型:是⼀种⾼级类型,它表示⼀个值可以是⼏种不同类型之⼀。
191// 1. 声明联合类型
2type Status = number | string // Status类型可以接收 number 或 string
3type Gender = '男' | '⼥' // Gender类型可以接接收 '男' 或 '⼥'
4
5// 2. 使用Status类型,可以接收 number 或 string
6function printStatus(status: Status) {
7 console.log(status);
8}
9printStatus(404);
10printStatus('200');
11printStatus('501');
12
13// 3. 使用Gender类型,可以接接收 '男' 或 '⼥'
14function logGender(str:Gender){
15 console.log(str)
16}
17logGender('男')
18logGender('⼥')
19
交叉类型:允许将多个类型合并为⼀个类型。合并后的类型将拥有所有被合并类型的成员。交叉类型通常⽤于对象类型。
241// 1. 对象类型1:⾯积
2type Area = {
3 height: number; //⾼
4 width: number; //宽
5};
6
7// 2. 对象类型2:地址
8type Address = {
9 num: number; //楼号
10 cell: number; //单元号
11 room: string; //房间号
12};
13
14// 3. 定义交叉类型House,由 Area 和 Address 交叉组成
15type House = Area & Address;
16
17// 4. 使用交叉类型
18const house: House = {
19 height: 180,
20 width: 75,
21 num: 6,
22 cell: 3,
23 room: '702'
24};
特殊情况:使用 type 定义的返回值为 void 的函数类型,无返回值为空的限制。
211// 1. 前面讲解void类型时可知,函数声明为void类型时,不能返回任何类型(undefined除外)
2function demo():void{
3}
4
5// 2. 但如果,使用 type 定义了一个返回值为 void 的函数类型
6type LogFunc = () => void
7
8// 3. 再使用该函数类型时,就没有返回值为空的限制了
9const f1: LogFunc = () => {
10 return 100; // 允许返回⾮空值
11};
12const f2: LogFunc = () => 200; // 允许返回⾮空值
13const f3: LogFunc = function () {
14 return 300; // 允许返回⾮空值
15};
16
17// 4. 这是 TS 为了兼容如下情况做出的特殊处理
18// Array.prototype.push 的返回值是⼀个数字,⽽ Array.prototype.forEach ⽅法期望其回调的返回类型是 void
19const src = [1, 2, 3];
20const dst = [0];
21src.forEach((el) => dst.push(el));
类型声明⽂件是 TypeScript 中的⼀种特殊⽂件,通常以 .d.ts
作为扩展名。它的主要作⽤是为现有的 JavaScript 代码提供类型信息,使得 TypeScript 能够在使⽤这些 JavaScript 库或模块时进⾏类型检查和提示。
181// demo.js
2export function add(a, b) {
3 return a + b;
4}
5export function mul(a, b) {
6 return a * b;
7}
8
9// demo.d.ts
10declare function add(a: number, b: number): number;
11declare function mul(a: number, b: number): number;
12export { add, mul };
13
14// index.ts
15import { add, mul } from "./demo.js";
16const x = add(2, 3); // x 类型为 number
17const y = mul(4, 5); // y 类型为 number
18console.log(x,y)
511// 1. 声明一个类
2class Person {
3 // 属性
4 public name: string
5 public age: number
6
7 // 构造器
8 constructor(name: string, age: number) {
9 this.name = name
10 this.age = age
11 }
12
13 // ⽅法
14 speak() {
15 console.log(`我叫:${this.name},今年${this.age}岁`)
16 }
17}
18
19// 2. 简写形式(简写时必须写修饰符,内部会自动生成this.xxx = xxx语句)
20class Person {
21 constructor(
22 public name: string,
23 public age: number) { }
24}
25
26// 3. 使用这个类
27const p1 = new Person('周杰伦', 38)
28
29// 4. 类的继承
30class Student extends Person {
31 // 子类属性
32 public grade: string
33
34 // 构造器
35 // 若Student类不需要额外的属性,Student的构造器可以省略
36 constructor(name: string, age: number, grade: string) {
37 super(name, age)
38 this.grade = grade
39 }
40
41 // 重写从⽗类继承的⽅法
42 override speak() {
43 console.log(`我是学⽣,我叫:${this.name},今年${this.age}岁,在读${this.grade}年级`)
44 }
45
46 // ⼦类⾃⼰的⽅法
47 study() {
48 console.log(`${this.name}正在努⼒学习中.....`)
49 }
50}
51
提示:
属性可以添加
public
、protected
、private
、readonly
等修饰符,默认为public
。
抽象类是⼀种⽆法被实例化的类,专⻔⽤来定义类的结构和⾏为,类中可以写抽象⽅法,也可以写具体实现。
291// 1. 声明一个抽象类
2abstract class Package {
3 constructor(public weight: number) { }
4
5 // 抽象⽅法:⽤来计算运费,不同类型包裹有不同的计算⽅式
6 abstract calculate(): number
7
8 // 通⽤⽅法:打印包裹详情
9 printPackage() {
10 console.log(`包裹重量为: ${this.weight}kg,运费为: ${this.calculate()}元`);
11 }
12}
13
14// 2. 声明一个具体类,继承抽象类
15class StandardPackage extends Package {
16 constructor(
17 weight: number,
18 public unitPrice: number // 每公⽄的固定费率
19 ) { super(weight) }
20
21 // 实现抽象⽅法:计算运费
22 calculate(): number {
23 return this.weight * this.unitPrice;
24 }
25}
26
27// 3. 使用具体类
28const s1 = new StandardPackage(10,5)
29s1.printPackage()
interface 是⼀种定义结构的⽅式,主要作⽤是为:类、对象、函数等规定⼀种契约,这样可以确保代码的⼀致性和类型安全,但要注意 interface 只能定义格式,不能包含任何实现 !
241// 1. 定义类的结构:PersonInterface接⼝,⽤与限制Person类的格式
2interface PersonInterface {
3 name: string age: number
4 speak(n: number): void
5}
6
7// 2. 创建符合类结构的实现类:定义⼀个类 Person,实现 PersonInterface 接⼝
8class Person implements PersonInterface {
9 constructor(
10 public name: string,
11 public age: number
12 ) { }
13
14 // 实现接⼝中的 speak ⽅法
15 speak(n: number): void {
16 for (let i = 0; i < n; i++) {
17 console.log(`你好,我叫${this.name},我的年龄是${this.age}`);
18 }
19 }
20}
21
22// 3. 使用实现类:创建⼀个 Person 类的实例 p1,传⼊名字 'tom' 和年龄 18
23const p1 = new Person('tom', 18);
24p1.speak(3)
161// 1. 定义对象结构
2interface UserInterface {
3 name: string
4 readonly gender: string // 只读属性
5 age?: number // 可选属性
6 run: (n: number) => void
7}
8
9// 2. 创建符合结构的对象
10const user: UserInterface = {
11 name: "张三",
12 gender: '男',
13 age: 18, run(n) {
14 console.log(`奔跑了${n}⽶`)
15 }
16};
101// 1. 定义函数结构
2interface CountInterface {
3 (a: number, b: number): number; // 2个number类型入参,返回值为number
4}
5
6// 2. 创建符合结构的函数
7const count: CountInterface = (x, y) => {
8 return x + y
9}
10
181// 1. 接口1
2interface PersonInterface {
3 name: string // 姓名
4 age: number // 年龄
5}
6
7// 2. 接口2继承接口1
8interface StudentInterface extends PersonInterface {
9 grade: string // 年级
10}
11
12// 3. 使用继承后的接口创建对象
13const stu: StudentInterface = {
14 name: "张三",
15 age: 25,
16 grade: '⾼三',
17}
18
301// 1. 第一次定义PersonInterface接⼝
2interface PersonInterface {
3 // 属性声明
4 name: string
5 age: number
6}
7
8// 2. 第二次定义PersonInterface接⼝:不是覆盖,而是添加新属性
9interface PersonInterface {
10 // ⽅法声明
11 speak(): void
12}
13
14// 3. 实现合并后的接口:Person类实现PersonInterface
15class Person implements PersonInterface {
16 name: string
17 age: number
18
19 // 构造器
20 constructor(name: string, age: number) {
21 this.name = name
22 this.age = age
23 }
24
25 // ⽅法
26 speak() {
27 console.log('你好!我是⽼师:', this.name)
28 }
29}
30
相同点: interface 和 type 都可以⽤于定义对象结构,在定义对象结构时两者可以互换。
不同点:
interface :更专注于定义对象和类的结构,⽀持继承、合并。
type :可以定义类型别名、联合类型、交叉类型,但不⽀持继承和⾃动合并
interface 和 type 都可以定义对象结构
321// 1. 使⽤ interface 定义 Person 对象
2interface PersonInterface {
3 ame: string;
4 age: number;
5 speak(): void;
6}
7
8// 2. 使⽤ type 定义 Person 对象
9type PersonType = {
10 name: string;
11 age: number;
12 speak(): void;
13};
14
15// 3. 使⽤PersonInterface
16/* let person: PersonInterface = {
17 name:'张三',
18 age:18,
19 speak(){
20 console.log(`我叫:${this.name},年龄:${this.age}`)
21 }
22} */
23
24// 4. 使⽤PersonType
25let person: PersonType = {
26 name:'张三',
27 age:18,
28 speak(){
29 console.log(`我叫:${this.name},年龄:${this.age}`)
30 }
31}
32
interface 可以继承、合并
261// 1. 定义接口
2interface PersonInterface {
3 name: string // 姓名
4 age: number // 年龄
5}
6
7// 2. 接口合并
8interface PersonInterface {
9 speak: () => void
10}
11
12// 3. 接口继承
13interface StudentInterface extends PersonInterface {
14 grade: string // 年级
15}
16
17// 4. 使用接口定义对象
18const student: StudentInterface = {
19 name: '李四',
20 age: 18,
21 grade: '⾼⼆',
22 speak() {
23 console.log(this.name,this.age,this.grade)
24 }
25}
26
type 的交叉类型
231// 1. 使⽤ type 定义 Person 类型,并通过交叉类型实现属性的合并
2type PersonType = {
3 name: string; // 姓名
4 age: number; // 年龄
5} & {
6 speak: () => void;
7};
8
9// 2. 使⽤ type 定义 Student 类型,并通过交叉类型继承 PersonType
10type StudentType = PersonType & {
11 grade: string; // 年级
12};
13
14// 3. 使用交叉类型定义对象
15const student: StudentType = {
16 name: '李四',
17 age: 18,
18 grade: '⾼⼆',
19 speak() {
20 console.log(this.name, this.age, this.grade);
21 }
22};
23
相同点:都能定义⼀个类的格式(定义类应遵循的契约)
不同点:
接⼝:只能描述结构,不能有任何实现代码,⼀个类可以实现多个接⼝。
抽象类:既可以包含抽象⽅法,也可以包含具体⽅法, ⼀个类只能继承⼀个抽象类
⼀个类可以实现多个接⼝
261// 1. FlyInterface 接⼝
2interface FlyInterface {
3 fly(): void;
4}
5
6// 2. 定义 SwimInterface 接⼝
7interface SwimInterface {
8 swim(): void;
9}
10
11// 3. Duck 类实现了 FlyInterface 和 SwimInterface 两个接⼝
12class Duck implements FlyInterface, SwimInterface {
13 fly(): void {
14 console.log('鸭⼦可以⻜');
15 }
16
17 swim(): void {
18 console.log('鸭⼦可以游泳');
19 }
20}
21
22// 4. 创建⼀个 Duck 实例
23const duck = new Duck();
24duck.fly(); // 输出: 鸭⼦可以⻜
25duck.swim(); // 输出: 鸭⼦可以游泳
26
泛型允许我们在定义函数、类或接⼝时,使⽤类型参数来表示未指定的类型,这些参数在具体使⽤时,才被指定具体的类型,泛型能让同⼀段代码适⽤于多种类型,同时仍然保持类型的安全性。
151// 1. 声明泛型函数
2function logData1<T>(data: T): T {
3 console.log(data)
4 return data
5}
6function logData2<T, U>(data1: T, data2: U): T | U {
7 console.log(data1,data2)
8 return Date.now() % 2 ? data1 : data2
9}
10
11// 2. 使用泛型函数(此处确定泛型类型)
12logData1<number>(100)
13logData1<string>('hello')
14logData2<number, string>(100, 'hello')
15logData2<string, boolean>('ok', false)
141// 1.声明泛型接口
2interface PersonInterface<T> {
3 name: string,
4 age: number,
5 extraInfo: T
6}
7
8// 2. 使用泛型接口声明变量(此处确定泛型类型)
9let p1: PersonInterface<string>
10let p2: PersonInterface<number>
11
12// 3. 变量赋值
13p1 = { name: '张三', age: 18, extraInfo: '⼀个好⼈' }
14p2 = { name: '李四', age: 18, extraInfo: 250 }
221// 1. 声明泛型类
2class Person<T> {
3 constructor(
4 public name: string,
5 public age: number,
6 public extraInfo: T) { }
7
8 speak() {
9 console.log(`我叫${this.name}今年${this.age}岁了`)
10 console.log(this.extraInfo)
11 }
12}
13
14// 2. 使用泛型类(此处确定泛型类型,泛型类型为number)
15const p1 = new Person<number>("tom", 30, 250);
16
17// 3. 使用泛型类(此处确定泛型类型,泛型类型为对象类型JobInfo)
18type JobInfo = {
19 title: string;
20 company: string;
21}
22const p2 = new Person<JobInfo>("tom", 30, { title: '研发总监', company: '发发发科技公司' });
131// 1. 声明接口类型
2interface LengthInterface {
3 length: number
4}
5
6// 2. 声明泛型函数,并约束传⼊的类型必须具有 length 属性(而非必须继承自LengthInterface)
7function logPerson<T extends LengthInterface>(data: T): void {
8 console.log(data.length)
9}
10
11// 3. 使用泛型函数
12logPerson<string>('hello') // OK:因为string具备length属性
13logPerson<number>(100) // 报错:因为number不具备length属性
装饰器本质是一种特殊的函数,它可以对:类、属性、方法、参数进行扩展,同时能让代码更简洁。
注意:
截止目前,装饰器依然是实验性特性 ,需要开发者手动调整
experimentalDecorators
配置,来开启装饰器支持。
类装饰器是一个应用在类声明上的函数,可以为类添加额外的功能,或添加额外的逻辑。
121/*
2 Demo函数会在Person类定义时执行
3 参数说明:
4 ○ target参数是被装饰的类,即:Person
5*/
6function Demo(target: Function) {
7 console.log(target)
8}
9
10// 使用装饰器
11@Demo
12class Person { }
定义一个装饰器,实现Person
实例调用toString
时返回JSON.stringify
的执行结果。
281// 使用装饰器重写toString方法 + 封闭其原型对象
2function CustomString(target: Function) {
3 // 向被装饰类的原型上添加自定义的 toString 方法
4 target.prototype.toString = function () {
5 return JSON.stringify(this)
6 }
7 // 封闭其原型对象,禁止随意操作其原型对象
8 Object.seal(target.prototype)
9}
10
11// 使用 CustomString 装饰器
12@CustomString
13class Person {
14 constructor(public name: string, public age: number) { }
15 speak() {
16 console.log('你好呀!')
17 }
18}
19
20/* 测试代码如下 */
21let p1 = new Person('张三', 18)
22console.log(p1.toString()) // 输出:{"name":"张三","age":18}
23// 禁止随意操作其原型对象
24interface Person {
25 a: any
26}
27// Person.prototype.a = 100 // 此行会报错:Cannot add property a, object is not extensible
28// console.log(p1.a)
设计一个LogTime
装饰器,可以给实例添加一个属性,用于记录实例对象的创建时间,再添加一个方法用于读取创建时间。
371// User接口
2interface User {
3 getTime(): Date
4 log(): void
5}
6
7// 自定义类型Class
8type Constructor = new (args: any[]) => {}
9
10// 创建一个装饰器,为类添加日志功能和创建时间
11function LogTime<T extends Constructor>(target: T) {
12 return class extends target {
13 createdTime: Date;
14 constructor(args: any[]) {
15 super(args);
16 this.createdTime = new Date(); // 记录对象创建时间
17 }
18 getTime() {
19 return `该对象创建时间为:${this.createdTime}`;
20 }
21 };
22}
23
24@LogTime
25class User {
26 constructor(
27 public name: string,
28 public age: number
29 ) { }
30 speak() {
31 console.log(`${this.name}说:你好啊!`)
32 }
33}
34
35const user1 = new User('张三', 13);
36user1.speak()
37console.log(user1.getTime())
类装饰器有返回值:若类装饰器返回一个新的类,那这个新类将替换掉被装饰的类。
类装饰器无返回值:若类装饰器无返回值或返回undefined
,那被装饰的类不会被替换。
191function demo(target:Function){
2 // 装饰器有返回值时,该返回值会替换掉被装饰的类
3 return class {
4 test(){
5 console.log(200)
6 console.log(300)
7 console.log(400)
8 }
9 }
10}
11
12@demo
13class Person {
14 test(){
15 console.log(100)
16 }
17}
18
19console.log(Person)
在 TypeScript 中,Function
类型所表示的范围十分广泛,包括:普通函数、箭头函数、方法等等。但并非Function
类型的函数都可以被 new
关键字实例化,例如箭头函数是不能被实例化的,那么 TypeScript 中概如何声明一个构造类型呢?有以下两种方式:
121// 定义Constructor类型,其含义是构造类型
2/*
3 ○ new 表示:该类型是可以用new操作符调用。
4 ○ ...args 表示:构造器可以接受【任意数量】的参数。
5 ○ any[] 表示:构造器可以接受【任意类型】的参数。
6 ○ {} 表示:返回类型是对象(非null、非undefined的对象)。
7*/
8type Constructor = new (args: any[]) => {};
9
10function test(fn:Constructor){}
11class Person {}
12test(Person)
111// 定义一个构造类型,且包含一个静态属性 wife
2type Constructor = {
3 new(args: any[]): {}; // 构造签名
4 wife: string; // wife属性
5};
6
7function test(fn:Constructor){}
8class Person {
9 static wife = 'asd'
10}
11test(Person)
装饰器工厂是一个返回装饰器函数的函数,可以为装饰器添加参数,可以更灵活地控制装饰器的行为。
案例:定义一个LogInfo
类装饰器工厂,实现Person
实例可以调用到introduce
方法,且introduce
中输出内容的次数,由LogInfo
接收的参数决定。
311interface Person {
2 introduce: () => void
3}
4
5// 定义一个装饰器工厂 LogInfo,它接受一个参数 n,返回一个类装饰器
6function LogInfo(n:number) {
7 // 装饰器函数,target 是被装饰的类
8 return function(target: Function){
9 target.prototype.introduce = function () {
10 for (let i = 0; i < n; i++) {
11 console.log(`我的名字:${this.name},我的年龄:${this.age}`)
12 }
13 }
14 }
15}
16
17@LogInfo(5)
18class Person {
19 constructor(
20 public name: string,
21 public age: number
22 ) { }
23 speak() {
24 console.log('你好呀!')
25 }
26}
27
28let p1 = new Person('张三', 18)
29// console.log(p1) // 打印的p1是:_classThis,转换的JS版本比较旧时,会出现,不必纠结
30p1.speak()
31p1.introduce()
装饰器可以组合使用,执行顺序为:
先【由上到下】的执行所有的装饰器工厂,依次获取到装饰器。
再【由下到上】执行所有的装饰器。
381//装饰器
2function test1(target:Function) {
3 console.log('test1')
4}
5//装饰器工厂
6function test2() {
7 console.log('test2工厂')
8 return function (target:Function) {
9 console.log('test2')
10 }
11}
12//装饰器工厂
13function test3() {
14 console.log('test3工厂')
15 return function (target:Function) {
16 console.log('test3')
17 }
18}
19//装饰器
20function test4(target:Function) {
21 console.log('test4')
22}
23
24@test1
25@test2()
26@test3()
27@test4
28class Person { }
29
30/*
31 控制台打印:
32 test2工厂
33 test3工厂
34 test4
35 test3
36 test2
37 test1
38*/
211/*
2 参数说明:
3 ○ target: 对于静态属性来说值是类,对于实例属性来说值是类的原型对象。
4 ○ propertyKey: 属性名。
5*/
6function Demo(target: object, propertyKey: string) {
7 console.log(target,propertyKey)
8}
9
10class Person {
11 @Demo name: string
12 @Demo age: number
13 @Demo static school:string
14
15 constructor(name: string, age: number) {
16 this.name = name
17 this.age = age
18 }
19}
20
21const p1 = new Person('张三', 18)
定义一个State
属性装饰器,来监视属性的修改。
401// 声明一个装饰器函数 State,用于捕获数据的修改
2function State(target: object, propertyKey: string) {
3 // 存储属性的内部值
4 let key = `__${propertyKey}`;
5
6 // 使用 Object.defineProperty 替换类的原始属性
7 // 重新定义属性,使其使用自定义的 getter 和 setter
8 Object.defineProperty(target, propertyKey, {
9 get () {
10 return this[key]
11 },
12 set(newVal: string){
13 console.log(`${propertyKey}的最新值为:${newVal}`);
14 this[key] = newVal
15 },
16 enumerable: true,
17 configurable: true,
18 });
19}
20
21class Person {
22 name: string;
23 //使用State装饰器
24 @State age: number;
25 school = 'atguigu';
26 constructor(name: string, age: number) {
27 this.name = name;
28 this.age = age;
29 }
30}
31
32const p1 = new Person('张三', 18);
33const p2 = new Person('李四', 30);
34
35p1.age = 80
36p2.age = 90
37
38console.log('------------------')
39console.log(p1.age) //80
40console.log(p2.age) //90
如下代码中,当构造器中的this.age = age
试图在实例上赋值时,实际上是调用了原型上age
属性的set
方法。
231class Person {
2 name: string
3 age: number
4 constructor(name: string, age: number) {
5 this.name = name
6 this.age = age
7 }
8}
9
10let value = 99
11// 使用defineProperty给Person原型添加age属性,并配置对应的get与set
12Object.defineProperty(Person.prototype, 'age', {
13 get() {
14 return value
15 },
16 set(val) {
17 value = val
18 }
19})
20
21const p1 = new Person('张三', 18)
22console.log(p1.age) //18
23console.log(Person.prototype.age)//18
291/*
2 参数说明:
3 ○ target: 对于静态方法来说值是类,对于实例方法来说值是原型对象。
4 ○ propertyKey:方法的名称。
5 ○ descriptor: 方法的描述对象,其中value属性是被装饰的方法。
6*/
7function Demo(target: object, propertyKey: string, descriptor: PropertyDescriptor){
8 console.log(target)
9 console.log(propertyKey)
10 console.log(descriptor)
11}
12
13class Person {
14 constructor(
15 public name:string,
16 public age:number,
17 ){}
18 // Demo装饰实例方法
19 @Demo speak(){
20 console.log(`你好,我的名字:${this.name},我的年龄:${this.age}`)
21 }
22 // Demo装饰静态方法
23 @Demo static isAdult(age:number) {
24 return age >= 18;
25 }
26}
27
28const p1 = new Person('张三',18)
29p1.speak()
定义一个Logger
方法装饰器,用于在方法执行前和执行后,均追加一些额外逻辑。
定义一个Validate
方法装饰器,用于验证数据。
451function Logger(target: object, propertyKey: string, descriptor: PropertyDescriptor){
2 // 保存原始方法
3 const original = descriptor.value;
4 // 替换原始方法
5 descriptor.value = function (args:any[]) {
6 console.log(`${propertyKey}开始执行......`)
7 const result = original.call(this, args)
8 console.log(`${propertyKey}执行完毕......`)
9 return result;
10 }
11}
12
13function Validate(maxValue:number){
14 return function (target: object, propertyKey: string, descriptor: PropertyDescriptor){
15 // 保存原始方法
16 const original = descriptor.value;
17 // 替换原始方法
18 descriptor.value = function (args: any[]) {
19 // 自定义的验证逻辑
20 if (args[0] > maxValue) {
21 throw new Error('年龄非法!')
22 }
23 // 如果所有参数都符合要求,则调用原始方法
24 return original.apply(this, args);
25 };
26 }
27}
28
29class Person {
30 constructor(
31 public name:string,
32 public age:number,
33 ){}
34 @Logger speak(){
35 console.log(`你好,我的名字:${this.name},我的年龄:${this.age}`)
36 }
37 @Validate(120)
38 static isAdult(age:number) {
39 return age >= 18;
40 }
41}
42
43const p1 = new Person('张三',18)
44p1.speak()
45console.log(Person.isAdult(100))
241/*
2 参数说明:
3 ○ target:
4 1. 对于实例访问器来说值是【所属类的原型对象】。
5 2. 对于静态访问器来说值是【所属类】。
6 ○ propertyKey:访问器的名称。
7 ○ descriptor: 描述对象。
8*/
9function Demo(target: object, propertyKey: string, descriptor: PropertyDescriptor) {
10 console.log(target)
11 console.log(propertyKey)
12 console.log(descriptor)
13}
14
15class Person {
16 @Demo
17 get address(){
18 return '北京宏福科技园'
19 }
20 @Demo
21 static get country(){
22 return '中国'
23 }
24}
对Weather
类的temp
属性的set
访问器进行限制,设置的最低温度-50
,最高温度50
。
401function RangeValidate(min: number, max: number) {
2 return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) {
3 // 保存原始的 setter 方法,以便在后续调用中使用
4 const originalSetter = descriptor.set;
5
6 // 重写 setter 方法,加入范围验证逻辑
7 descriptor.set = function (value: number) {
8 // 检查设置的值是否在指定的最小值和最大值之间
9 if (value < min || value > max) {
10 // 如果值不在范围内,抛出错误
11 throw new Error(`${propertyKey}的值应该在 ${min} 到 ${max}之间!`);
12 }
13
14 // 如果值在范围内,且原始 setter 方法存在,则调用原始 setter 方法
15 if (originalSetter) {
16 originalSetter.call(this, value);
17 }
18 };
19 };
20}
21
22class Weather {
23 private _temp: number;
24 constructor(_temp: number) {
25 this._temp = _temp;
26 }
27 // 设置温度范围在 -50 到 50 之间
28 @RangeValidate(-50,50)
29 set temp(value) {
30 this._temp = value;
31 }
32 get temp() {
33 return this._temp;
34 }
35}
36
37const w1 = new Weather(25);
38console.log(w1)
39w1.temp = 67
40console.log(w1)
211/*
2 参数说明:
3 ○ target:
4 1.如果修饰的是【实例方法】的参数,target 是类的【原型对象】。
5 2.如果修饰的是【静态方法】的参数,target 是【类】。
6 ○ propertyKey:参数所在的方法的名称。
7 ○ parameterIndex: 参数在函数参数列表中的索引,从 0 开始。
8*/
9function Demo(target: object, propertyKey: string, parameterIndex: number) {
10 console.log(target)
11 console.log(propertyKey)
12 console.log(parameterIndex)
13}
14
15// 类定义
16class Person {
17 constructor(public name: string) { }
18 speak(@Demo message1: any, mesage2: any) {
19 console.log(`${this.name}想对说:${message1},${mesage2}`);
20 }
21}
431function NotNumber(target: any, propertyKey: string, parameterIndex: number) {
2 // 初始化或获取当前方法的参数索引列表
3 let notNumberArr: number[] = target[`__notNumber_${propertyKey}`] || [];
4 // 将当前参数索引添加到列表中
5 notNumberArr.push(parameterIndex);
6 // 将列表存储回目标对象
7 target[`__notNumber_${propertyKey}`] = notNumberArr;
8}
9
10// 方法装饰器定义
11function Validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
12 const method = descriptor.value;
13 descriptor.value = function (args: any[]) {
14 // 获取被标记为不能为空的参数索引列表
15 const notNumberArr: number[] = target[`__notNumber_${propertyKey}`] || [];
16 // 检查参数是否为 null 或 undefined
17 for (const index of notNumberArr) {
18 if (typeof args[index] === 'number') {
19 throw new Error(`方法 ${propertyKey} 中索引为 ${index} 的参数不能是数字!`)
20 }
21 }
22 // 调用原始方法
23 return method.apply(this, args);
24 };
25
26 return descriptor;
27}
28
29// 类定义
30class Student {
31 name: string;
32 constructor(name: string) {
33 this.name = name;
34 }
35 @Validate
36 speak(@NotNumber message1: any, mesage2: any) {
37 console.log(`${this.name}想对说:${message1},${mesage2}`);
38 }
39}
40
41// 使用
42const s1 = new Student("张三");
43s1.speak(100, 200);
Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML、CSS、JavaScript开发的简洁、直观、强悍的响应式前端开发框架,使得Web开发更加快捷。
首先从官网下载Bootstrap压缩包,解压后复制到项目中,然后在HTML页面引入相关资源进行使用。
251
2<html lang="zh-CN">
3<head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7 <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
8
9 <title>Bootstrap HelloWorld</title>
10
11 <!-- Bootstrap -->
12 <link href="css/bootstrap.min.css" rel="stylesheet">
13
14 <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
15 <script src="js/jquery-3.2.1.min.js"></script>
16
17 <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
18 <script src="js/bootstrap.min.js"></script>
19</head>
20<body>
21<h1>你好,世界!</h1>
22
23</body>
24</html>
25
更多资料请参考Bootstrap官网https://www.bootcss.com/。
Jquery 是一个快速、简洁的JavaScript框架,封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。
首先从官网(https://jquery.com/)下载JQuery,然后在HTML中引入jquery-3.3.1.js
或jquery-3.3.1.min.js
文件。
271
2<html>
3<head>
4<script src='./jquery-3.3.1.js'></script>
5</head>
6<body>
7<div id = "demo"> Hello, JQuery! </div>
8<div> 官网:https://jquery.com </div>
9</body>
10<script>
11 // 入口函数(类似于window.onload)
12 $(function () {
13 var $demo = $('#demo'); // 获取id为demo的标签
14 console.log($demo.html()); // 获取标签体内容
15
16 // JQ对象 -> JS对象
17 var $divs = $("div"); // 所有的DIV标签 => JQ对象
18 var div0 = $divs[0]; // JS对象
19 var div1 = $divs.get(1); // JS对象
20
21 // JS对象 -> JQ对象
22 var demo = document.getElementById("demo"); // id为demo的标签 => JS对象
23 var $demo = $(demo);
24
25 });
26</script>
27</html>
441// id选择器
2$("#one").css("backgroundColor","pink");
3
4// 元素选择器
5$("div").css("backgroundColor","pink");
6
7// 类选择器
8$(".mini").css("backgroundColor","pink");
9
10// 选择器并集
11$("span,#two").css("backgroundColor","pink"); // 所有的<span>元素和id为two的元素
12
13// 后代选择器
14$("body div").css("backgroundColor","pink");
15
16// 子代选择器
17$("body > div").css("backgroundColor","pink");
18
19// 属性选择器
20$("div[title]").css("backgroundColor","pink");
21$("div[title='test']").css("backgroundColor","pink");
22$("div[title!='test']").css("backgroundColor","pink");
23$("div[title^='te']").css("backgroundColor","pink"); // title属性以te开头的div标签
24$("div[title$='est']").css("backgroundColor","pink"); // title属性以est结尾的div标签
25$("div[title*='es']").css("backgroundColor","pink"); // title属性含有es的div标签
26$("div[id][title*='es']").css("backgroundColor","pink"); // 存在id属性,且title属性含有es的div标签
27
28// 伪类与伪元素
29$("div:first").css("backgroundColor","pink"); // 第一个DIV标签
30$("div:last").css("backgroundColor","pink"); // 最后一个DIV标签
31$("div:not(.one)").css("backgroundColor","pink"); // 不含one属性的DIV标签
32$("div:even").css("backgroundColor","pink"); // 索引为偶数的DIV标签
33$("div:odd").css("backgroundColor","pink"); // 索引为奇数的DIV标签
34$("div:gt(3)").css("backgroundColor","pink"); // 索引>3的DIV标签
35$("div:eq(3)").css("backgroundColor","pink"); // 索引=3的DIV标签
36$("div:lt(3)").css("backgroundColor","pink"); // 索引<3的DIV标签
37$(":header").css("backgroundColor","pink");
38
39// 有关表单的伪类与伪元素
40$("input[type='text']:enabled").val("aaa"); // enabled 获得可用元素
41$("input[type='text']:disabled").val("aaa"); // disabled 获得不可用元素
42alert($("input[type='checkbox']:checked").length); // checked 获得单选/复选框选中的元素
43alert($("#job > option:selected").length); // selected 获得下拉框选中的元素
44
381// 原生JS方式
2for (var i = 0; i < citys.length; i++) {
3 if("上海" == citys[i].innerHTML){
4 break; 结束循环
5 }
6
7 alert(i+":"+citys[i].innerHTML);
8}
9
10
11// JQ.each(callback)方式
12citys.each(function (index,element) {
13 //获取li对象 第一种方式 this
14 //alert(this.innerHTML);
15 //alert($(this).html());
16
17 //获取li对象 第二种方式 在回调函数中定义参数 index(索引) element(元素对象)
18 //alert(index+":"+element.innerHTML);
19 //alert(index+":"+$(element).html());
20
21 //判断如果是上海,则结束循环
22 if("上海" == $(element).html()){
23 return true; //返回true,结束本次循环,继续下次循环(continue)
24 }
25
26 alert(index+":"+$(element).html());
27});
28
29// $.each(object, [callback])方式
30$.each(citys,function () {
31 alert($(this).html());
32});
33
34// for..of方式(jquery3.0+)
35for(li of citys){
36 alert($(li).html());
37}
38
271// 内容操作
2$(function () {
3 // 获取和设置value属性
4 var value = $("#myinput").val();
5 $("#myinput").val("李四");
6
7 // 获取和设置innerHTML
8 var html = $("#mydiv").html();
9 $("#mydiv").html("<p>aaaa</p>");
10
11 // 获取和设置innerText
12 var text = $("#mydiv").text();
13 $("#mydiv").text("bbb");
14});
15
16// 属性操作
17$(function () {
18 // 固有属性操作 attr()/removeAttr()
19 var name = $("#bj").attr("name");
20 $("#bj").attr("name","dabeijing");
21 $("#bj").removeAttr("name");
22
23 // 自定义属性操作 prop()/removeProp()
24 var checked = $("#hobby").prop("checked");
25 //var checked = $("#hobby").attr("checked"); //获取不到,弹出undefined
26});
27
301$(function () {
2 //<input type="button" value="采用属性增加样式(改变id=one的样式)" id="b1"/>
3 $("#b1").click(function () {
4 $("#one").prop("class","second");
5 });
6 //<input type="button" value=" addClass" id="b2"/>
7 $("#b2").click(function () {
8 $("#one").addClass("second");
9 });
10 //<input type="button" value="removeClass" id="b3"/>
11 $("#b3").click(function () {
12 $("#one").removeClass("second");
13 });
14 //<input type="button" value=" 切换样式" id="b4"/>
15 $("#b4").click(function () {
16 $("#one").toggleClass("second");
17 });
18 //<input type="button" value=" 通过css()获得id为one背景颜色" id="b5"/>
19 $("#b5").click(function () {
20 var backgroundColor = $("#one").css("backgroundColor");
21 alert(backgroundColor);
22
23 });
24 //<input type="button" value=" 通过css()设置id为one背景颜色为绿色" id="b6"/>
25 $("#b6").click(function () {
26 $("#one").css("backgroundColor","green");
27
28 });
29});
30
1911) 父子关系
2对象1.append(对象2) //对象1追加对象2内部
3对象1.prepend(对象2) //对象1前追加对象2内部
4
5对象2.appendTo(对象1) //对象2追加到对象1内部
6对象2.prependTo(对象1) //对象2前追加到对象1内部
7
82) 兄弟关系
9对象1.after(对象2) //对象1后跟对象2
10对象1.before(对象2) //对象1前跟对象2
11
12对象2.insertAfter(对象1) //对象2插入到对象1后
13对象2.insertBefore(对象1) //对象2插入到对象1前
14
153) 删除元素
16对象.remove() //将对象删除掉
17对象.empty() //将对象的后代元素全部清空,但是保留当前对象以及其属性节点
18
19
411// 标签显示与隐藏(speed-动画速度(slow、normal、fast、毫秒值),easing-切换效果(swing-慢快慢、linear-匀速),fn-动画完成回调函数)
2show/slideDown/fadeIn([speed,[easing],[fn]]) // 显示
3hide/slideUp/fadeOut([speed,[easing],[fn]]) // 隐藏
4toggle/slideToggle/fadeToggle([speed],[easing],[fn]) // 切换
5
6//隐藏div
7function hideFn(){
8 //默认方式
9 $("showDiv").hide(5000,"swing");
10
11 //滑动方式
12 $("showDiv").slideUp("slow");
13
14 //淡入淡出方式
15 $("showDiv").fadeOut("slow");
16}
17
18//显示div
19function showFn(){
20 //默认方式
21 $("showDiv").show(5000,"linear");
22
23 //滑动方式
24 $("showDiv").slideDown("slow");
25
26 //淡入淡出方式
27 $("showDiv").fadeIn("slow");
28}
29
30//切换div
31function toggleFn(){
32 //默认方式
33 $("showDiv").toggle("slow");
34
35 //滑动方式
36 $("showDiv").slideToggle("slow");
37
38 //淡入淡出方式
39 $("showDiv").fadeToggle("slow");
40}
41
591// 方式一:JQ对象.事件名称(callback),如果callback为空,则触发默认事件,如submit()触发表单提交
2$(function () {
3 //获取name对象,绑定click事件
4 $("name").click(function () {
5 alert("我被点击了...")
6 });
7
8 //给name绑定鼠标移动到元素之上事件。绑定鼠标移出事件
9 $("name").mouseover(function () {
10 alert("鼠标来了...")
11 });
12
13 $("name").mouseout(function () {
14 alert("鼠标走了...")
15 });
16
17 //简化操作,链式编程
18 $("name").mouseover(function () {
19 alert("鼠标来了...")
20 }).mouseout(function () {
21 alert("鼠标走了...")
22 });
23
24 //让文本输入框获得焦点
25 alert("我要获得焦点了...")
26 $("name").focus();
27});
28
29// 方式二:jq对象.on("事件名称",回调函数)/jq对象.off("事件名称"),如果off方法不传递任何参数,则将组件上的所有事件全部解绑
30$(function () {
31 //使用on给按钮绑定单击事件
32 $("btn").on("click",function () {
33 alert("我被点击了。。。")
34 }) ;
35
36 //使用off解除btn按钮的单击事件
37 $("btn2").click(function () {
38 //解除btn按钮的单击事件
39 $("btn").off("click");
40
41 //将组件上的所有事件全部解绑
42 $("btn").off();
43 });
44});
45
46// 方式三:jq对象.toggle(fn1,fn2...),当单击jq对象对应的组件后,会执行fn1.第二次点击会执行fn2.....
47// 注意:1.9版本 .toggle() 方法删除,jQuery Migrate(迁移)插件可以恢复此功能。引入方法如下:
48// <script src="../js/jquery-migrate-1.0.0.js" type="text/" charset="utf-8"></script>
49$(function () {
50 //获取按钮,调用toggle方法
51 $("btn").toggle(function () {
52 //改变div背景色backgroundColor 颜色为 green
53 $("myDiv").css("backgroundColor","green");
54 },function () {
55 //改变div背景色backgroundColor 颜色为 pink
56 $("myDiv").css("backgroundColor","pink");
57 });
58});
59
361// $.fn.extend(object) 增强通过Jquery获取的对象的功能,如:$("id")
2
3//案例:使用jquery插件 给jq对象添加2个方法 check()选中所有复选框,uncheck()取消选中所有复选框
4
5//定义jqeury的对象插件,增强JQuery获取的对象
6$.fn.extend({
7 //定义了一个check()方法。所有的jq对象都可以调用该方法
8 check:function () {
9 // 让复选框选中
10 this.prop("checked",true); //this:调用该方法的jq对象
11 },
12 uncheck:function () {
13 // 让复选框不选中
14 this.prop("checked",false);
15 }
16
17});
18
19// 调用增强的方法
20$(function () {
21 // 获取按钮
22 //$("btn-check").check(); //复选框对象.check();
23
24 $("btn-check").click(function () {
25 //全选
26 $("input[type='checkbox']").check();
27
28 });
29
30 $("btn-uncheck").click(function () {
31 //全不选
32 $("input[type='checkbox']").uncheck();
33
34 });
35});
36
211// $.extend(object) 增强JQeury对象自身的功能,如:$/jQuery
2
3//案例:对全局方法扩展2个方法。扩展min()方法,求2个值的最小值;扩展max()方法,求2个值最大值
4$.extend({
5 max:function (a,b) {
6 //返回两数中的较大值
7 return a >= b ? a:b;
8 },
9 min:function (a,b) {
10 //返回两数中的较小值
11 return a <= b ? a:b;
12 }
13});
14
15//调用全局方法
16var max = $.max(4,3);
17alert(max);
18
19var min = $.min(1,2);
20alert(min);
21
501// 通用方式:$.ajax(json)
2function fun() {
3 //使用$.ajax()发送异步请求
4
5 $.ajax({
6 url:"ajaxServlet1111" , // 请求路径
7 type:"POST" , //请求方式
8 //data: "username=jack&age=23",//请求参数
9 data:{"username":"jack","age":23},
10 success:function (data) {
11 alert(data);
12 },//响应成功后的回调函数
13 error:function () {
14 alert("出错啦...")
15 },//表示如果请求响应出现错误,会执行的回调函数
16
17 dataType:"text"//设置接受到的响应数据的格式
18 });
19}
20
21
22// 发送GET请求:$.get()
23function fun() {
24 /* 语法:$.get(url, [data], [callback], [type])
25 * url:请求路径
26 * data:请求参数
27 * callback:回调函数
28 * type:响应结果的类型
29 */
30
31 $.get("ajaxServlet",{username:"rose"},function (data) {
32 alert(data);
33 },"text");
34}
35
36
37// 发送POST请求:$.post()
38function fun() {
39/* 语法:$.post(url, [data], [callback], [type])
40 * url:请求路径
41 * data:请求参数
42 * callback:回调函数
43 * type:响应结果的类型
44*/
45
46 $.post("ajaxServlet",{username:"rose"},function (data) {
47 alert(data);
48 },"text");
49}
50
Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。
安装方式如下:
11npm install axios
使用方式如下:
31import axios from "axios"
2axios.get('/user')
3 .then(res => console.log(resp.data))
281// 1. 发送Get请求
2axios.get('/user?ID=12345')
3 .then(function (response) {
4 // 处理成功情况
5 console.log(response);
6 })
7 .catch(function (error) {
8 // 处理错误情况
9 console.log(error);
10 })
11 .finally(function () {
12 // 总是会执行
13 });
14
15// 2. 发送Get请求(参数单独设置)
16axios.get('/user', {
17 params: {
18 ID: 12345
19 }
20 })
21 .then(function (response) {
22 console.log(response);
23 })
24 .catch(function (error) {
25 console.log(error);
26 })
27 .finally(function () {
28 });
111// 1. 发送Post请求(请求体中的数据将默认以json方式提交)
2axios.post('/user', {
3 firstName: 'Fred',
4 lastName: 'Flintstone'
5})
6.then(function (response) {
7 console.log(response);
8})
9.catch(function (error) {
10 console.log(error);
11});
231{
2 // `data` 由服务器提供的响应
3 data: {},
4
5 // `status` 来自服务器响应的 HTTP 状态码
6 status: 200,
7
8 // `statusText` 来自服务器响应的 HTTP 状态信息
9 statusText: 'OK',
10
11 // `headers` 是服务器响应头
12 // 所有的 header 名称都是小写,而且可以使用方括号语法访问
13 // 例如: `response.headers['content-type']`
14 headers: {},
15
16 // `config` 是 `axios` 请求的配置信息
17 config: {},
18
19 // `request` 是生成此响应的请求
20 // 在node.js中它是最后一个ClientRequest实例 (in redirects),
21 // 在浏览器中则是 XMLHttpRequest 实例
22 request: {}
23}
1681const instance = axios.create({
2 baseURL: 'https://some-domain.com/api/',
3 timeout: 1000,
4 headers: {'X-Custom-Header': 'foobar'}
5});
6
7//可用的配置项如下:
8{
9 // `url` 是用于请求的服务器 URL
10 url: '/user',
11
12 // `method` 是创建请求时使用的方法
13 method: 'get', // 默认值
14
15 // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
16 // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
17 baseURL: 'https://some-domain.com/api/',
18
19 // `transformRequest` 允许在向服务器发送前,修改请求数据
20 // 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
21 // 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
22 // 你可以修改请求头。
23 transformRequest: [function (data, headers) {
24 // 对发送的 data 进行任意转换处理
25
26 return data;
27 }],
28
29 // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
30 transformResponse: [function (data) {
31 // 对接收的 data 进行任意转换处理
32
33 return data;
34 }],
35
36 // 自定义请求头
37 headers: {'X-Requested-With': 'XMLHttpRequest'},
38
39 // `params` 是与请求一起发送的 URL 参数
40 // 必须是一个简单对象或 URLSearchParams 对象
41 params: {
42 ID: 12345
43 },
44
45 // `paramsSerializer`是可选方法,主要用于序列化`params`
46 // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
47 paramsSerializer: function (params) {
48 return Qs.stringify(params, {arrayFormat: 'brackets'})
49 },
50
51 // `data` 是作为请求体被发送的数据
52 // 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
53 // 在没有设置 `transformRequest` 时,则必须是以下类型之一:
54 // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
55 // - 浏览器专属: FormData, File, Blob
56 // - Node 专属: Stream, Buffer
57 data: {
58 firstName: 'Fred'
59 },
60
61 // 发送请求体数据的可选语法
62 // 请求方式 post
63 // 只有 value 会被发送,key 则不会
64 data: 'Country=Brasil&City=Belo Horizonte',
65
66 // `timeout` 指定请求超时的毫秒数。
67 // 如果请求时间超过 `timeout` 的值,则请求会被中断
68 timeout: 1000, // 默认值是 `0` (永不超时)
69
70 // `withCredentials` 表示跨域请求时是否需要使用凭证
71 withCredentials: false, // default
72
73 // `adapter` 允许自定义处理请求,这使测试更加容易。
74 // 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
75 adapter: function (config) {
76 /* ... */
77 },
78
79 // `auth` HTTP Basic Auth
80 auth: {
81 username: 'janedoe',
82 password: 's00pers3cret'
83 },
84
85 // `responseType` 表示浏览器将要响应的数据类型
86 // 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
87 // 浏览器专属:'blob'
88 responseType: 'json', // 默认值
89
90 // `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
91 // 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
92 // Note: Ignored for `responseType` of 'stream' or client-side requests
93 responseEncoding: 'utf8', // 默认值
94
95 // `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
96 xsrfCookieName: 'XSRF-TOKEN', // 默认值
97
98 // `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
99 xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值
100
101 // `onUploadProgress` 允许为上传处理进度事件
102 // 浏览器专属
103 onUploadProgress: function (progressEvent) {
104 // 处理原生进度事件
105 },
106
107 // `onDownloadProgress` 允许为下载处理进度事件
108 // 浏览器专属
109 onDownloadProgress: function (progressEvent) {
110 // 处理原生进度事件
111 },
112
113 // `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
114 maxContentLength: 2000,
115
116 // `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
117 maxBodyLength: 2000,
118
119 // `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。
120 // 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
121 // 则promise 将会 resolved,否则是 rejected。
122 validateStatus: function (status) {
123 return status >= 200 && status < 300; // 默认值
124 },
125
126 // `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
127 // 如果设置为0,则不会进行重定向
128 maxRedirects: 5, // 默认值
129
130 // `socketPath` 定义了在node.js中使用的UNIX套接字。
131 // e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
132 // 只能指定 `socketPath` 或 `proxy` 。
133 // 若都指定,这使用 `socketPath` 。
134 socketPath: null, // default
135
136 // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
137 // and https requests, respectively, in node.js. This allows options to be added like
138 // `keepAlive` that are not enabled by default.
139 httpAgent: new http.Agent({ keepAlive: true }),
140 httpsAgent: new https.Agent({ keepAlive: true }),
141
142 // `proxy` 定义了代理服务器的主机名,端口和协议。
143 // 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
144 // 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
145 // `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
146 // 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
147 // 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
148 proxy: {
149 protocol: 'https',
150 host: '127.0.0.1',
151 port: 9000,
152 auth: {
153 username: 'mikeymike',
154 password: 'rapunz3l'
155 }
156 },
157
158 // see https://axios-http.com/zh/docs/cancellation
159 cancelToken: new CancelToken(function (cancel) {
160 }),
161
162 // `decompress` indicates whether or not the response body should be decompressed
163 // automatically. If set to `true` will also remove the 'content-encoding' header
164 // from the responses objects of all decompressed responses
165 // - Node only (XHR cannot turn off decompression)
166 decompress: true // 默认值
167
168}
191// 添加请求拦截器
2axios.interceptors.request.use(function (config) {
3 // 在发送请求之前做些什么
4 return config;
5 }, function (error) {
6 // 对请求错误做些什么
7 return Promise.reject(error);
8 });
9
10// 添加响应拦截器
11axios.interceptors.response.use(function (response) {
12 // 2xx 范围内的状态码都会触发该函数。
13 // 对响应数据做点什么
14 return response;
15 }, function (error) {
16 // 超出 2xx 范围的状态码都会触发该函数。
17 // 对响应错误做点什么
18 return Promise.reject(error);
19 });
Vite是一个前端工具链,官网:https://cn.vitejs.dev ,主要功能如下:
快速创建前端项目脚手架。
统一的工程化规范:目录结构、代码规范、git提交规范 等。
自动化构建和部署:前端脚手架可以自动进行代码打包、压缩、合并、编译等常见的构建工作,可以通过集成自动化部署脚本,自动将代码部署到测试、生产环境等;
171# 创建项目
2npm create vite # 根据向导选择技术栈
3
4# 安装依赖
5npm install # 安装项目所有依赖
6npm install axios # 安装指定依赖到当前项目
7npm install -g xxx # 全局安装
8
9# 项目启动
10npm run dev #启动项目
11
12# 项目打包
13npm run build #构建后 生成 dist 文件夹
14
15# 项目部署
16# 前后分离方式:需要把 dist 文件夹内容部署到如 nginx 之类的服务器上。
17# 前后不分离方式:把 dist 文件夹内容复制到 SpringBoot 项目 resources 下面