一、HTML5
(1)語意化標(biāo)簽
<header> // 頭部
<mian> // 主體
<footer> // 底部
(2)視頻和音頻標(biāo)簽
<video> // 視頻標(biāo)簽
<audio> // 音頻
(3)新增表單屬性
placeholder // 輸入框提示文字
required // 是否必填
autofocus // 自動(dòng)獲取焦點(diǎn)
(4)canvas
??通過javaScript來繪制圖像
應(yīng)用: 通過canvas繪制優(yōu)化圖片大小,通過fileReader獲取到圖片文件,然后創(chuàng)建一個(gè)canvas標(biāo)簽,通過getContext()獲取到他的上下文,canvas調(diào)用drawImage(image,x, y, w, h)將圖片繪制到畫布中,canvas調(diào)用ToDataUrl()方法,傳入圖片格式和圖片質(zhì)量,轉(zhuǎn)換成dataUrl的格式,設(shè)置一個(gè)目標(biāo)大小,如果不滿足就重復(fù)這個(gè)壓縮的過程,可以按比例的降低質(zhì)量或者尺寸以達(dá)到降低圖片大小的目標(biāo)。
//核心代碼
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的數(shù)據(jù)轉(zhuǎn)換成file格式resolve出去
const compressFile = dataURLtoFile(data, fileName)
reslove(compressFile)
};
image.src = file.target.result;
}
reader.readAsDataURL(file);
})
}
/**
* 將 image 對(duì)象 畫入畫布并導(dǎo)出base64數(shù)據(jù)
*/
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上,從原點(diǎn)0,0繪制到w,h
ctx.drawImage(image, 0, 0, w, h);
let dataUrl = cvs.toDataURL(`image/jpeg`, quality);
// 當(dāng)圖片大小 > maxSize 時(shí),循環(huán)壓縮,并且循環(huán)不超過10次
let count = 0;
while (dataUrl.length > maxSize && count < 10) {
const imgDataLength = dataUrl.length;
const isDoubleSize = imgDataLength / maxSize > 2;
// 質(zhì)量一次下降
quality -= isDoubleSize ? COMPRESS_QUALITY_STEP_BIG : COMPRESS_QUALITY_STEP;
quality = parseFloat(quality.toFixed(2));
// 圖片還太大的情況下,繼續(xù)壓縮 。 按比例縮放尺寸
const scaleStrength = COMPRESS_SIZE_RATE;
w = w * scaleStrength;
h = h * scaleStrength;
size = prepareCanvas(cvs, ctx, w, h, 6);
// 將圖片繪制到Canvas上,從原點(diǎn)0,0繪制到w,h
ctx.drawImage(image, 0, 0, w, h);
dataUrl = cvs.toDataURL(`image/jpeg`, quality);
count++;
}
cvs = ctx = null;
return dataUrl;
}
// 將dataurl格式的圖片數(shù)據(jù)轉(zhuǎn)換為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)拖拽
??元素可以設(shè)置一個(gè)拖拽的屬性dragable,在拖拽的過程中會(huì)有很鉤子函數(shù)供我們進(jìn)行操作例如:開始拖動(dòng):ondragstatr() ;拖動(dòng)中: ondrag();拖動(dòng)結(jié)束:ondragend();
(7)web worker(優(yōu)化,復(fù)雜的js操作阻塞瀏覽器渲染,導(dǎo)致頁(yè)面卡死)
??通過加載一個(gè)腳本來創(chuàng)建一個(gè)新的工作線程。通過postmessage和onmessage進(jìn)行通話, 需要手動(dòng)關(guān)閉通過調(diào)用 self.close() 或者 worker.terminate()來關(guān)閉工作線程
// demo
// work.js
onmessage = function(event) { // 監(jiān)聽數(shù)據(jù)傳入
const { repeatData } = event.data;
postMessage([...new Set(repeatData)]); // 處理完講數(shù)據(jù)發(fā)送給主線程
}
//webWorker.html
<script>
var myWorker = new Worker('./work.js') // 創(chuàng)建一個(gè)web worker 將要執(zhí)行的腳本路徑傳入
myWorker.postMessage({handle: '數(shù)組去重', repeatData: [1,1,2,3,4,2]}) // 發(fā)送
myWorker.onmessage = function(evt) { // 接收
console.log(evt.data);
}
</script>
(8)storage本地存儲(chǔ)
?? 一共兩種: localstorage和sessionstorage
?? localstorage:需要手動(dòng)removeItem()
?? sessionstorage:瀏覽器窗口關(guān)閉就會(huì)被刪除
(8)websocket
??程序客戶端和服務(wù)端之間提供了一種全雙工通信機(jī)制
二、CSS
(1)浮動(dòng):float: none left right
浮動(dòng)的貼靠性:當(dāng)剩余空間不足,元素會(huì)尋找上一個(gè)兄弟節(jié)點(diǎn);

