CSS
1. css佈局,實現頂部高固定,左側導航寬固定,右側自適應
2. 三大定位,相對定位放在固定定位產生什麼影響?
fixed、relative、absolute
相對定位和固定定位,都會使塊級元素產生BFC,下面通過步驟檢測一下
-
設定父元素為固定定位,不設定高度,內部box設定高度和寬度,根據BFC內部box垂直排列的特徵,效果如下
<div class="sj"> <div>1</div> </div> 複製程式碼
.sj{ position: fixed; top: 0; left: 0; width: 200px; background-color: #ccc; } .sj>div{ height: 20px; width: 100px; background-color: #2db7f5; } 複製程式碼
- 若將內部box設為絕對定位,即內部box會產生BFC,根據BFC與外部互不影響的特徵,內部box將無法撐起父元素高度,如下
.sj>div{ height: 20px; width: 100px; position: absolute; background-color: #2db7f5; } 複製程式碼
3. 偽類和偽元素
偽類:向某些選擇器設定特殊效果,用於選擇器選擇不到的元素
偽元素:向某些選擇器新增特殊效果
- 偽類本質為了彌補選擇器的不足,以此獲取更多資訊
- 偽類建立一個新的虛擬容器,該容器內不包含dom節點,但可以新增內容,並且可對偽元素追加樣式
- 偽類“:”,偽元素“::”
- 可以同時使用多個偽類,但同時只能使用一個偽元素
4. 純css畫三角形
5. CSS BFC是什麼?
BFC是一個獨立的塊級渲染容器,擁有自己的渲染規則,不受外部影響,不影響外部
特徵
- 內部box垂直往下排列
- 受maigin特徵的影響,上下外邊距會塌陷
- BFC區域不會遮蓋浮動元素區域
- 計算BFC高度時,浮動元素高度也計算在內
- BFC是獨立渲染容器,外部元素不影響內部,反之亦然
產生條件
- 固定定位和絕對定位
- float除了none外
- overflow除了visible外(hidden、auto、scroll)
- display為以下其一(inline-block、table-cell、table-caption)
作用
- 清除浮動
- 消除margin重疊
- 佈局(左浮動,右BFC自適應)
6. 清除浮動的方式
1. 父元素設定偽類:clear:both + zoom:1
設定zomm為了相容IE
<div class="parent1 clearFloat">
<div class="left"></div>
</div>
<div class="parent2"></div>
.parent1{
border: 1px solid red;
}
.parent2{
height: 100px;
border: 1px solid blue;
}
.left{
width: 200px;
height: 200px;
background-color: #5cadff;
float: left;
}
.clearfloat::after{
display: block;
clear: both;
content: '';
visibility: hidden;
height: 0;
}
.clearfloat {
zoom: 1
}
複製程式碼
2. 結尾處新增空白標籤:claer:both
<div class="parent1">
<div class="left"></div>
<div class="clearfloat"></div>
</div>
<div class="parent2"></div>
.clearfloat{
clear: both;
}
複製程式碼
3. 父元素產生BFC
BFC內浮動元素高度計算在內
7. 水平垂直居中的實現方式,儘可能多
方法一、定位 + transform
.parent{
height: 500px;
width: 500px;
border: 1px solid red;
position: relative;
}
.child{
height: 80px;
width: 80px;
background-color: #515A6E;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
複製程式碼
方法二、margin + transform
.parent{
height: 500px;
width: 500px;
border: 1px solid red;
}
.child{
height: 80px;
width: 80px;
background-color: #515A6E;
margin: 50% 0 0 50%;
transform: translate(-50%, -50%);
}
複製程式碼
方法三、定位 + 負margin
.parent{
height: 500px;
width: 500px;
border: 1px solid red;
position: relative;
}
.child{
height: 80px;
width: 80px;
background-color: #515A6E;
position: absolute;
top: 50%;
left: 50%;
margin: -40px 0 0 -40px;
}
複製程式碼
方法四、flex
.parent{
height: 500px;
width: 500px;
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.child{
height: 80px;
width: 80px;
background-color: #515A6E;
}
複製程式碼
方法五、table-cell
.parent{
height: 500px;
width: 500px;
border: 1px solid red;
display: table-cell;
text-align: center;
vertical-align: middle;
}
.child{
display: inline-block;
height: 80px;
width: 80px;
background-color: #515A6E;
}
複製程式碼
8. 盒子模型
標準盒子模型
width = content
IE盒子模型
width = border + padding + content
9. 塊級元素和行內元素的區別?img可設定寬高嗎?
塊級元素
- 獨佔一行,在預設情況下,其寬度自動填滿其父元素的寬度
- 塊級元素可以設定width、height屬性
- 塊級元素即使設定了寬度也是獨佔一行,塊級元素可以設定margin、padding屬性
行內元素
- 行內元素不會獨佔一行,相鄰的行內元素會排列在同一行裡,直到行排不下,就自動換行,其寬度隨內容而變化
- 行內元素的width、height屬性則無效
- 水平方向的padding、margin會產生邊距效果,豎直方向的padding、margin不會產生邊距效果
行內建換元素
瀏覽器依據元素的標籤和屬性來決定元素的具體顯示內容
img、input、textarea、select、object屬於行內建換元素, 具有塊級元素的特徵(除寬度外)
10. absolute定位 不設定top、right、bottom、left有什麼效果?
元素脫離文件流,但因為沒有設定屬性導致無法具體定位,緊跟在上個元素之後,但下個元素排列時會忽略此元素
JavaScript
1. js輸出陣列中出現最多的元素和次數
2. 100階臺階一次走1步或2步有多少種走法
假設只走一個臺階,有1種走法;兩個臺階,2中走法,三個臺階,3種走法;四個臺階,5種走法...
1->1; 2->2; 3->3; 4->5...可以看出此問題是斐波那契數列,即下個值是前兩個值的和
公式為:f(n) = f(n-1) + f(n-2)
方法一、遍歷相加
function test (num) {
let num1 = 1, num2 = 2, res = 0
for (let i=2; i<num; i++) {
res = num1 + num2
num1 = num2
num2 = res
}
return res
}
複製程式碼
方法二、遞迴 (不推薦)
function test (num) {
if (num === 1)
return 1
else if (num === 2)
return 2
else
return test(num-1) + test(num-2)
}
複製程式碼
3. 如何實現抽獎轉盤
4. 閉包及使用場景
-
閉包
- 外部函式能夠訪問內部函式的變數
- 閉包所在的函式變數不能被垃圾回收機制回收
- 常駐記憶體,佔用記憶體使用量
-
使用場景
- 給物件設定私有變數並且利用特權方法去訪問私有屬性
- 採用函式引用方式的setTimeout呼叫
- 封裝相關功能集
5. 什麼是原型、原型鏈?
- 原型物件也是普通的物件,是物件一個自帶隱式的__proto__屬性,原型也有可能有自己的原型,如果一個原型物件的原型不為null的話,我們就稱之為原型鏈。
- 原型鏈是由一些用來繼承和共享屬性的物件組成的(有限的)物件鏈。
6. 類的建立與繼承
- 建立:new 一個Function,在prototype中新增屬性和方法
- 繼承:
- 原型鏈繼承,基於原型鏈,是父類和子類的例項,無法實現多繼承
function Cat(){} Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; // Test Code var cat = new Cat(); 複製程式碼
- 建構函式繼承:複製父類的例項給子類,只繼承父類例項的屬性與方法,不繼承原型上的,可實現多繼承
function Cat(name){ Animal.call(this) this.name = name || 'Tom'; } var cat = new Cat() 複製程式碼
- 組合繼承(原型鏈繼承+建構函式繼承)
7. new做了什麼事
- 建立一個空物件
- 將該物件的原型指向建立該物件的建構函式的prototype上
8.建立物件的方式
- 工廠模式
- 建構函式模式
- 原型模式
- 混合建構函式與原型模式
9. 深拷貝
- 陣列的深拷貝
let newArr = JSON.Parse(JSON.Stringify(oldArr))
複製程式碼
擴充套件運算子
let newArr = [...oldArr]
複製程式碼
- 物件的深拷貝
function deepClone (obj) {
let newObj = obj instanceof Array ? [] : {}
for(var i in obj){
newObj[i] = typeof obj[i] == 'object' ? deepClone(obj[i]) : obj[i]
}
return newObj
}
複製程式碼
webpack
webpack是模組打包工具,對js模組和擴充套件語言進行打包供瀏覽器識別執行
- webpack只能處理js程式碼,其他格式需要通過loader進行轉換
- 可對瀏覽器不能識別的規範和靜態檔案進行分析、壓縮、合併、打包成可供瀏覽器支援的程式碼
1. webpack和Grunt以及Gulp相比有什麼區別
-
Grunt和Gulp屬於任務流工具Tast Runner
-
webpack屬於模組打包工具 Bundler
2. webpack 的 loader 和 plugin 區別,舉幾個常用的 loader 和 plugin 並說出作用
- loader用於對模組程式碼進行轉換,可將不同格式語言轉換為JavaScript,或將影象轉換為Data Url,由於webpack只能夠識別JavaScript,所以不同型別的模組需要對應的loader進行轉換
- plugin是webpack的擴充套件外掛,可完成loader無法完成的複雜功能,可控制webpack每個打包環節的流程,極大豐富了webpack的擴充套件性
3. webpack打包過程
- 讀取檔案,分析模組的依賴
- 對模組進行解析執行(深度遍歷)
- 針對不同的模組使用不同的 loader
- 編譯模組,生成抽象語法樹(AST)
- 遍歷 AST,輸出 JS
4. webpack打包優化
- 使用compression-webpack-plugin壓縮程式碼
- 使用cdn引入第三方庫
- 按需引入第三方庫裡不同元件
Vue
1. 兄弟元件如何通訊,無巢狀,回撥觸發
方法一、通過父元件通訊
此方法需要保證兄弟元件A、B都在同一個父元件下;
父元件通過接受子元件A傳遞過來的事件訊息,並呼叫子元件B
子元件A
this.$emit('transmit', 'msg')
複製程式碼
父元件
<ChildA @transmit="transmit"></ChildA>
<ChildB :msg="msg"></ChildB>
transmit (data) => {
this.msg = data
}
複製程式碼
子元件B、需要使用watch來監聽父元件props穿過來的資料變化
watch (new, old) {
資料操作...
}
複製程式碼
方法二、eventBus
通過建立Bus.js註冊一個全域性例項,通訊元件通過呼叫例項的方法達到通訊目的
- 建立Bus.js
// eventBus 共享vue例項,用於兄弟元件資料傳遞
import Vue from 'vue'
const Bus = new Vue({})
export {Bus}
複製程式碼
- 元件A匯入Bus.js 並emit訊息
import {Bus} from './Bus.js'
Bus.$emit('transmit', 'msg')
複製程式碼
- 元件B匯入Bus.js並在mounted中檢測資料變化
import {Bus} from './Bus.js'
mounted () {
Bus.$on('transmit', (data) => {
操作...
})
}
由於$on事件無法主動銷燬,所以需要根據業務手動進行銷燬
在元件銷燬前方法中銷燬
beforeDestory () {
Bus.$off('transmit')
}
或者在使用前進行銷燬
mounted () {
Bus.$off('transmit')
Bus.$on('transmit', (data) => {
操作...
})
}
複製程式碼
2. vueRouter的工作原理
Vue Router 是路由管理器,可以改變url而不向伺服器傳送請求
有hash和history兩種路由模式
hash模式通過#之後的hash匹配路由元件;history通過url模擬hash匹配路由元件
3. Vuex的理解
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式
Vuex包含五個屬性:state、getter、mutation、action、module
- state:儲存資料,儲存狀態;註冊了Store例項後,可通過this.$store.XX來訪問;對應元件內的data,資料為響應式,元件通過store來讀取vuex的資料,若資料改變,則元件的資料也會改變
- getter:store的計算屬性,它的返回值會被依賴快取起來,當依賴值發生變化時才會被重新計算
- mutation:更改Vuex的store中狀態的唯一方法是提交mutation
- action:包含任意非同步操作,通過提交 mutation 間接更變狀態
- module:將 store 分割成模組,每個模組都具有state、mutation、action、getter、甚至是巢狀子模組
當元件進行資料修改的時候,通過呼叫dispatch來觸發actions裡面的方法,actions裡每個方法都有commit方法,通過執行commit方法來觸發mutation裡的方法進行資料修改,由於mutation裡每個函式都有一個state引數,進而可對state進行修改,當資料修改完畢後,會傳導給頁面。頁面的資料也會發生改變。
4. vue Dom渲染的過程和原理
- new Vue 初始化Vue例項
- 通過三種渲染模式 Render、el、template 生成Render函式
- 通過Watcher監測資料變化
- 當資料變化時,通過Render函式生成VNode
- 通過patchVnode對比前後變化,通過diff進行更新、新增、刪除等操作生成真實Dom節點
5. watch用法
watch用來監聽並響應資料的變化
- 可以直接監聽基本資料型別資料
- 若是監聽物件,則需要開啟deep(深度監聽)
- 若是監聽陣列,則不需要開啟deep監聽
- immediate 初始化繫結值時即執行監聽
- watch首次初始化繫結不執行,但監聽的值發生變化時則執行監聽
data () {
return {
age: 20,
obj: {
age: 24
},
arr: [1,2,3]
}
}
複製程式碼
1. 監聽基本型別
watch: {
age (newd, oldd) {
...
}
}
複製程式碼
2. 監聽物件
watch: {
obj: {
handler (newd, oldd) {
...
},
deep: true, // 開啟深度監聽
immediate: true // 首次即執行
}
}
複製程式碼
3. 監聽物件某個屬性
*** 採用字串
watch: {
'obj.age': {
handler (newd, oldd) {
...
}
}
}
*** 利用computed計算屬性
computed: {
age () {
return this.obj.age
}
}
watch: {
age (newd, oldd) {
...
}
// 也可寫為
age: {
handler (newd, oldd) {
...
}
}
}
複製程式碼
6. vue nextTick
非同步更新佇列
Vue 非同步執行 DOM 更新。只要觀察到資料變化,Vue將開啟一個佇列,並緩衝在同一事件迴圈中發生的所有資料改變。如果同一個 watcher被多次觸發,只會被推入到佇列中一次。這種在緩衝時去除重複資料對於避免不必要的計算和 DOM 操作是非常重要的。然後,在下一個的事件迴圈“tick”中,Vue重新整理佇列並執行實際 (已去重的) 工作。Vue 在內部嘗試對非同步佇列使用原生的Promise.then和MessageChannel,如果執行環境不支援,會採用 setTimeout(fn, 0) 代替。
例如,當你設定 vm.someData='newvalue',該元件不會立即重新渲染。當重新整理佇列時,元件會在事件迴圈佇列清空時的下一個“tick”更新
nextTick
由於DOM是非同步執行更新的,有時我們修改完資料等待DOM更新後進行操作,則此刻可使用Vue.nextTick(callback)
Vue.component('example', {
template: '<span>{{ message }}</span>',
data: function () {
return {
message: '沒有更新'
}
},
methods: {
updateMessage: function () {
this.message = '更新完成'
console.log(this.$el.textContent) // => '沒有更新'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '更新完成'
})
}
}
})
複製程式碼
因為 $nextTick() 返回一個 Promise 物件,所以你可以使用新的ES2016async/await語法完成相同的事情:
methods: {
updateMessage: async function () {
this.message = 'updated'
console.log(this.$el.textContent) // => '未更新'
await this.$nextTick()
console.log(this.$el.textContent) // => '已更新'
}
}
複製程式碼
7. vue 生命週期有哪些?
- beforeCreate ----建立前
- created ---- 成功建立
- beforeMount ---- 掛載前
- mounted ---- 成功掛載
- beforeUpdate ---- 更新前
- updated ---- 成功更新
- beforeDestroy ---- 銷燬前
- destroyed ---- 成功銷燬
8. vue 響應式資料是如何實現的?
網路
1. 瀏覽器輸入地址後發生什麼
- 解析URL
- DNS解析、監測快取
- 客戶端與服務端建立TCP連線(三次握手)
- 請求與傳輸資料
- 進行資料渲染
- 解析HTML、生成DOM樹、解析CSS程式碼、將資料渲染到網頁上
2. 輪詢、長連線、websocket區別
- 輪詢:每間隔規定時間,向伺服器傳送ajax請求,無需等待響應
- 長連線:每次傳送完請求後,等待response後再傳送請求
- websocket:h5提供的基於TCP的雙向通訊協議,伺服器主動推送訊息到客戶端,只需一次握手連線,即可建立持久連線
3. 三次握手、四次分手
- 三次握手
客戶端 ->(建立連線)-> 伺服器
客戶端 <-(確認接受,建立連線)<- 伺服器
客戶端 ->(確認接受)-> 伺服器
複製程式碼
- 四次分手
客戶端 ->(關閉連線)-> 伺服器
客戶端 <-(確認關閉)<- 伺服器
客戶端 <-(關閉連線)<- 伺服器
客戶端 ->(確認關閉)-> 伺服器
複製程式碼
4. 請求狀態碼
- 2XX 請求成功(200 請求成功、204 請求成功,但未有任何資源返回、206 範圍請求)
- 3XX 重定向(301 url已更新、302 url重定向、303 是否訪問新的url、304 資源找到,不符合條件)
- 4XX 客戶端錯誤(401 需要驗證、403 不允許訪問)
- 5XX 伺服器錯誤
5. 如何防禦XSS攻擊
xss(跨站指令碼攻擊)攻擊是在返回的html中嵌入js指令碼
- 需要在http頭部加上set-cookie httponly(禁止js訪問cookie) secure(在https時傳送cookie)
6. ajax請求過程
- 建立XMLHttpRequest物件,
- 建立http請求,並指明請求的url,方式和引數
- 設定http請求狀態變化的函式
- 傳送http請求
- 通過回撥獲取返回的資料
- 渲染