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