浮動(dòng)的元素具有塊元素的特性;
浮動(dòng)的元素會(huì)導(dǎo)致父元素高度塌陷;
(3)BFC塊級(jí)格式上下文: 它是一個(gè)渲染區(qū)域并且有自己的規(guī)則
高度:浮動(dòng)元素也算在內(nèi),通常用overflow屬性來清除浮動(dòng),影響最小
BFC外的互相不影響
不會(huì)與浮動(dòng)的box重疊
BFC外的互相不影響
成為BFC的條件: display: flex/inline-block ; overflow不是visible
(4)display:none; visibility:hidden;opacity: 0;三者的區(qū)別
相同點(diǎn): 他們都存在于Render tree中,審查元素的時(shí)候標(biāo)簽都存在。
不同點(diǎn):
display: 不渲染;不能進(jìn)行dom的事件監(jiān)聽; 觸發(fā)重繪和重排;子元素不繼承
visibility:渲染只占位置內(nèi)容隱藏;不能進(jìn)行dom事件監(jiān)聽; 觸發(fā)重繪; 子元素繼承可修改;
opacity: 渲染 不透明度為 0 ;可以進(jìn)行dom事件監(jiān)聽;不一定觸發(fā)重繪(有合成層就不重繪,沒有就重繪);可以繼承但是子元素修改無用;
(4)重繪和回流(重排)
瀏覽器請(qǐng)求回來一個(gè)html文件的時(shí)候,會(huì)解析出DOM和CSSOM,然后合并成為Render Tree ,然后經(jīng)過layout 布局計(jì)算出每一個(gè)節(jié)點(diǎn)的大小 位置 顏色等信息,渲染display屬性不為none的所有節(jié)點(diǎn)。
重繪:字體顏色 背景色 visibility屬性 改變會(huì)發(fā)生重繪操作。
回流(重排):render tree中元素 位置 尺寸 內(nèi)容改變的時(shí)候,需要重新布局渲染的過程;
引起重排的操作:<1>第一次加載 <2>元素內(nèi)容變化 <3>元素尺寸位置變化 <4>瀏覽器窗口大小改變 <5>訪問部分屬性 width height clientwidth ...
重排一定會(huì)重繪,重繪不一定會(huì)引起重排,重排的消耗更大
減少重排的做法: <1>減少對(duì)css命令式的更改 document.style.width = XXX
<2>通過修改 類名的方式 減少重排的次數(shù)<3> 盡量修改最底層的樣式 縮小范圍
訪問瀏覽器的屬性導(dǎo)致回流的原因:瀏覽器對(duì)重排會(huì)進(jìn)行優(yōu)化,將多次的回流事件序列化,一定時(shí)間或者達(dá)到一定的閥值會(huì)進(jìn)行一次性處理,遇到訪問元素屬性的時(shí)候,因?yàn)橐祷刈钚碌闹邓詴?huì)清空隊(duì)列然后進(jìn)行一次回流
(5)動(dòng)畫
(6)移動(dòng)端布局方式
三、JS基礎(chǔ)
(1)js的繼承
原型繼承
構(gòu)造函數(shù)繼承
組合式繼承
類繼承
(2)閉包
保存變量不被銷毀的代碼塊,定義在函數(shù)中的函數(shù)。
為什么會(huì)出現(xiàn)閉包: 函數(shù)在聲明的時(shí)候,他的文本環(huán)境就被存儲(chǔ)在內(nèi)存中,包含了他可以訪問的父級(jí)別作用域的變量。所以父函數(shù)被執(zhí)行完后他還是可以訪問到父級(jí)作用域內(nèi)的變量,所以不會(huì)被銷毀;
應(yīng)用:<1>封裝一個(gè)不會(huì)污染全局環(huán)境的私有變量<2>防抖函數(shù)
(3)原型鏈
一個(gè)對(duì)象在被初始化的時(shí)候會(huì)關(guān)聯(lián)另一個(gè)對(duì)象,并且繼承該對(duì)象身上的屬性和方法。
每個(gè)對(duì)象都有一個(gè)__proto__指向構(gòu)造函數(shù)的__prototype__屬性
每個(gè)對(duì)象都有一個(gè)屬性constructor屬性指向他的構(gòu)造函數(shù)
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);

