認真對待每一道面試題
CSS部分
CSS中 link 和@import 的區(qū)別是夺姑?
link屬于HTML標簽扑浸,而@import是CSS提供的,頁面被加載的時迈倍,link會同時被加載择浊,而@import引用的CSS會等到頁面被加載完再加載
import只在IE5以上才能識別戴卜,而link是HTML標簽,無兼容問題
link方式的樣式的權重 高于@import的權重.
css3實現三欄布局琢岩,左右固定投剥,中間自適應
圣杯布局/雙飛翼布局
如何修改Chrome記住密碼后自動填充表單的黃色背景?
產生原因:由于Chrome默認會給自動填充的input表單加上 input:-webkit-autofill 私有屬性造成的
解決方案1:在form標簽上直接關閉了表單的自動填充:autocomplete="off"
解決方案2:input:-webkit-autofill { background-color: transparent; }
display:inline-block 什么時候會顯示間隙担孔?(攜程)
產生原因:元素被當成行內元素排版的時候江锨,元素之間的空白符(空格吃警、回車換行等)都會被瀏覽器處理,根據white-space的處理方式(默認是normal啄育,合并多余空白)酌心,原來HTML代碼中的回車換行被轉成一個空白符,在字體不為0的情況下挑豌,空白符占據一定寬度安券,所以inline-block的元素之間就出現了空隙。這些元素之間的間距會隨著字體的大小而變化浮毯,當行內元素font-size:16px時完疫,間距為8px泰鸡。
解決方法:移除空格债蓝、使用margin負值渐尿、使用font-size:0挺智、letter-spacing、word-spacing
li與li之間有看不見的空白間隔是什么原因引起的醉锅?有什么解決辦法余舶?
行框的排列會受到中間空白(回車\空格)等的影響啊鸭,因為空格也屬于字符,這些空白也會被應用樣式,占據空間匿值,所以會有間隔赠制,把字符大小設為0,就沒有空格了
用css分別實現某個DIV元素上下居中和左右居中挟憔。
方法一:
#one {
width: 100px;
height: 100px;
border: 4px solid red;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
方法二:
#one {
width: 100px;
height: 100px;
border: 4px solid red;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
}
方法三:
#one {
width: 100px;
height: 100px;
border: 4px solid red;
position: absolute;
left: 50%;
right: 50%;
margin-left: -50px;
margin-top: -50px;
}
用純CSS創(chuàng)建一個三角形的原理是什么钟些?
// 把上、左绊谭、右三條邊隱藏掉(顏色設為 transparent) 默認值政恍。邊框顏色為透明
#demo {
width: 0;
height: 0;
border-width: 20px;
border-style: solid;
border-color: transparent transparent red transparent;
}
重繪(redraw)和重排(reflow)
重繪:是一個元素的外觀變化所引發(fā)的瀏覽器行為;例如改變visibility达传、outline篙耗、背景色等屬性。
重排:是引起DOM樹重新計算的行為宪赶;又叫回流
很顯然宗弯,每次重排,必然會導致重繪搂妻,那么蒙保,重排會在哪些情況下發(fā)生?
- 添加或者刪除可見的DOM元素
- 元素位置改變
- 元素尺寸改變
- 元素內容改變(例如:一個文本被另一個不同尺寸的圖片替代)
- 頁面渲染初始化(這個無法避免)
- 瀏覽器窗口尺寸改變
這些都是顯而易見的叽讳,或許你已經有過這樣的體會追他,不間斷地改變?yōu)g覽器窗口大小坟募,導致UI反應遲鈍(某些低版本IE下甚至直接掛掉),現在你可能恍然大悟邑狸,沒錯懈糯,正是一次次的重排重繪導致的!
升華版:
dom樹的結構變化 (添加单雾、刪除dom)
獲取某些屬性 offsetTop赚哗、offsetLeft、 offsetWidth硅堆、offsetHeight屿储、scrollTop、scrollLeft渐逃、scrollWidth够掠、scrollHeight、clientTop茄菊、clientLeft疯潭、clientWidth、clientHeight面殖。也會引起回流竖哩。因為瀏覽器需要通過回流計算最新值
重排和重繪是DOM編程中耗能的主要原因之一,平時涉及DOM編程時可以參考以下幾點:
- 盡量不要在布局信息改變時做查詢(會導致渲染隊列強制刷新)
- 同一個DOM的多個屬性改變可以寫在一起(減少DOM訪問脊僚,同時把強制渲染隊列刷新的風險降為0)
- 如果要批量添加DOM相叁,可以先讓元素脫離文檔流,操作完后再帶入文檔流辽幌,這樣只會觸發(fā)一次重排(fragment元素的應用)
- 將需要多次重排的元素增淹,position屬性設為absolute或fixed,這樣此元素就脫離了文檔流舶衬,它的變化不會影響到其他元素埠通。例如有動畫效果的元素就最好設置為絕對定位。
參考:http://web.jobbole.com/83164/
https://blog.csdn.net/sinat_37328421/article/details/54575638
vh vw vmin vmax rem em
rem與em都是相對單位逛犹,我們使用它們的目的就是為了適應各種手機屏幕端辱。
rem是根據html根節(jié)點來計算的,而em是繼承父元素的字體虽画。
響應式網頁設計技術很大程度上依賴于比例規(guī)則舞蔽。然而,CSS比例不總是每個問題的最佳解決方案码撰。CSS寬度是相對于最近的包含父元素渗柿。如果你想使用顯示窗口的寬度或高度而不是父元素的寬度將會怎么樣?這正是vh和vw單位所提供的。
vh等于viewport高度的1/100.例如朵栖,如果瀏覽器的高是900px,1vh求得的值為9px颊亮。同理,如果顯示窗口寬度為750px,1vw求得的值為7.5px陨溅。
vw:viewpoint width终惑,視窗寬度,1vw等于視窗寬度的1%门扇。
vh:viewpoint height雹有,視窗高度,1vh等于視窗高度的1%臼寄。
vmin:vw和vh中較小的那個霸奕。
vmax:vw和vh中較大的那個。
實現一個div吉拳,左邊固定div寬度200px质帅,右邊div自適應
三種方法實現
html:
<div class="container">
<div class="left">
left固定寬度200px
</div>
<div class="right">
可變寬度rightrightrightrightrightrightrightrightri
</div>
</div>
方式一:利用bfc
.left{
width:200px;
float:left;
background:red;
}
.right{
overflow:hidden;
background:blue;
}
右邊盒子觸發(fā)bfc,使其不與浮動盒子區(qū)域重疊合武,因此會重新計算寬度临梗。
方式二:左浮動+margin-left
.left{
width:200px;
float:left;
border: 2px solid blue;
background:red;
}
.right{ 可以設置一個高度涡扼,div中有沒有內容都能實現相應功能
border: 2px solid yellow;
margin-left:200px;
background:blue;
}
方式三:flex布局
.container{
display:flex;/*設為伸縮容器*/
}
.left{
width:200px;
border: 2px solid blue;
background:red;
}
.right{
border: 2px solid yellow;
flex:1;/*這里設置為占比1稼跳,填充滿剩余空間,如果左右div都有這個屬性吃沪,則兩者寬度平分*/
background:blue;
}
盒子模型
其實盒子模型有兩種汤善,分別是 ie 盒子模型和標準 w3c 盒子模型。他們對盒子模型的解釋各不相同票彪,先來看看我們熟知的標準盒子模型:
標準 W3C 盒子模型的范圍包括 margin红淡、border、padding降铸、content在旱,并且 content 部分不包含其他部分。
IE 盒子模型的范圍也包括 margin推掸、border桶蝎、padding、content谅畅,和標準 W3C 盒子模型不同的是:IE 盒子模型的 content 部分包含了 border 和 pading登渣。
例如一個盒子模型如下:margin:20px,border:10px,padding:10px;width:200px;height:50px;
如果用w3c盒子模型解釋,那么這個盒子需要占據的位置為
寬度為:202+102+102+200=280px;
高度:202+102+202+50=130px;
盒子的實際寬度大小為:102+102+200=240px;
實際高度:102+102+50=90px;
用ie的盒子模型解釋 :盒子在網頁中占據的大小為202+200=240px; 高:202+50=90px;
盒子的實際大小為:寬度:200px, 高度:50px;
我們常常理解的盒子模型是w3c這樣的盒子模型
加分項回答
1.對于行級元素毡泻,margin-top和margin-bottom對于上下元素無效胜茧,margin-left和margin-right有效
2.對于相鄰的塊級元素margin-bottom和margin-top 取值方式
1) 都是正數: 取最大值
距離=Math.max(margin-botton,margin-top)
2) 都是負數: 取最小值
距離=Math.min(margin-botton,margin-top)
3)上面是正數,下面是負數或者 上面是負數仇味,下面是正數: 正負相加
距離=margin-botton+margin-top
參考:http://www.reibang.com/p/e2eb0d8c9de6
我個人認為W3C定義盒子模型與IE定義的盒子模型呻顽,IE定義的比較合理雹顺,元素的寬度應該包含border(邊框)和padding(填充),這個和我們現實生活的盒子是一樣的廊遍,W3C也認識到自己的問題了无拗,所以在CSS3中新增了一個樣式box-sizing,包含兩個屬性content-box 和 border-box昧碉。
box-sizing常用屬性有哪些英染,分別是什么
content-box
這是由 CSS2.1 規(guī)定的寬度高度行為。寬度和高度分別應用到元素的內容框被饿。在寬度和高度之外繪制元素的內邊距和邊框四康。
border-box
為元素設定的寬度和高度決定了元素的邊框盒。就是說狭握,為元素指定的任何內邊距和邊框都將在已設定的寬度和高度內進行繪制闪金。通過從已設定的寬度和高度分別減去邊框和內邊距才能得到內容的寬度和高度。
inherit
規(guī)定應從父元素繼承 box-sizing 屬性的值论颅。
左固定哎垦,右自適應的布局
方法一:左邊設置左浮動,右邊寬度設置100%
.left{
float: left;
}
.right{
width: 100%;
}
【分析】這樣的方式簡單得讓我懷疑恃疯,但是效果上確實是實現了漏设。
方法二: 父容器設置 display:flex;Right部分設置 flex:1
body{
display: flex;
}
.right{
flex: 1;
}
【分析】display:flex; 設置為彈性盒子今妄,其子元素可以通過設置 flex 的數值來控制所占空間的比例郑口。
方法三:設置浮動 + 在 css 中使用 calc() 函數
.left{
float: left;
}
.right{
float: left;
width: calc( 100vw - 200px);
}
【分析】
1. 浮動。(注意:為了不影響其他元素盾鳞,別忘了在父級上清除浮動)
calc() = calc(四則運算) 用于在 css 中動態(tài)計算長度值犬性,需要注意的是,運算符前后都需要保留一個空格腾仅,例如:width: calc(100% - 10px)乒裆;
vw: viewport width。1vw = viewport 寬度的 1%, 100vw = viewport width,
同樣的還有 vh: viewport height推励。1vw = viewport 高度的 1%鹤耍, 100vh = viewport height。
瀏覽器支持情況: 主流瀏覽器吹艇、IE10+
vw 和 vh 會隨著viewport 的變化而變化惰蜜,因此十分適合于自適應場景來使用。
css3實現三欄布局受神,左右固定抛猖,中間自適應(圣杯布局/雙飛翼布局)
<style>
* {
margin: 0;
padding: 0;
}
.middle,
.left,
.right {
position: relative;
float: left;
min-height: 130px;
}
.container {
padding: 0 220px 0 200px;
overflow: hidden;
}
.left {
margin-left: -100%;
left: -200px;
width: 200px;
background: red;
}
.right {
margin-left: -220px;
right: -220px;
width: 220px;
background: green;
}
.middle {
width: 100%;
background: blue;
word-break: break-all;
}
</style>
</head>
<body>
<div class='container'>
<div class='middle'></div>
<div class='left'></div>
<div class='right'></div>
</div>
</body>
CSS居中
transform:translate(-50%,-50%)實現水平垂直居中
.content {
padding:10px;
background:green;
color:#fff;
position:absolute;
top:50%;
left:50%;
border-radius: 5px;
-webkit-transform: translate(-50%,-50%);
-moz-transform: translate(-50%,-50%);
transform:translate(-50%,-50%);
}
當使用:top: 50%;left: 50%;, 是以左上角為原點,故不處于中心位置财著,
translate(-50%,-50%) 作用是联四,往上(x軸),左(y軸)移動自身長寬的 50%,以使其居于中心位置撑教。與負margin-left和margin-top實現居中不同的是朝墩,
margin-left必須知道自身的寬高(負自身已知寬高的一半),而translate可以在不知道寬高的情況下進行居中伟姐,tranlate()函數中的百分比是相對于自身寬高的百分比收苏,所以能進行居中。
JS中常見的異步任務
定時器愤兵、ajax鹿霸、事件綁定、回調函數秆乳、async await懦鼠、promise
defer和async的區(qū)別
大概說下實現無縫輪播的思路?
說出以下代碼的執(zhí)行結果
var a = 10;
var obj = {
a: 20,
say: function () {
console.log(this.a);
}
};
obj.say();
這個是被我簡化后的版本屹堰,具體題目記不太清了肛冶,反正就是考的this的指向問題,上題中答案為20扯键。然后面試官繼續(xù)追問睦袖,如何才能打印出10,給出如下方式:
// 方式1
var a = 10;
var obj = {
a: 20,
say: () => { // 此處改為箭頭函數
console.log(this.a);
}
};
obj.say(); // -> 10
// 方式2
var a = 10;
var obj = {
a: 20,
say: function () {
console.log(this.a);
}
};
obj.say.call(this); // 此處顯示綁定this為全局window對象
// 方式3
var a = 10;
var obj = {
a: 20,
say: function () {
console.log(this.a);
}
};
var say = obj.say; // 此處先創(chuàng)建一個臨時變量存放函數定義忧陪,然后單獨調用
say();
書寫bind
Function.prototype.bind = function(context, ...args1) {
if (typeof this !== 'function') {
throw new Error('not a function');
}
let fn = this;
let resFn = function(...args2) {
return fn.apply(this instanceof resFn ? this : context, args1.concat(args2));
};
const DumpFunction = function DumpFunction() {};
DumpFunction.prototype = this.prototype;
resFn.prototype = new DumpFunction();
return resFn;
}
防抖函數扣泊、函數節(jié)流
防抖節(jié)流
防抖(Debounce): 在指定時間A內,連續(xù)調用的時間間隔小于A嘶摊,前面的調用都會被取消,最后一次調用被執(zhí)行评矩。
移動端 上拉刷新
模糊查詢搜索框的 ajax請求
節(jié)流(throttle): 在指定時間A內叶堆,該函數只會被調用一次。等待時間A過了函數可以被再次調用且執(zhí)行最后一次調用斥杜。
ajax請求的時候虱颗,規(guī)定時間內設置請求次數,可以減少ajax請求蔗喂。
resize或者鼠標移動事件忘渔,防止瀏覽器頻繁響應事件,嚴重拉低性能缰儿。
防抖(Debounce)
利用延時器就可以實現
實現圖片懶加載的幾種方案比較
https://juejin.im/post/5dbf7b6a6fb9a0207326b32b
(算法題) 如何從10000個數中找到最大的10個數
以下打印結果
if([]==false){console.log(1)};
if({}==false){console.log(2)};
if([]){console.log(3)}
if([1]==[1]){console.log(4)}
1和2左右被轉成數字 3被轉成boolean 4 地址不一樣
vue源碼
從一個無序畦粮,不相等的數組中,選取N個數,使其和為M實現算法
以下打印結果
async function async1(){
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1();
new promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise2')
})
console.log('script end')
這個也很簡單 promise 優(yōu)先于 setTimeout 微任務和宏任務
script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout
// await等async 后面的加入異步不知道233333
// 還有最新V8和舊版本V8展示結果不一樣promise2 和async1 end略有互換
async function asyncFunc() {
const result = await otherAsyncFunc();
console.log(result);
}
// 等價于:
function asyncFunc() {
return otherAsyncFunc().then(result => {
console.log(result);
});}
箭頭函數this是聲明確定還是執(zhí)行確定
安全
問項目也就算了宣赔,問的還都是項目安全問題预麸,大概她做的是安全方面的
問加密算法 問https是怎么回事,真的安全嗎儒将?問dns解析怎么回事吏祸,dns劫持知道嗎?
localhost如何不被篡改钩蚊,對贡翘,全部是圍繞安全來的
css3特性中的transform:translateZ(0)有什么作用
GPU加速,優(yōu)化前端性能
列舉三種禁止瀏覽器緩存的頭字段砰逻,并寫出響應的設置值
https://juejin.im/post/5be2fcd7f265da616d53aad0
手動實現Promise床估,寫出偽代碼
數據結構:
https://juejin.im/post/5dc25951e51d4561f81ad1d9
請說出以下打印結果
let a = {a: 10};
let b = {b: 10};
let obj = {
a: 10
};
obj[b] = 20;
console.log(obj[a]);
這道題目主要考對JS數據類型的熟練度以及對ES6 中屬性名表達式的理解。在上題中 obj[b] = 20的賦值操作后诱渤,obj 其實已經變成了 {a: 10, [object Object]: 20}丐巫,這是因為如果屬性名表達式是一個對象的話,那么默認情況下會自動將對象轉為字符串[object Object]勺美,最后一步獲取obj[a]時递胧,a本身也是一個對象,所以會被轉換為獲取obj['[object Object]']也就是上一步賦值的20赡茸。
對象數組如何去重缎脾?
面試官跟我說是根據每個對象的某一個具體屬性來進行去重,因為考慮到服務端返回的數據中可能存在id重復的情況占卧,需要前端進行過濾遗菠,如下:
const responseList = [
{ id: 1, a: 1 },
{ id: 2, a: 2 },
{ id: 3, a: 3 },
{ id: 1, a: 4 },
];
const result = responseList.reduce((acc, cur) => {
const ids = acc.map(item => item.id);
return ids.includes(cur.id) ? acc : [...acc, cur];
}, []);
console.log(result); // -> [ { id: 1, a: 1}, {id: 2, a: 2}, {id: 3, a: 3} ]
實現函數柯里化
代碼如下:
const curry = (fn, ...args1) => (...args2) => (
arg => arg.length === fn.length ? fn(...arg) : curry(fn, ...arg)
)([...args1, ...args2]);
// 調用
const foo = (a, b, c) => a * b * c;
curry(foo)(2, 3, 4); // -> 24
curry(foo, 2)(3, 4); // -> 24
curry(foo, 2, 3)(4); // -> 24
curry(foo, 2, 3, 4)(); // -> 24