HTML是什么:即HyperText Markup language 超文本标记语言,HTML的作用是定义网页的内容和结构
<标签>
的方式赋予内容不同功能和含义
html由一系列元素构成:<p>
和</p>
称为起始和结束标签
被标签包围的被称为内容
元素内部还能有属性
1<div id="div1" class="class_div"></div>
元素之间还可以嵌套(嵌套不能交叉)
xxxxxxxxxx
91
2<html>
3 <head>
4 ...
5 </head>
6 <body>
7 ...
8 </body>
9</html>
<!DOCTYPE html> 为文档声明,告诉浏览器如何加载该文档,以标准模式加载html
空元素
xxxxxxxxxx
21<!--展示图片,src为图片地址-->
2<img src="test.png"/>
vscode快捷键生成html:输入! + tab键
Anchor元素
超链接
x1<a href="网页地址">超链接文本</a>
2
3#页面锚点,使用#号
4<a href="#p1">跳转页面锚点</a>
5<p id="p1">...</p>
6
7#跳转顶部
8<a href="#">回到顶部</a>
多媒体
Image
src格式有三种
文件地址
data URL
xxxxxxxxxx
11<img src="data:image/png;base64,数据">
data 媒体类型 base64,数据
Video
controls:播放控制条
xxxxxxxxxx
11<video src="视频文件地址" controls></video>
Audio
xxxxxxxxxx
11<audio src="音频文件地址" controls></audio>
更多元素参考mdn网站
网址:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
表单
表单的作用:收集用户填入的数据,并将这些数据提交给服务器
xxxxxxxxxx
41<form action="服务器地址" method="请求方式" enctype="数据格式">
2 <!--表单项-->
3 <input type="submit" value="提交按钮">
4</form>
method请求方式有
enctype在post请求时,指定数据的格式
其中表单项提供多种收集数据的方式
日期
在后端接收日期的时候需要指定和前端日期格式对应
使用@DateTimeFormat注解
xxxxxxxxxx
21pattern= "yyyy-MM-dd") (
2private LocalDate birthday;
文件上传
xxxxxxxxxx
11<input type="file" name="testFile">
xxxxxxxxxx
31<form action="..." method="post" enctype="multipart/form-data">
2 ...
3</form>
MultipartFile 接收上传的文件数据
xxxxxxxxxx
61"/test") (
2
3public String test(MultipartFile testFile){
4 System.out.println("testFile:" + testFile.getSize());
5 return "收到数据";
6}
请求分三部分组成
Http无状态,有会话
服务端使用了session技术来暂存数据,客户端会保存本次session的cookie,JSESSIONID
xxxxxxxxxx
51"/s2") (
2
3public String s2(HttpSession session){
4 return "取出数据" + session.getAttribute("name");
5}
返回的是一个加密生成后的令牌(token),返回给客户端
下次请求会携带token,服务端校验token,校验无误,放行
token一般存放在请求头的Authorization中
xxxxxxxxxx
361"/testToken") (
2
3public String testToken(String name,String password){
4 //这里做个伪验证
5 if ("zhangsan".equals(name) && "123".equals(password)){
6
7 String token = Jwts.builder().setSubject(name).signWith(key).compact();
8
9 return "验证身份通过" + token;
10
11 }else {
12
13 return "身份验证失败";
14
15 }
16}
17
18
19"/testToken2") (
20
21public String testToken2( String authorization){
22
23 try{
24
25 System.out.println(authorization);
26
27 Jws<Claims> jws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(authorization);
28
29 return "校验通过,你是:"+ jws.getBody().getSubject();
30
31 }catch(Exception e){
32
33 return "校验失败";
34
35 }
36}
token构造
header(签名算法).payload(数据).签名
签名是根据前两部分根据一个密钥生成的
签名算法会生成一个签名值,会根据签名值是否相同判断token内容是否被篡改
CSS是什么:即Cascading Style Sheets 级联(层叠)样式表,它描述了网页的表现与展示效果
在html中引入css文件
xxxxxxxxxx
11<link rel="stylesheet" href="style.css">
选择器
xxxxxxxxxx
141/*标签选择器*/
2p {
3 background-color: rgb(243,136,42);
4}
5
6/*类选择器*/
7.c1{
8 background-color: rgb(151,211,48);
9}
10
11/*id选择器*/
12#p{
13 background-color: cyan;
14}
选择器优先级
同一标签被三种选择器作用,存在作用优先级
css样式大全:https://developer.mozilla.org/en-US/docs/Web/CSS/accent-color
页面组成
div标签
容器标签,可以划分页面布局,容纳其它标签
template标签
结合js代码动态的加入到div中
基础部分详细参考博客JavaScript
在js中函数也是一种对象
js中的默认值设置
xxxxxxxxxx
31function pagination(page = 1,size = 10){
2 alert(page,size)
3}
xxxxxxxxxx
41(参数) => {
2 //函数体
3 return 结果;
4}
使用场景
调用匿名函数
xxxxxxxxxx
31(function(a,b){
2 return a + b;
3})(1,2)
xxxxxxxxxx
31document.getElementById("p1").onclick = (function(){
2 alert("鼠标单击事件");
3});
箭头函数
无需写function
xxxxxxxxxx
41(参数) => {
2 //函数体
3 return 结果;
4}
xxxxxxxxxx
11document.getElementById("p1").onclick = () => alert("鼠标单击事件");
JS函数的作用域根据参数声明位置决定
函数定义时它的作用域已经确定好了,因此无论函数将来在哪里被调用,都能从它的作用域中找到需要的变量
闭包:闭包就是指函数能够访问自己的作用域中的变量
在java中也有类似的代码结构
函数接口
任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口
xxxxxxxxxx
51public interface TestObj {
2
3 void accept(Integer x);
4
5}
测试lambda
xxxxxxxxxx
181public class TestDemo {
2
3 public static void main(String[] args) {
4
5 a().accept(1);
6
7 }
8
9 public static TestObj a(){
10
11 int y = 20;
12
13 TestObj function = x -> System.out.println(x +","+y);
14
15 return function;
16 }
17
18}
如果函数外层引用的是let变量,那么外层普通的{}(比如if的花括号)也会作为作用域边界,最外层的let也占一个script作用域
如果函数外层引用的是var变量,外层普通的{}不会视为边界
如果var变量出现了重名,则都会被视为同一作用域里的变量
xxxxxxxxxx
71var e = 10;
2if(true){
3 /*这里相当于重新赋值*/
4 var e = 20;
5 alert(e);
6}
7alert(e);
语法
xxxxxxxxxx
11let arr [1,2,3];
遍历数组
xxxxxxxxxx
31for(let i = 0;i < arr.length; i++){
2 alert(arr[i]);
3}
API
xxxxxxxxxx
61//数组尾部添加数据
2arr.push(4)
3//头部移除一个元素
4arr.shift()
5//指定位置删除元素
6arr.splice(2)
xxxxxxxxxx
31let arr = ['a','b','c']
2//默认用逗号将元素连成一个字符串,也可以指定分隔符
3arr.join();
xxxxxxxxxx
51function a(i){ //代表新旧元素间的变换规则
2 return i * 10;
3}
4
5arr.map(a);
高阶函数:map、filter、forEach
回调函数:作为参数传入的函数
xxxxxxxxxx
61let obj = {
2 _属性名:值
3 方法名: 函数,
4 get 属性名() {},
5 set 属性名(新值){}
6}
JS对象创建示例:
xxxxxxxxxx
91let obj = {
2 _name: null, /*_开头类似于Java中的私有成员变量,实际上没有私有概念,直接访问_name不走get方法*/
3 get name(){
4 return this._name;
5 },
6 set name(name){
7 this._name = name;
8 }
9}
调用get,set方法
xxxxxxxxxx
41//默认执行了对象的set方法
2obj.name = "Tom";
3//默认执行了对象的get方法
4alert(obj.name);
JS对象特色
属性增删
对比下Java中的Object
xxxxxxxxxx
91let obj = {name:"tom"};
2
3obj.age = 18;
4
5delete obj.age;
6
7obj.method = function(){
8 alert("对象的方法");
9}
添加get,set
xxxxxxxxxx
101let obj = {_name:null};
2
3Object.defineProperty(obj,"name",{
4 get(){
5 return this._name;
6 },
7 set(name){
8 this._name = name;
9 }
10});
js中this的两种用法
xxxxxxxxxx
91let obj = {
2 name:"tom",
3 friends:["link","jack","tony"],
4 play(){
5 this.friends.forEach(e => {
6 console.log(this.name + "与" + e + "在玩耍");
7 })
8 }
9}
xxxxxxxxxx
31tom与link在玩耍
2tom与jack在玩耍
3tom与tony在玩耍
不用箭头函数的做法
xxxxxxxxxx
101let obj = {
2 name:"tom",
3 friends:["link","jack","tony"],
4 play(){
5 let me = this;
6 this.friends.forEach(function(e){
7 console.log(this.name + "与" + e + "在玩耍");
8 })
9 }
10}
js采用原型继承方式,继承发生在对象之间
_proto_
属性引用了父类对象(原型对象)js对象都是根据原型链模式查找对象属性,没有原型的对象会有一个默认的原型Object
js以父对象为原型创建子对象
xxxxxxxxxx
11let son = Object.create(father);
特色:基于函数的原型继承
处于方便的原因,Js又提供了一种基于函数的原型继承
函数职责
1、负责创建子对象,给子对象提供属性、方法,功能上相当于构造方法
2、函数有个特殊的属性
prototype
,它就是函数创建子对象的父对象注意:区别于
_proto_
,这个属性的作用就是为新对象提供原型,实际上函数本身是有自己的_proto
属性,是函数对象的父对象
配合new关键字,创建子对象
xxxxxxxxxx
191function cons(f2){
2 //创建子对象(this),给属性f2赋值
3 this.f2 = f2;
4 //给子对象赋值方法
5 this.m2 = function(){
6 alert("子方法");
7 }
8}
9
10//cons.prototype就是父对象
11cons.prototype.f1 = "父属性"
12cons.prototype.m1 = function(){
13 alert("父方法");
14}
15
16/*
17 创建子对象,此时子对象的_proto_就是函数的prototype属性
18*/
19let son = new cons("子属性")
xxxxxxxxxx
21JSON.parse(json字符串); //返回js对象
2JSON.stringify(js对象); //返回json串
JS属于动态类型语言,值有类型,但变量没有类型,赋值给变量时,没要求
js中的??
与?.
需求:如果参数n没有传递或是null,给它一个"male",使用??
xxxxxxxxxx
31function test(n){
2 n = n ?? '男';
3}
其实??
的作用相当于在空参条件下的默认值
需求,需要访问一个对象的子属性,如果子属性在不存在的情况下就需要用到?.
此时当某个属性是nullish时,短路并返回undefined
xxxxxxxxxx
41/*在不知道city属性是否存在的情况下*/
2function test(obj){
3 console.log(obj.address?.city);
4}
展开运算符...
xxxxxxxxxx
171let arr = [1,2,3];
2//相当于test(arr[0],arr[1],arr[2])
3test(arr);
4
5//用于复制数组
6let arr2 = [arr];
7
8//用于复制对象
9let obj = {name:"tom",age:18};
10
11let obj2 = {obj}
12
13//用于合并,同时也能添加新元素
14let arr3 = [arr,5,arr2];
15
16//出现同名,则后面的会覆盖前面的
17let obj3 = {obj,obj2}
解构赋值[]{}
xxxxxxxxxx
111let arr = [1,2,3];
2
3let [a,b,c] = arr; //结果a=1,b=2,c=3
4
5//用于对象参数接收,属性名需要相同
6let obj = {name:"tom",age:18}
7
8test({name,age}){
9 alert(name,age);
10}
11test(obj);
主要用来遍历对象
xxxxxxxxxx
81let obj = {name:"tom",age:18}
2
3//const n 代表遍历出来的对象属性名
4for(const n in obj){
5 alert(n);
6 //如果要获取属性值需要用[]
7 alert(obj[n]);
8}
主要用来遍历数组,也可以是其它可迭代对象,如Map,Set等
xxxxxxxxxx
201let arr = [1,2,3];
2
3for(const i of arr){
4 console.log(i);
5}
6
7let arr2 = [
8 {name:"tom",age:18},
9 {name:"link",age:24},
10 {name:"jack",age:19}
11]
12
13//两种for of对象遍历
14for(const obj of arr2){
15 console.log(obj.name,obj.age);
16}
17
18for(const {name,age} of arr2){
19 console.log(name,age);
20}