(4)執(zhí)行上下文
定義:js引擎為了為了處理和轉(zhuǎn)換JavaScript創(chuàng)造的一種特殊的環(huán)境。
分為兩類: 全局執(zhí)行上下文 和 函數(shù)執(zhí)行上下文
執(zhí)行上下文是在被調(diào)用的時(shí)侯創(chuàng)建的:全局和函數(shù)執(zhí)行上下文
創(chuàng)建過程:第一階段:<1>創(chuàng)建變量對(duì)象:var let const 變量提升 暫時(shí)性死區(qū),變量名重復(fù)校驗(yàn) <2>創(chuàng)建作用域鏈:從內(nèi)存中拿出它可以訪問的父級(jí)作用域和當(dāng)前的作用域相關(guān)聯(lián),子可以訪問父,然后設(shè)置this的值;第二階段:執(zhí)行階段,創(chuàng)建完后壓入棧中。當(dāng)前執(zhí)行上下文就是棧頂?shù)膱?zhí)行上下文。如果有新的執(zhí)行上下文被創(chuàng)建則壓棧,沒有就出棧。
(5)事件循環(huán)
JS是單線程語言,不是只有一個(gè)線程,而是只有一個(gè)主線程來執(zhí)行JS代碼。還有其他的工作線程:包括定時(shí)器線程 文件I/O線程 ajax請(qǐng)求線程 這些線程主要是用來執(zhí)行異步的任務(wù),異步調(diào)用成功后將回調(diào)時(shí)間放到事件隊(duì)列中,主線程在執(zhí)行完同步代碼后,從事件隊(duì)列中拿回調(diào)函數(shù)來執(zhí)行。事件循環(huán)就是反復(fù)這個(gè)過程。
異步任務(wù)分為宏任務(wù)和微任務(wù)。
宏任務(wù): settimeout setinterval 代碼塊;web api
微任務(wù): promise ;js內(nèi)置對(duì)象
執(zhí)行順序:先執(zhí)行宏任務(wù): 再執(zhí)行微任務(wù)
為什么會(huì)有微任務(wù): 以前都是:宏任務(wù) => 渲染 => 宏任務(wù) => 渲染
為了給微任務(wù)一個(gè)插隊(duì)的機(jī)會(huì),并不是因?yàn)槟硞€(gè)漏洞才增加的微任務(wù),從沒有到有的過程經(jīng)歷了很多,都是為了語言的功能更加強(qiáng)大,做更多的事。
四、ES6
文檔:https://sagittarius-rev.gitbooks.io/understanding-ecmascript-6-zh-ver/content/
(1)let const 聲明
存在暫時(shí)性死區(qū),聲明之前訪問會(huì)報(bào)錯(cuò);const聲明的是常量
(2)新增symbol數(shù)據(jù)類型代表獨(dú)一無二的意思
主要用來給對(duì)象添加屬性的時(shí)候防止覆蓋掉原有的屬性
(3)擴(kuò)展了數(shù)組的方法
array.of array.from
find系列: findindex find
filter過濾;
(4)新增set map 集合
set: 無重復(fù)值的列表 add(); delete()
map: 鍵值對(duì)的有序列表;傳統(tǒng)的對(duì)象會(huì)吧key值轉(zhuǎn)換為字符串,而map不會(huì) set() get() haskey() delete()
(5)Promise
異步編程的一種方案,區(qū)別于以往的嵌套函數(shù)他是可以使用鏈?zhǔn)秸{(diào)用的方式來書寫代碼。它包含了3種狀態(tài):進(jìn)行中 已完成 已失敗 ,狀態(tài)由進(jìn)行中改變?yōu)橐淹瓿苫蛘咭咽∈遣豢赡娴?,異步調(diào)用成功后,將返回的數(shù)據(jù)resovle出去,使用.then來處理回調(diào)。promise.all([]) promise.race([])
(6)模塊化
es的模塊化是通過import導(dǎo)入 export導(dǎo)出,它屬于編譯時(shí)加載,解析時(shí)先加載最里面的模塊,加載的模塊只是一個(gè)引用,真正使用到的時(shí)候才回去取值。
區(qū)別于node的模塊化:node的模塊化是根據(jù)commonjs的規(guī)范來實(shí)現(xiàn)的,通過module.exports導(dǎo)出,通過require()導(dǎo)入。屬于運(yùn)行時(shí)加載,而且是同步加載。所以一般require都寫在最上面。
五、瀏覽器
(1)垃圾回收機(jī)制
標(biāo)記清除法: 被引用標(biāo)記為1,沒被引用標(biāo)記0 ,定期清除為0的變量, 內(nèi)存不連續(xù)優(yōu)化出標(biāo)記整理法,將標(biāo)記為1的移動(dòng)到一端,清除另一端
引用計(jì)數(shù)法:每被引用一次就+1,缺點(diǎn):次數(shù)需要保存,循環(huán)引用:
const a = new Object(); const b = new Object(); a.b = b; b.a =a ;無法被清除 棄用
(2)瀏覽器緩存機(jī)制
強(qiáng)制緩存:三種情況<1>強(qiáng)制緩存失效:結(jié)果和標(biāo)識(shí)都沒有,直接請(qǐng)求服務(wù)器<2>強(qiáng)制緩存失效,使用協(xié)商緩存: 結(jié)果失效,標(biāo)識(shí)還在,拿著標(biāo)識(shí)取請(qǐng)求服務(wù)器<3>生效: 結(jié)果和標(biāo)識(shí)都在
主要是實(shí)現(xiàn)的字段是catch-control:<1>no-cache:客戶端緩存內(nèi)容,但是是否使用緩存則需要經(jīng)過協(xié)商緩存來驗(yàn)證決定<2> max-age:緩存多少秒失效<3>no-store:不緩存
協(xié)商緩存:緩存結(jié)果失效,緩存標(biāo)識(shí)存在,拿著標(biāo)識(shí)去請(qǐng)求服務(wù)器,服務(wù)器告訴瀏覽器沒有更新,則使用緩存結(jié)果,如果有更新,則獲取新的內(nèi)容 然后將緩存結(jié)果和緩存標(biāo)識(shí)存儲(chǔ)在緩存中
六、網(wǎng)絡(luò)
(1)http和https
(2)cors
定義: 跨域資源共享
瀏覽器將cors分為兩種: 簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求

