前端基础
一、HTML5
(1)语意化标签
<header> // 头部
<mian> // 主体
<footer> // 底部
(2)视频和音频标签
<video> // 视频标签
<audio> // 音频
(3)新增表单属性
placeholder // 输入框提示文字
required // 是否必填
autofocus // 自动获取焦点
(4)canvas
通过javaScript来绘制图像
应用: 通过canvas绘制优化图片大小,通过fileReader获取到图片文件,然后创建一个canvas标签,通过getContext()获取到他的上下文,canvas调用drawImage(image,x, y, w, h)将图片绘制到画布中,canvas调用ToDataUrl()方法,传入图片格式和图片质量,转换成dataUrl的格式,设置一个目标大小,如果不满足就重复这个压缩的过程,可以按比例的降低质量或者尺寸以达到降低图片大小的目标。
//核心代码
export function imageListConvert(file, options = {}) {
options = { ...defaultOptions, ...options };
const fileName = file.name
return new Promise((reslove) => {
console.log('压缩前:', parseFloat(file.size / 1048576).toFixed(2), 'M')
const reader = new FileReader();
reader.onload = function(file) {
const image = new Image();
image.onload = function() {
// 用canvas绘制,并压缩
const data = convertImage(image, options.maxSize, options.fillBgColor);
// 将压缩后的dataurl的数据转换成file格式resolve出去
const compressFile = dataURLtoFile(data, fileName)
reslove(compressFile)
};
image.src = file.target.result;
}
reader.readAsDataURL(file);
})
}
/**
* 将 image 对象 画入画布并导出base64数据
*/
export function convertImage(
image,
maxSize = 1024 * 1024 * 5,
fillBgColor = '#ffffff'
) {
const maxWidth = 1280
const maxHeight = 1280
let cvs = document.createElement('canvas')
let w = image.width
let h = image.height
let quality = 0.9;
let ctx = cvs.getContext('2d');
// 填充白色背景
ctx.fillStyle = fillBgColor;
ctx.fillRect(0, 0, w, h);
// 将图片绘制到Canvas上,从原点0,0绘制到w,h
ctx.drawImage(image, 0, 0, w, h);
let dataUrl = cvs.toDataURL(`image/jpeg`, quality);
// 当图片大小 > maxSize 时,循环压缩,并且循环不超过10次
let count = 0;
while (dataUrl.length > maxSize && count < 10) {
const imgDataLength = dataUrl.length;
const isDoubleSize = imgDataLength / maxSize > 2;
// 质量一次下降
quality -= isDoubleSize ? COMPRESS_QUALITY_STEP_BIG : COMPRESS_QUALITY_STEP;
quality = parseFloat(quality.toFixed(2));
// 图片还太大的情况下,继续压缩 。 按比例缩放尺寸
const scaleStrength = COMPRESS_SIZE_RATE;
w = w * scaleStrength;
h = h * scaleStrength;
size = prepareCanvas(cvs, ctx, w, h, 6);
// 将图片绘制到Canvas上,从原点0,0绘制到w,h
ctx.drawImage(image, 0, 0, w, h);
dataUrl = cvs.toDataURL(`image/jpeg`, quality);
count++;
}
cvs = ctx = null;
return dataUrl;
}
// 将dataurl格式的图片数据转换为file的格式
function dataURLtoFile(dataurl, filename) {
const arr = dataurl.split(',')
const bstr = window.atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type: 'image/jpeg',
})
}
(5)位置信息api getCurrentPosition()获取用户的位置信息
(6)拖拽
元素可以设置一个拖拽的属性dragable,在拖拽的过程中会有很钩子函数供我们进行操作例如:开始拖动:ondragstatr() ;拖动中: ondrag();拖动结束:ondragend();
(7)web worker(优化,复杂的js操作阻塞浏览器渲染,导致页面卡死)
通过加载一个脚本来创建一个新的工作线程。通过postmessage和onmessage进行通话, 需要手动关闭通过调用 self.close() 或者 worker.terminate()
来关闭工作线程
// demo
// work.js
onmessage = function(event) { // 监听数据传入
const { repeatData } = event.data;
postMessage([...new Set(repeatData)]); // 处理完讲数据发送给主线程
}
//webWorker.html
<script>
var myWorker = new Worker('./work.js') // 创建一个web worker 将要执行的脚本路径传入
myWorker.postMessage({handle: '数组去重', repeatData: [1,1,2,3,4,2]}) // 发送
myWorker.onmessage = function(evt) { // 接收
console.log(evt.data);
}
</script>
(8)storage本地存储
一共两种: localstorage和sessionstorage
localstorage:需要手动removeItem()
sessionstorage:浏览器窗口关闭就会被删除
(8)websocket
程序客户端和服务端之间提供了一种全双工通信机制
二、CSS
(1)浮动:float: none left right
浮动的贴靠性:当剩余空间不足,元素会寻找上一个兄弟节点;
image.png
浮动的元素具有块元素的特性;
浮动的元素会导致父元素高度塌陷;
(3)BFC块级格式上下文: 它是一个渲染区域并且有自己的规则
高度:浮动元素也算在内,通常用overflow属性来清除浮动,影响最小
BFC外的互相不影响
不会与浮动的box重叠
BFC外的互相不影响
成为BFC的条件: display: flex/inline-block ; overflow不是visible
(4)display:none; visibility:hidden;opacity: 0;三者的区别
相同点: 他们都存在于Render tree中,审查元素的时候标签都存在。
不同点:
display: 不渲染;不能进行dom的事件监听; 触发重绘和重排;子元素不继承
visibility:渲染只占位置内容隐藏;不能进行dom事件监听; 触发重绘; 子元素继承可修改;
opacity: 渲染 不透明度为 0 ;可以进行dom事件监听;不一定触发重绘(有合成层就不重绘,没有就重绘);可以继承但是子元素修改无用;
(4)重绘和回流(重排)
浏览器请求回来一个html文件的时候,会解析出DOM和CSSOM,然后合并成为Render Tree ,然后经过layout 布局计算出每一个节点的大小 位置 颜色等信息,渲染display属性不为none的所有节点。
重绘:字体颜色 背景色 visibility属性 改变会发生重绘操作。
回流(重排):render tree中元素 位置 尺寸 内容改变的时候,需要重新布局渲染的过程;
引起重排的操作:<1>第一次加载 <2>元素内容变化 <3>元素尺寸位置变化 <4>浏览器窗口大小改变 <5>访问部分属性 width height clientwidth ...
重排一定会重绘,重绘不一定会引起重排,重排的消耗更大
减少重排的做法: <1>减少对css命令式的更改 document.style.width = XXX
<2>通过修改 类名的方式 减少重排的次数<3> 尽量修改最底层的样式 缩小范围
访问浏览器的属性导致回流的原因:浏览器对重排会进行优化,将多次的回流事件序列化,一定时间或者达到一定的阀值会进行一次性处理,遇到访问元素属性的时候,因为要返回最新的值所以会清空队列然后进行一次回流
(5)动画
(6)移动端布局方式
三、JS基础
(1)js的继承
原型继承
构造函数继承
组合式继承
类继承
(2)闭包
保存变量不被销毁的代码块,定义在函数中的函数。
为什么会出现闭包: 函数在声明的时候,他的文本环境就被存储在内存中,包含了他可以访问的父级别作用域的变量。所以父函数被执行完后他还是可以访问到父级作用域内的变量,所以不会被销毁;
应用:<1>封装一个不会污染全局环境的私有变量<2>防抖函数
(3)原型链
一个对象在被初始化的时候会关联另一个对象,并且继承该对象身上的属性和方法。
每个对象都有一个__proto__
指向构造函数的__prototype__
属性
每个对象都有一个属性constructor
属性指向他的构造函数
function Person() {
this.age = 26
}
const a = new Object()
const lec = new Person()
console.log(lec.__proto__ === Person.prototype);
console.log(Person.prototype.constructor === Person);
console.log(lec.constructor === Person);
console.log(Person.__proto__ === Function.prototype);
console.log(Function.__proto__ === Function.prototype); // function Function()
console.log(Person.prototype.__proto__ === Object.prototype);
console.log(Function.prototype.__proto__ === Object.prototype);
console.log(a.__proto__ === Object.prototype);
console.log(Object.prototype.__proto__ === null);
1632878-20190507094639999-1584111224.png
(4)执行上下文
定义:js引擎为了为了处理和转换JavaScript创造的一种特殊的环境。
分为两类: 全局执行上下文 和 函数执行上下文
执行上下文是在被调用的时侯创建的:全局和函数执行上下文
创建过程:第一阶段:<1>创建变量对象:var let const 变量提升 暂时性死区,变量名重复校验 <2>创建作用域链:从内存中拿出它可以访问的父级作用域和当前的作用域相关联,子可以访问父,然后设置this的值;第二阶段:执行阶段,创建完后压入栈中。当前执行上下文就是栈顶的执行上下文。如果有新的执行上下文被创建则压栈,没有就出栈。
(5)事件循环
JS是单线程语言,不是只有一个线程,而是只有一个主线程来执行JS代码。还有其他的工作线程:包括定时器线程 文件I/O线程 ajax请求线程 这些线程主要是用来执行异步的任务,异步调用成功后将回调时间放到事件队列中,主线程在执行完同步代码后,从事件队列中拿回调函数来执行。事件循环就是反复这个过程。
异步任务分为宏任务和微任务。
宏任务: settimeout setinterval 代码块;web api
微任务: promise ;js内置对象
执行顺序:先执行宏任务: 再执行微任务
为什么会有微任务: 以前都是:宏任务 => 渲染 => 宏任务 => 渲染
为了给微任务一个插队的机会,并不是因为某个漏洞才增加的微任务,从没有到有的过程经历了很多,都是为了语言的功能更加强大,做更多的事。
四、ES6
文档:https://sagittarius-rev.gitbooks.io/understanding-ecmascript-6-zh-ver/content/
(1)let const 声明
存在暂时性死区,声明之前访问会报错;const声明的是常量
(2)新增symbol数据类型代表独一无二的意思
主要用来给对象添加属性的时候防止覆盖掉原有的属性
(3)扩展了数组的方法
array.of array.from
find系列: findindex find
filter过滤;
(4)新增set map 集合
set: 无重复值的列表 add(); delete()
map: 键值对的有序列表;传统的对象会吧key值转换为字符串,而map不会 set() get() haskey() delete()
(5)Promise
异步编程的一种方案,区别于以往的嵌套函数他是可以使用链式调用的方式来书写代码。它包含了3种状态:进行中 已完成 已失败 ,状态由进行中改变为已完成或者已失败是不可逆的,异步调用成功后,将返回的数据resovle出去,使用.then来处理回调。promise.all([]) promise.race([])
(6)模块化
es的模块化是通过import导入 export导出,它属于编译时加载,解析时先加载最里面的模块,加载的模块只是一个引用,真正使用到的时候才回去取值。
区别于node的模块化:node的模块化是根据commonjs的规范来实现的,通过module.exports导出,通过require()导入。属于运行时加载,而且是同步加载。所以一般require都写在最上面。
五、浏览器
(1)垃圾回收机制
标记清除法: 被引用标记为1,没被引用标记0 ,定期清除为0的变量, 内存不连续优化出标记整理法,将标记为1的移动到一端,清除另一端
引用计数法:每被引用一次就+1,缺点:次数需要保存,循环引用:
const a = new Object(); const b = new Object(); a.b = b; b.a =a ;
无法被清除 弃用
(2)浏览器缓存机制
强制缓存:三种情况<1>强制缓存失效:结果和标识都没有,直接请求服务器<2>强制缓存失效,使用协商缓存: 结果失效,标识还在,拿着标识取请求服务器<3>生效: 结果和标识都在
主要是实现的字段是catch-control:<1>no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定<2> max-age:缓存多少秒失效<3>no-store:不缓存
协商缓存:缓存结果失效,缓存标识存在,拿着标识去请求服务器,服务器告诉浏览器没有更新,则使用缓存结果,如果有更新,则获取新的内容 然后将缓存结果和缓存标识存储在缓存中
六、网络
(1)http和https
(2)cors
定义: 跨域资源共享
浏览器将cors分为两种: 简单请求和非简单请求
简单请求过程: 浏览器发现这个请求是跨域请求,会加上一个origin:当前的协议域名端口,发送给服务器,服务器正常返回,浏览器发现这个origin不在access-control-allow-origin范围内就会抛出异常,如果在这个范围内就会返回多几个字段,
(3)session和cookie和token的区别
cookie:保存在本地,每次请求的时候放在http请求报文中的setcookie字段中,可以被篡改不安全,
session:保存在服务器端,用户向服务器发送登录请求,服务器响应成功会生成一个session 存放在服务器中。
session的cookie实现:服务器返回给客户端一个sessionId然后存储在cookie中,每次请求都会带上这个sessionId,服务器接收到请求会获取这个sessionId进行验证
问题: 用户量太大,session存储是一个比较难解决的问题
jwt:json web token的缩写,
image.png
过程:客户端发起登录请求,服务器根据密钥加密生成jwt返回给前端 ,前端可以使用两种方式每次请求携带上jwtToken,第一种是cookie,第二种是挂再http请求头字段authorization字段中,服务器接收到jwtToken调用JWT.verify(token, '密钥')
解密,然后判断是否合法。jwt由三部分组成:headers (加密算法)payload(签发人 到期时间 id等数据) signature(headers和payload通过base64转码再根据密钥加密生成的字符串),三者用.连接。
特点: 一旦签发不能更改,到期之前一直有效