
(原始导出文件的标题是「Python学习——前端版」,但这份文档记的全是前端内容: HTML / CSS / 布局 / JavaScript / Ajax / Promise。课程名带「Python」只是当时的课程命名, 标题在这里按实际内容改了一下,方便以后翻回来时不用猜。)
用户交互,数据交互
html不会报错,会强行修改代码,执行的未必就是写的代码
右击文件资源管理器
超文本标记语言,是构成web页面的基本元素
1<!-- 注释 -->
2
<!-- ctrl+/ -->
xxxxxxxxxx
2
1
<单标签名>
2
<单标签 />
xxxxxxxxxx
1
1
<双标签名></双标签名>
xxxxxxxxxx
5
1
<双标签名>
2
<还是双标签名>
3
<放一个单标签 />
4
</还是双标签名>
5
</双标签名>
xxxxxxxxxx
1
1
<!--感叹号后回车就可使用-->
xxxxxxxxxx
61
1
2
<!--
3
1.标签类型:单标签
4
2.标签名:!DOCTYPE
5
3.属性:html
6
4.意义|展示:定义当前html文件标示的html标准(H5)
7
-->
8
<html lang="en">
9
<!--
10
1.标签名:双标签
11
2.标签名:html
12
3.属性:lang="en"(页面语言环境)
13
4.意义|展示:html内容的范围
14
-->
15
<head>
16
<!--
17
1.标签类型:双标签
18
2.标签名:head
19
3.属性:
20
4.意义|属性:网页设置
21
-->
22
<meta charset="UTF-8">
23
<!--
24
1.标签类型:单标签
25
2.标签名:meta
26
3.属性:charset="UTF-8"
27
4.意义|展示:设置文件编码格式
28
-->
29
<meta http-equiv="X-UA-Compatible" content="IE=edge">
30
<!--
31
1.标签类型:单标签
32
2.标签名:meta
33
3.属性:http-equiv="X-UA-Compatible"
34
content="IE=edge"
35
4.意义|展示:指定浏览器以某种方式渲染,兼容
36
-->
37
<meta name="viewport" content="width=device-width,initial-scale=2.0">
38
<!--
39
1.标签类型:单标签
40
2.标签名:meta
41
3.属性:
42
4.意义|展示:移动端的试图处理
43
-->
44
<title>这里写标题
45
<!--
46
1.标签类型:双标签
47
2.标签名:title
48
3.属性:无属性
49
4.意义|展示:网页标题
50
-->
51
</title>
52
</head>
53
<body>
54
<!--
55
1.标签类型:双标签
56
2.标签名:body
57
3.属性:无属性
58
4.意义|展示:网页内容
59
-->
60
</body>
61
</html>
xxxxxxxxxx
8
1
<div>默认占据一行</div>
2
<!--双标签,div,正常内容,块-->
3
<h1>这个更大一点</h1>
4
<!--双标签,h1,文字加粗变大,隐藏:用于网页名称-->
5
<h2>这个小一点</h2>
6
<!--双标签,h2,文字加粗变大,就等于标题一样分级-->
7
<p>这个是段落标签</p>
8
<!--双标签,这个上下有间隔,相当于分开了,隐藏:内部不能有块标签-->
xxxxxxxxxx
3
1
<span>在行内部里贴贴的没有什么特点的标签</span>
2
<i>这个是斜体</i>
3
<b>这个是粗体</b>
xxxxxxxxxx
9
1
<img src="这里是路径" alt="这里是属性">
2
<!--单标签,块且有外边界,内部不能放块标签,显示图片-->
3
<!--路径可以放以下路径
4
网络路径
5
直接放路径
6
本地路径(绝对路径,只用来对本地文件的操作)
7
相对路径(本文件的路径有关,项目的文件的使用,就用相对路径)
8
项目绝对路径:启动的项目为根目录
9
-->
在厚渡之网上只能用相对路径和网络路径
绝对不能在属性之间加逗号
xxxxxxxxxx
7
1
<a href="这里放路径" download target="_blank"></a>
2
<!--双标签,可以使用相对路径和网络路径-->
3
<!--加了download就是下载后查看-->
4
<!--可以使用相对路径链接到其他标签,从而实现一个页面链接到其他页面-->
5
<!--加了target _blank就是新标签打开,要不然默认就是覆盖性打开
6
_self就是覆盖当前页面打开-->
7
<!--在前端浏览器web里下载资源只能用a标签进行下载-->
.md文件不能展示,只能下载后查看,可以转化为html导出来查看
超链接标签可以放入index文件当做主目录导航使用
xxxxxxxxxx
3
1
<p>比如说这里是一个小段落<br> 这里前面的标签实现换行</p>
2
<hr><!--分割线-->
3
<p>这里是另外一个小段落</p>
xxxxxxxxxx
5
1
<ul>
2
<li>这里是无序标签的样子</li>
3
<li>这里也是无序标签的样子</li>
4
<!--注意这个是固定式标签 组合使用 里面可以包含块标签和行内标签-->
5
</ul>
xxxxxxxxxx
4
1
<ol>
2
<li>这里是有序标签这里是序号1</li>
3
<li>这里也是有序列表而序号为2</li>
4
</ol>
xxxxxxxxxx
2
1
a > b
2
<!--html的实体符号对于显示符号,没有转义符-->
在web里只有行的概念,没有列,有单元格对应的标签
xxxxxxxxxx
20
1
<!--表格
2
行
3
列
4
单元格-->
5
<table border>
6
<!--定义表格-->
7
<tr><!--可以定义一行,首行默认加粗居中-->
8
<th>名称</th><!--会加粗居中-->
9
<th>战绩</th>
10
<th>职业</th>
11
<th>颜值</th>
12
</tr><!--这里表示一行结束-->
13
<tr>
14
<!--定义一行-->
15
<td>惠惠</td><!--会居中-->
16
<td>12/4</td>
17
<td>大魔法师</td>
18
<td>爆满</td>
19
</tr>
20
</table>
分为纵向和横向合并
xxxxxxxxxx
5
1
<table>
2
<th colspan="2">这里表示两个单元格左右合并,占用两个单元格</th>
3
<!--并不会吞并下一个单元格,只是占用的位置会挤开旁边的格子-->
4
<th rowspan="2">这里表示两个单元格上下合并,占用两个单元格</th>
5
</table>
是一个用来提交数据的工具,表单只有一部分
前端无法和数据库直接进行交互,需要第三方语言进行操作
xxxxxxxxxx
6
1
<!--设置一个表单,不写任何东西也是表单,form标签也是表单-->
2
<form action="" target="">
3
<!--action="提交地址"-->
4
<!--method="提交类型"-->
5
<!--target="跳转方式"-->
6
</form>
x1<!--表单控件,可以写在表单里面,也可以写在任何位置作为一个控件-->
2
<!--区分表单控件和控件是不一样的-->
3
4
<h1>输入类</h1>
5
<input type="text"><!--可以输入任意文本的文本输入框-->
6
<!--type 属性决定控件类型
7
placeholder 提示文本
8
value 设置默认值
9
disabled 不可选中
10
name 给表单控件取名,对于数据需要数据格式才可以呈现key-value形式-->
11
<input type="password"><!--密码输入框,内容会脱敏-->
12
<input type="number"><!--数字输入框,只能输入数字和相关符号-->
13
<input type="date"><!--日期选择框,只能选择时间-->
14
<!--date可以换成month,week,year,同理-->
15
16
<hr>
17
18
<h1>选择类</h1>
19
<input type="radio">男<!--单选单标签,可以加相同的名字归入同一组-->
20
<input type="radio" value="男"><!--计算机必要的值属性-->
21
<label>表单控件和文本,相当于放大了input的作用,可以点文本操作</label>
22
<input type="chekbox">惠惠<!--多选单标签,可以加相同名字归入一组-->
23
<!--checked属性可以使选项默认勾选-->
24
<select name = "days">
25
<option value="">开始显示的是第一行</option>
26
<option value="">这里是里面的选项</option>
27
</select>
28
29
<hr>
30
31
<h1>按钮类</h1>
32
<!--在表单控件里的默认是提交按钮
33
不在表单控件里的默认是普通按钮-->
34
<button>提交按钮</button>
35
<!--默认是get的提交形式-->
36
<button type="reset">这是重置按钮</button>
37
<button type="submit">提交按钮</button>
38
<button type="button">普通按钮</button>
css是样式
xxxxxxxxxx
14
1
<!--通过标签行内style属性 设置行内 样式-->
2
<p style="color: pink">
3
这样写出来就是粉红色的段落</p>
4
5
<!--内部样式 写在head标签的style里面-->
6
<style>
7
/*使用选择器*/
8
p{
9
font-size:20px;
10
}
11
</style>
12
13
<!--外部标签 通过link标签进行一个联系-->
14
<link rel="stylesheet" href="./">
xxxxxxxxxx
4
1
p{
2
background:blue;
3
border:solid 10xp black;
4
} /*这是CSS文件*/
对于所有的标签,没有特定属性
所有的属性都可以设置任何标签,只是有些标签有效果,有些没效果
xxxxxxxxxx
30
1
<head>
2
<style>
3
/*由4个选择器单元组成*/
4
/*标签选择器 标签名 {css}*/
5
p {
6
color:yellow;
7
}
8
h1 {
9
color:red;
10
}
11
/*class选择器 .className {css}*/
12
.huihui {
13
color:brown;
14
}
15
/*id选择器 #idName {css}*/
16
#megumin {
17
color:purple;
18
}
19
/*所有标签 通配符选择器*/
20
/* * {
21
color:pink;
22
} */
23
</style>
24
</head>
25
<body>
26
<p>惠惠天下第一</p>
27
<h1>惠惠世界第一</h1>
28
<h2 class="huihui">惠惠宇宙第一</h2>
29
<h3 id="megumin"></h3>
30
</body>
xxxxxxxxxx
27
1
<head>
2
<style>
3
/*后代选择器 先 后代 {css}*/
4
div p b{
5
color:red;
6
}
7
/*子代选择器 父>子 {css}*/
8
div>p>i {
9
color:brown;
10
}
11
/*复合选择器 直接精确到各种类 注意没有空格*/
12
b.huihui.hui {
13
color:red;
14
}
15
/*组合选择器 几个选择器执行同一份代码 选择器1,选择器2 {css}*/
16
b,i{
17
color:pink;
18
}
19
/*属性选择器 [] {css}*/
20
[title="akuya"] {color:blue;}
21
/*元素选择*/
22
b,i:nth-child(n)/*这里就是选第n个元素标签*/
23
</style>
24
</head>
25
<div>
26
<p><b class="huihui hui">惠惠</b><i>天下第一</i></p>
27
</div>
xxxxxxxxxx
19
1
<style>
2
.p1:hover {/*:hover是鼠标放上去会变色的效果*/
3
color:red;
4
}
5
.p1:active {/*:active是鼠标按下去才会变色的效果*/
6
color:red;
7
}
8
.my::before {
9
content:"惠惠";/*content不能套标签*/
10
color:red;}
11
.my::after {
12
content:"天下第一";
13
color:red;}/*这个标签是两个夹住内容*/
14
</style>
15
<body>
16
<p class="my">
17
永远是
18
</p>
19
</body>
xxxxxxxxxx
13
1
<style>
2
/*权重:继承样式<通配符选择器<标签选择器<class选择器<id选择器*/
3
/*权重计算:先计算最高权重的个数比较后再顺位比较下一位权重的个数*/
4
p {
5
color:pink !important;
6
}
7
.pclass {
8
color:orangered;
9
}
10
/*最高权重:!important;*/
11
</style>
12
<body>
13
</body>
块盒子外边距会合并,且外边距会超出父盒子
对于块盒子实现间距建议使用内间距
xxxxxxxxxx
29
1
<head>
2
<style>
3
#app {
4
/*内容为宽和高*/
5
width: 100px;/*宽*/
6
heighat: 100px;/*高*/
7
/*min-width:50限制最小为5,同理还有max*/
8
padding: 20px;/*内边距*/
9
border: solid 10px;/*边框*/
10
/*还可以精确到某个方向padding-left:20px*/
11
/*分别可用top,bottom,left,right*/
12
/*也可以一次性写完,上开始顺时针,左结束*/
13
/*对于CSS都可以有自己的属性,是个框就基本可以设置四个值*/
14
margin: 20xp;/*外边距*/
15
background-color:pink;/*背景颜色*/
16
/*border: style width color;边框的格式*/
17
/*边框样式:dashed 实线 solid 虚线*/
18
/*圆角的边框:border-radius: 10px;*/
19
/*正方形边框可以变成圆形:border-radius: 50%;*/
20
21
/*怪异盒子模型 设置属性不会改变盒子大小*/
22
box-sizing: border-box;
23
}
24
</style>
25
</head>
26
<body>
27
<div id="app">
28
</div>
29
</body>
布局就是设置上下左右的空间,宏观布局和微观布局
布局原理简单,但套娃容易让人混淆‘
xxxxxxxxxx
7
1
<body>
2
<div id="app">
3
<!--行内标签不能实现左右布局,布局只能使用块标签-->
4
<span class="box">路过</span><!--区分块标签行内标签-->
5
<span class="box">路过</span>
6
</div>
7
</body>
xxxxxxxxxx
9
1
<!---->
2
<style>
3
#app {
4
display: flex;/*使子 盒子之间左右排列,必须是父盒子才能操作子盒子*/
5
}
6
#app2 {
7
display:
8
}
9
</style>
取色:截图后按C取色号
xxxxxxxxxx
38
1
<!--
2
容器
3
项目:不属于任何盒子类型
4
主轴
5
交叉轴
6
-->
7
<style>
8
#app {
9
display:flex;
10
flex-direction: row;/*从左到右*/
11
flex-direction: row-reverse;/*从右到左 */
12
flex-direction: column;/*从上到下*/
13
flex-direction: column-reverse;/*从下到上*/
14
}
15
</style>
16
<!--换行 flex项目不会换行-->
17
<style>
18
#appp {
19
flex-wrap: nowrap;/*默认不换行*/
20
flex-wrap: wrap;/*换行*/
21
}
22
</style>
23
<!--主轴排列方式-->
24
<style>
25
#apppp {
26
justify-content: flex-end;/*结束方向*/
27
justify-content: flex-start;/*开始方向*/
28
justify-content: center;/*居中*/
29
justify-content: space-around;/*项目平分容器左右空间*/
30
justify-content: space-between;/*项目靠边*/
31
}
32
</style>
33
<!--缩小比-->
34
<style>
35
#appppp {
36
flex-shrink: 1;/*缩小所占的比例 */
37
}
38
</style>
小技巧:
- 布局不要去固定高度
具体文本的一些样式,CSS无法直接操作文本,只能通过标签控制文本
xxxxxxxxxx
38
1
<style>
2
#app {
3
/*文字大小*/
4
px 像素 基于像素点;
5
em 父盒子的文字大小;
6
rem html 标签的文字大小;
7
vh 视图可视区域的高百分之一为1vh;
8
vw 视图可视区域的宽百分之一为1vw;
9
/*文字颜色*/
10
color: agb(0,0,0);
11
/*文字粗细 可用hex或rgb或rgba表示*/
12
font-weight: 300;/*细300正常500粗700*/
13
/*字体*/
14
font-family: 微软雅黑;/*可以使用逗号后续补充字体*/
15
/*行高*/
16
line-height: 80px;
17
/*文本样式*/
18
text-align: left;/*左对齐*/
19
text-align: center;/*居中*/
20
text-align: right;/*右对齐*/
21
/*首行缩进*/
22
text-indent: 2em;
23
/*文本线*/
24
text-decoration-style: solid;
25
/*设置线的位置*/
26
text-decoration-line: underline;/*下划线*/
27
text-decoration-line: line-through;/*删除线*/
28
text-decoration-line: overline;/*上划线*/
29
/*字间距*/
30
letter-spacing: 20px;
31
/*溢出显示方式*/
32
text-overflow: clip;/*擦掉不显示*/
33
text-overflow: ellipsis;/*以滚动条的形式显示*/
34
/*限制内容*/
35
/*不能换行*/
36
white-space: nowrap;
37
}
38
</style>
标准盒模型中width指的是内容区域content的宽度;height指的是内容区域content的高度。 标准盒模型下盒子的大小 = content + border + padding + margin
怪异盒模型中的width指的是内容、边框、内边距总的宽度(content + border + padding);height指的是内容、边框、内边距总的高度
xxxxxxxxxx
25
1
<!--定位是布局的补充-->
2
<!--固定定位:脱离文档流 寻找o点-->
3
<style>
4
.box {
5
position: fixed;
6
right: 200px;
7
bottom: 200px;
8
left: 400px;/*left和top权重更大*/
9
}
10
</style>
11
<!--相对定位:不脱离文档流 定位相对是自己原有的位置 o点就是原有位置4个点-->
12
<style>
13
.box2 {
14
position: relative;
15
right: 200px;
16
}
17
</style>
18
<!--绝对定位:必须先找一个有定位属性的容器 基于容器定位
19
如果没有定位属性 就加相对定位属性-->
20
<style>
21
.box3 {
22
position: absolute;
23
24
}
25
</style>
xxxxxxxxxx
5
1
<style>
2
.box {
3
z-index: 2;/*设置层级,越大越在上面*/
4
}
5
</style>
xxxxxxxxxx
14
1
/*盒子阴影*/
2
#app {
3
box-shadow: 10px 5px 10px 5px red;
4
}/*水平偏移 垂直偏移 模糊距离 扩散距离*/
5
/*盒子透明度*/
6
#app2 {
7
opacity: .5;
8
}
9
/*过渡*/
10
#app3 {
11
transition: 3s;/*设置一个过渡的时间*/
12
transition-timing-function: cubic-bezier();
13
/*不是所有属性都可以过渡,可以设置像素值或颜色的属性才可以过渡*/
14
}
JavaScript是一种直译式脚本语言,是一种动态类型,弱类型,基于原型的语言
功能:操作html,响应浏览器事件,用户行为交互,数据验证,前后端交互
xxxxxxxxxx
10
1
<!--页面标签-->
2
<script>
3
console.log('hello world!');//注释用//
4
</script>
5
<!--标签属性中-->
6
<button onclick="console.log('onclick me')">
7
</button>
8
<a href="javascript: console.log('onclick me');"></a>
9
<!--外部文件引入-->
10
<script src='./'>引入js文件</script>
xxxxxxxxxx
16
1
//日志输出
2
console.log("普通日志");
3
console.warn('警告日志');
4
console.error('错误日志');
5
throw '抛出代码异常,会中断代码异常'
6
7
//针对对象打印
8
console.dir(console);
9
10
//弹框输出
11
alert()//普通弹窗
12
confirm()//确认弹框
13
prompt()//输出弹框
14
15
//页面展示输出
16
document.body.innerText = '展示到页面了哇';
xxxxxxxxxx
4
1
// 定义变量前要声明
2
let a = 1;// 这是只能声明一次的变量
3
var b = 2;// 这是可以重复覆盖声明的变量量
4
const c = 3;// 这是常量
xxxxxxxxxx
19
1
// 字符串
2
let s = "我是字符串";
3
let s2 = '我也是字符串';
4
// 模板字符串,可以写多行,还可以在里面插入变量
5
let meigumin = "first";
6
let s3 = `这是字符串(${meigumin})模板`;// 插入了变量
7
8
// 数字类型 number,不分具体类型
9
let num = 1314;
10
let huihui = 12.04;
11
12
// 布尔类型 boolean
13
true false;
14
15
// undefined 未定义类型
16
let xxxx;
17
18
// null 空
19
lala = null;
xxxxxxxxxx
18
1
// Object 对象
2
// 模板对象
3
let o = {};
4
let o2 = {
5
maxAge : 27;
6
minAge : 17;
7
height : 165;
8
weight : "44-48";
9
};
10
// 增
11
o1.character = "可爱";
12
// 删
13
delete.o1.minAge;
14
// 改
15
o1.maxAge = 24;
16
// 查
17
console.log(o2);// 显示全部,包括键值
18
console.log(o2.height);// 显示具体其中一个的值
xxxxxxxxxx
14
1
// Array 数组
2
let huihui = [16,154,42,true,{handsome : "me"}];
3
// 增
4
huihui.push('头部添加');
5
huihui.unshift('尾部添加');
6
// 查
7
console.log(huihui);
8
// 改
9
huihui[2] = '41';
10
// 删
11
huihui.pop('头部删除');
12
huihui.shift('尾部删除');
13
// splice方法
14
huihui.splice('下标','删除数量','添加内容','')
xxxxxxxxxx
9
1
// 定义函数
2
// 普通函数
3
function huihui() {
4
}
5
// 匿名函数
6
function() {
7
}// 匿名函数的第一种
8
() => {
9
}// 匿名函数的第二种
xxxxxxxxxx
9
1
// 函数执行
2
function hanshuming() {;
3
}
4
hanshuming();
5
// 函数的传参
6
function hanshu(a,b,c = false) {
7
}//c 的默认值为FALSE
8
hanshu(1,2);
9
// 返回值
xxxxxxxxxx
24
1
// 获取DOM
2
// querySelector 通过选择器获取
3
let app = document.querySelector('#app');
4
let app = document.querySelectorAll('span');//得到一个数组,里面有很多标签的dom
5
6
// 操作DOM
7
// 内容
8
app.innerText = '你是我的app';
9
app.innerHTML = '<b>你是我的app</b>';
10
11
// 样式
12
app.style.color = 'pink';
13
app.style.fontSize = '20px';
14
15
// 操作 class
16
app.className = "box";// 直接复制样式
17
// 增
18
app.classList.add("box");
19
app.classList.add('back');
20
// 删
21
app.classList.remove('back');
22
// 查
23
app.classList.contains('box'); //得到TRUE or FALSE
24
// 不能改样式
xxxxxxxxxx
13
1
// 事件类型
2
//鼠标事件
3
onclick /*左键单击*/ ondblclick /*左键双击*/
4
onmouseover onmouseenter/*鼠标放上去*/
5
onmouseenter onmouseleave/*鼠标进入*/
6
//键盘事件
7
onkeydown onkeypress/*键按下*/ onkeyup /*键抬起*/
8
//系统事件
9
onload /*加载完成后*/ onerror /*加载出错后*/
10
onresize /*窗口大小调整时*/ onscroll /*屏幕滚动时*/
11
//表单事件
12
onfocus /*获取焦点后*/ oublur /*失去焦点后*/
13
onchange /*改变内容后*/ onreset /*重载表单后*/
xxxxxxxxxx
5
1
// 添加事件的两种方式
2
app.onclick = ()=>{
3
}//dom后加上事件类型和匿名函数
4
function event() {
5
}//然后在标签里用事件类型<div onclick="event()">
xxxxxxxxxx
17
1
//多种判断
2
if(true){}
3
else if(true){}
4
else {}
5
6
//三目标识符
7
true ? console.log('good') : console.log('bad');
8
9
//switch语句
10
switch(a){
11
case '':
12
break;
13
case '':
14
break;
15
default:
16
break;
17
}
xxxxxxxxxx
4
1
//循环语句
2
for(let i = 0; i<100; i++){
3
console.log('舔+1');
4
}
xxxxxxxxxx
3
1
//强制类型转换
2
let a = 1;
3
a = String(a);
xxxxxxxxxx
9
1
let s = '惠惠天下第一';
2
console.log(s.length);//字符串长度
3
console.log(s[1]);//通过下标获取
4
console.log(s.charCodeAt(2));//获取某个字符的Unicode编码
5
console.log(String.fromCharCode(c));//将Unicode编码还原成对应的字符
6
console.log(s.substring(1,3));//字符串截取,开始下标和结束下标
7
console.log(str.toUpperCase());//把纯字母全部变成大写
8
console.log(str.toLowerCase());//把纯字母全部变成小写
9
console.log(s.indexOf());//检索字符串里是否有某个字符串,得到的值为第一次出现的下标,反则为-1
xxxxxxxxxx
15
1
console.log(arr.len);//数组长度
2
console.sort(function xx(a, b){return a - b;/*小到大*/});//数组内元素排序
3
console.log(arr.concat(arr1));//将两个数组合并成一个数组
4
console.log(arr);//将数组变成字符串
5
console.log(arr.join());//将数组元素拼接成字符串,默认为,
6
console.log(str.split(","))//用逗号将字符串变成数组
7
console.log(Array.isArray(arr));//判断是否是一个数组返回布尔值
8
arr.forEach((el, i)=>{console.log('内容${el}, 下标${i}')});//历遍得到数组里的内容和下标
9
console.log(arr.map((el, i)=>{return{el:el, i: i};}));//映射得到一个类似有模板的历遍
10
/*for in 循环,可以循环对象的循环*/
11
let obj = {key:'value', age: 'max-Age'}
12
for (const key in obj) {
13
console.log(key);//得到对象的key
14
conso.log(obj[key]);//由key找到值
15
}
xxxxxxxxxx
5
1
let vat = setInterval(()=>{},time);//只要我不取消就一直执行的定时任务
2
clearInterval(vat);//停止定时任务
3
//说明:每隔time就执行一遍定时任务
4
5
let
xxxxxxxxxx
15
1
//随机数
2
console.log(Math.random());
3
//无法添加可选参数,如果要加范围,可以通过四则运算
4
//取整
5
//向上取整
6
console.log(Math.ceil(Nember));
7
//向下取整
8
console.log(Math.floor(Nember));
9
//四舍五入
10
console.log(Math.round(Nember));
11
//保留小数
12
console.log(Nember);//(默认四舍五入保留两位小数)
13
console.log(Nember.toFixed(n));//保留n位小数
14
//取绝对值
15
console.log(Math.abs(-99));
xxxxxxxxxx
14
1
//当前时间
2
let newTime = new Date();
3
console.log(newTime);
4
//特定时间
5
let lodTime = new Date('2022-12-04 00:00:00');
6
//获取其中一部分
7
console.log(lodTime.getFullYear());
8
console.log(lodTime.getTime());//获取时间戳,单位是毫秒
9
console.log(lodTime.getDate());
10
console.log(lodTime.getMinutes());
11
console.log(lodTime.getHours());
12
console.log(lodTime.getMonth());
13
console.log(lodTime.getSeconds());
14
console.log(lodTime.getDay());
用户访问网站时,将一些字符串信息保存起来,当下次访问时可以直接读取到上次储存的信息
在服务器环境下才能使用cookie
客户端和后端都可以设置cookie
每个网页之间的cookie不共享,每个浏览器之间的cookie不共享
与后端的所有交互都会自动带上cookie
单个域名cookie的大小不能超过4kb
xxxxxxxxxx
4
1
//获取与设置
2
document.cookie = "key = value";
3
//时间设置
4
document.cookie = "name = value;expires=对应utc时间";
xxxxxxxxxx
15
1
let cookie = {
2
//设置
3
set(mJson,day){let date = new Date( new Date().getTime()+day*24*3600*1000).toUTCString();
4
Object.entries(mJson).forEach(([key,value])=>{
5
document.cookie = '${key}=${value};expires=${date}';
6
});
7
},
8
get(key){
9
new RegExp("(^|\\s)"+key+"=([^;])(;|$)").test(document.cookie);
10
return RegExp.$2;
11
},
12
remove(key){
13
Cookie.set({[key]:""},-1);
14
}
15
};
本地储存分为临时储存和永久储存,相比cookie:
本地储存的数据量更大,每个域名5M
本地储存只在客户端进行操作
本地储存不会每次请求都自动带上数据,减少请求压力
本地储存不兼容低版本浏览器
临时储存,关闭浏览器再打开没有数据
数据不共享,打开同域新页面没有数据
xxxxxxxxxx
4
1
sessionStorage.setItem("key","value");//存
2
sessionStorage.getItem("key");//取
3
sessionStorage.removeItem("key");//删
4
sessionStorage.clear();//删全部
永久储存,关闭浏览器再打开对应页面也有数据
数据共享,打开同域页面也有数据
IOS设备客户端无痕模式存储不了,所以最好提前判断是否存在localStorage对象
xxxxxxxxxx
4
1
localStorage.setItem("key","value");//存
2
localStorage.getItem("key");//取
3
localStorage.remove("key");//删
4
localStorage.clear();//删全部
原生的Ajax即“ Asynchronous Javascript And XML"(异步JS和XLM)是指一种创建交互式网页应用的网页开发技术
Ajax可以在不刷新页面的前提下向后端发送/请求数据,在开发中必然会用到
xxxxxxxxxx
49
1
var xhr;
2
if(window.XMLHttpRequest) { //标准浏览器
3
xhr = new XMLHttpRequest();
4
}else if(window.ActiveXObject) { //低版本IE
5
try{
6
xhr = new ActiveXObject('Msxm12.XMLHTTP');
7
}catch (e) {
8
try {
9
xhr = new ActiveXObject('Microsoft.XMLHTTP');
10
}catch (e) {}
11
}}
12
if(xhr) {
13
xhr.onreadystatechange = onReadyStateChange;
14
xhr.open('POST','/url',true);
15
//设置Content-Type 为application/x-www-form-urlencoded
16
//以表单的形式传递数据
17
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
18
xhr.send('username=admin&password=root');
19
}
20
// onreadystatechange方法
21
function onReadyStateChange() {
22
/*
23
xhr.readyState:
24
0:请求未初始化
25
1:J服务器连接已建立
26
2:请求已接收
27
3:请求处理中
28
4:请求已完成,且响应已就绪
29
*/
30
if(xhr.readyState === 4) {
31
//请求到了最后一步
32
/*
33
xhr.status:状态码
34
100+ 请求已被接受,需要继续处理
35
200+ 请求已成功被接受和处理
36
300+ 通常代表重定向
37
400+ 客户端请求发生了错误
38
500+ 服务端发生了错误
39
*/
40
if(xhr.status >= 200 && xhr.status<300) {
41
console.log(xhr.responseText);//打印请求返回的文本内容
42
} else {
43
console.log('请求有问题');
44
}
45
else {
46
console.log('请求还没处理到最后一步');
47
}
48
}
49
}
没用经过封装的原生Ajax非常复杂,使用起来代码也极为不协调,并且如需多次请求会出现回调的情况,所以一般不使用原生Ajax
使用jQuery的Ajax要先引入jQuery库,但仍然没有解决回调地狱问题
xxxxxxxxxx
1
1
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
xxxxxxxxxx
9
1
$.ajax ({
2
method : "POST"//请求方式
3
,url:"/url"//请求地址
4
,data:{}//需要发送的数据
5
,dataType:"json"//对请求返回的数据预处理
6
,success:function(data){}//请求成功后的回调函数
7
,error:function(err){}//请求失败的回调函数
8
})
9
// 另外有单独的 $.get() $.post() 方法快捷使用
fetch和axios都使用了ES6的promise方案来解决回调地狱的问题,所以目前我们在使用Ajax的时候比较多的是采用这两种方案,从功能与完善度来讲,axios更好用
fetch是ES6引入的新API,所以只要浏览器支持ES6,那么对fetch就是支持的,不需要额外的引入
xxxxxxxxxx
7
1
fetch("/url",{method:"post"})//路径,各项参数
2
.then((res)=>{
3
return res.json();//将返回的数据格式化
4
})
5
.then((data)=>{
6
console.log(data);//最终拿到的数据
7
})
fetch是一个底层的API,功能不完美,400和500的状态码也会当成成功来处理,默认也不带cookie,并且不支持超时控制与阶段监听,所以一般情况下使用axios
axios是一个基于promise的http库,可以用在浏览器和node.js中,原生js并不支持axios,浏览器环境需要引入axios
xxxxxxxxxx
1
1
<script src="https://cdn.bootcss.com/axios/0.19-bata.1/axios.min.js"></script>
xxxxxxxxxx
12
1
//get
2
axios
3
.get(
4
"http://api.afei.fun"//url
5
,{params : {name:"affei",age:18}}//传过去的数据
6
)
7
.then(res=>{
8
console.log(res);
9
})
10
.catch(err=>{
11
console.log(err);
12
})
xxxxxxxxxx
12
1
//post
2
axios
3
.post(
4
"http://api.afei.fun"//url
5
,{name:"afei",age:18}//传过去的参数
6
)
7
.then(res=>{
8
console.log(res);
9
})
10
.catch(err=>{
11
console.log(err);
12
})
xxxxxxxxxx
12
1
//直接执行axios,各项参数额外配置
2
axios({
3
method:"post"
4
,url:"http://api.afei.fun"
5
,data;{name:"afei",age:18}
6
})
7
.then(res=>{
8
console.log(res);
9
})
10
.catch(err=>{
11
console.log(err);
12
})
xxxxxxxxxx
12
1
//同时发送两个请求,等到处理完后执行回调
2
function reqA() {
3
return axios.get("url1");
4
}
5
function reqB() {
6
return axios.get("url1");
7
}
8
axios
9
.all([reqA(),reqB()])
10
.then(res=>{
11
console.log(res);
12
})
xxxxxxxxxx
31
1
//在所有axios请求发送之前,先执行这里
2
axios.interceptors.request.use(config=>{
3
//config.method = "get";
4
console.log(config);
5
return config;
6
},err=>{
7
console.log(err);
8
return Promise.reject(err);
9
});
10
11
//在所有的axios请求成功之后,(在回调执行之前)先执行这里
12
axios.interceptors.response.use(response=>{
13
console.log(response);
14
return response;
15
},err=>{
16
console.log(err);
17
return Promise.reject(err);
18
});
19
20
//请求
21
axios
22
.post(
23
"http://api.afei.fun"
24
,{name:"afei",age:18}
25
)
26
.then(res=>{
27
console.log(res);
28
})
29
.catch(err=>{
30
console.log(err);
31
});
xxxxxxxxxx
12
1
//需要现在添加的时候得到返回值,方便于移除
2
let interceptor = axios.interceptors.request.use(config=>{
3
//config.method = "get";
4
console.log(config);
5
return config;
6
},err=>{
7
console.log(err);
8
return Promise.reject(err);
9
});
10
11
//移除
12
axios.interceptors.request.eject(interceptor);
xxxxxxxxxx
16
1
//创建实例提前配置一些参数,这样后期在使用的时候,就无需重复配置了
2
let myInstance = axios.create({
3
//这里可以写默认配置项
4
});
5
6
//发送请求时,会带上默认的配置
7
myInstance.get("url")
8
.then(res=>{
9
console.log(res);
10
})
11
.catch(err=>{
12
console.log(err);
13
});
14
15
//还可以只为该实例设置拦截
16
myInstance.interceptors.request.use(/*……*/)
当我们往一个地址发送请求时,需要确保该地址和你运行HTML文件的地址为同源关系(协议、ip、端口都相同),否则是会出现跨域问题的。报错信息类似于:
Access to XMLHttpRequest at 'https://www.baidu.com/' (redirected from 'http://www.baidu.com/') from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
跨域问题最常用的解决方案有两种,一种是在对应地址的后端设置允许你HTML地址的请求,另外一种是使用jsonp的形式请求数据(需要特定格式数据才行)。
promise是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理
promise简单地说就是一个容器里面保存着某个未来才会结束的事件(通常是异步操作)的结果
promise对象代表一个异步操作,有三种状态:
pending(进行中),fulfiled(已成功)和rejected(已失败)
之后异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
写js必然不会对异步事件陌生
xxxxxxxxxx
4
1
settimeout(()=>{
2
console.log("123");
3
},0)
4
console.log("abc");
xxxxxxxxxx
13
1
let p = new Promise((resolve,reject)=>{
2
//一些异步操作
3
settimeout(()=>{
4
console.log("123")
5
resolve("abc");
6
},0)
7
})
8
.then(function(data){
9
//resolve状态
10
console.log(data)
11
},function(err){
12
//reject状态
13
})
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
也就是说,状态由实例化时的参数(函数)执行来决定的,根据不同的状态,看看需要走then的第一个参数还是第二个。
resolve()和reject()的参数会传递到对应的回调函数的data或err
then返回的是一个新的Promise实例,也就是说可以继续then
所以,从表面上看,Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的:
xxxxxxxxxx
18
1
runAsync1()
2
.then(function(data){
3
console.log(data);
4
return runAsync2();
5
})
6
.then(function(data){
7
console.log(data);
8
return runAsync3();
9
})
10
.then(function(data){
11
console.log(data);
12
});
13
//异步任务1执行完成
14
//随便什么数据1
15
//异步任务2执行完成
16
//随便什么数据2
17
//异步任务3执行完成
18
//随便什么数据3
runAsync1、runAsync2、runAsync3长这样↓
xxxxxxxxxx
30
1
function runAsync1(){
2
var p = new Promise(function(resolve, reject){
3
//做一些异步操作
4
setTimeout(function(){
5
console.log('异步任务1执行完成');
6
resolve('随便什么数据1');
7
}, 1000);
8
});
9
return p;
10
}
11
function runAsync2(){
12
var p = new Promise(function(resolve, reject){
13
//做一些异步操作
14
setTimeout(function(){
15
console.log('异步任务2执行完成');
16
resolve('随便什么数据2');
17
}, 2000);
18
});
19
return p;
20
}
21
function runAsync3(){
22
var p = new Promise(function(resolve, reject){
23
//做一些异步操作
24
setTimeout(function(){
25
console.log('异步任务3执行完成');
26
resolve('随便什么数据3');
27
}, 2000);
28
});
29
return p;
30
}
在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中也可以接收到数据:
xxxxxxxxxx
17
1
runAsync1()
2
.then(function(data){
3
console.log(data);
4
return runAsync2();
5
})
6
.then(function(data){
7
console.log(data);
8
return '直接返回数据'; //这里直接返回数据
9
})
10
.then(function(data){
11
console.log(data);
12
});
13
//异步任务1执行完成
14
//随便什么数据1
15
//异步任务2执行完成
16
//随便什么数据2
17
//直接返回数据
reject的用法
前面的例子都是只有“执行成功”的回调,还没有“失败”的情况,reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。
xxxxxxxxxx
21
1
let num = 10;
2
let p1 = function() {
3
return new Promise((resolve,reject)=>{
4
if (num <= 5) {
5
resolve("<=5,走resolce")
6
console.log('resolce不能结束Promise')
7
}else{
8
reject(">5,走reject")
9
console.log('reject不能结束Promise')
10
}
11
})
12
}
13
14
p1()
15
.then(function(data){
16
console.log(data)
17
},function(err){
18
console.log(err)
19
})
20
//reject不能结束Promise
21
//>5,走reject
resolve和reject永远会在当前环境的最后执行,所以后面的同步代码会先执行。
如果resolve和reject之后还有代码需要执行,最好放在then里。
然后在resolve和reject前面写上return。
Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。
xxxxxxxxxx
9
1
p1()
2
.then(function(data){
3
console.log(data)
4
})
5
.catch(function(err){
6
console.log(err)
7
})
8
//reject不能结束Promise
9
//>5,走reject
Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
xxxxxxxxxx
1
1
const p = Promise.all([p1, p2, p3]);
p的状态由p1、p2、p3决定,分成两种情况。
p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled。
此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
promises是包含 3 个 Promise 实例的数组,只有这 3
个实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。
如果作为参数的 Promise
实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法,如果没有参数没有定义自己的catch,就会调用Promise.all()的catch方法。
Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
xxxxxxxxxx
1
1
const p = Promise.race([p1, p2, p3]);
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的
Promise 实例的返回值,就传递给p的回调函数。
有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。
xxxxxxxxxx
1
1
const jsPromise = Promise.resolve('123');
上面代码将123转为一个 Promise 对象。
Promise.resolve等价于下面的写法。
xxxxxxxxxx
3
1
Promise.resolve('123')
2
// 等价于
3
new Promise(resolve => resolve('123'))
Promise.resolve方法的参数分成四种情况。
参数是一个 Promise 实例
如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
参数是一个thenable对象
thenable对象指的是具有then方法的对象,比如下面这个对象。
xxxxxxxxxx
5
1
let thenable = {
2
then: function(resolve, reject) {
3
resolve(42);
4
}
5
};
Promise.resolve方法会将这个对象转为 Promise
对象,然后就立即执行thenable对象的then方法。
xxxxxxxxxx
10
1
let thenable = {
2
then: function(resolve, reject) {
3
resolve(42);
4
}
5
};
6
7
let p1 = Promise.resolve(thenable);
8
p1.then(function(value) {
9
console.log(value); // 42
10
});
上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出
42。
参数不是具有then方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的
Promise 对象,状态为resolved。
xxxxxxxxxx
6
1
const p = Promise.resolve('Hello');
2
3
p.then(function (s){
4
console.log(s)
5
});
6
// Hello
上面代码生成一个新的 Promise
对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise
实例的状态从一生成就是resolved,所以回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数。
不带有任何参数
Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve方法。
xxxxxxxxxx
5
1
const p = Promise.resolve();
2
3
p.then(function () {
4
// ...
5
});
上面代码的变量p就是一个 Promise 对象。
需要注意的是,立即resolve的 Promise 对象,是在本轮“事件循环”(event
loop)的结束时,而不是在下一轮“事件循环”的开始时。
xxxxxxxxxx
13
1
setTimeout(function () {
2
console.log('three');
3
}, 0);
4
5
Promise.resolve().then(function () {
6
console.log('two');
7
});
8
9
console.log('one');
10
11
// one
12
// two
13
// three
上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。
Promise.reject(reason)方法也会返回一个新的 Promise
实例,该实例的状态为rejected。
xxxxxxxxxx
8
1
const p = Promise.reject('出错了');
2
// 等同于
3
const p = new Promise((resolve, reject) => reject('出错了'))
4
5
p.then(null, function (s) {
6
console.log(s)
7
});
8
// 出错了
上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。
注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。
xxxxxxxxxx
11
1
const thenable = {
2
then(resolve, reject) {
3
reject('出错了');
4
}
5
};
6
7
Promise.reject(thenable)
8
.catch(e => {
9
console.log(e === thenable)
10
})
11
// true
上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。