簡(jiǎn)單請(qǐng)求過程: 瀏覽器發(fā)現(xiàn)這個(gè)請(qǐng)求是跨域請(qǐng)求,會(huì)加上一個(gè)origin:當(dāng)前的協(xié)議域名端口,發(fā)送給服務(wù)器,服務(wù)器正常返回,瀏覽器發(fā)現(xiàn)這個(gè)origin不在access-control-allow-origin范圍內(nèi)就會(huì)拋出異常,如果在這個(gè)范圍內(nèi)就會(huì)返回多幾個(gè)字段,
(3)session和cookie和token的區(qū)別
cookie:保存在本地,每次請(qǐng)求的時(shí)候放在http請(qǐng)求報(bào)文中的setcookie字段中,可以被篡改不安全,
session:保存在服務(wù)器端,用戶向服務(wù)器發(fā)送登錄請(qǐng)求,服務(wù)器響應(yīng)成功會(huì)生成一個(gè)session 存放在服務(wù)器中。
session的cookie實(shí)現(xiàn):服務(wù)器返回給客戶端一個(gè)sessionId然后存儲(chǔ)在cookie中,每次請(qǐng)求都會(huì)帶上這個(gè)sessionId,服務(wù)器接收到請(qǐng)求會(huì)獲取這個(gè)sessionId進(jìn)行驗(yàn)證
問題: 用戶量太大,session存儲(chǔ)是一個(gè)比較難解決的問題
jwt:json web token的縮寫,
過程:客戶端發(fā)起登錄請(qǐng)求,服務(wù)器根據(jù)密鑰加密生成jwt返回給前端 ,前端可以使用兩種方式每次請(qǐng)求攜帶上jwtToken,第一種是cookie,第二種是掛再http請(qǐng)求頭字段authorization字段中,服務(wù)器接收到j(luò)wtToken調(diào)用JWT.verify(token, '密鑰')解密,然后判斷是否合法。jwt由三部分組成:headers (加密算法)payload(簽發(fā)人 到期時(shí)間 id等數(shù)據(jù)) signature(headers和payload通過base64轉(zhuǎn)碼再根據(jù)密鑰加密生成的字符串),三者用.連接。
特點(diǎn): 一旦簽發(fā)不能更改,到期之前一直有效
image.png
