Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
有朋友準備看看新工作,正好有空,幫忙整理了一下常見的前端面試題,整理的面試題都比較基礎,主要面向初中級前端。篇幅有限,有些知識就直接貼文章鏈接了,大家可以自己去看~
BFC(Block Formatting Context)格式化上下文,是 Web 頁面中盒模型布局的 CSS 渲染模式,指一個獨立的渲染區域或者說是一個隔離的獨立容器。
形成 BFC 的條件
BFC 的特性
CSS3中的盒模型有以下兩種:標準盒子模型、IE盒子模型
盒模型都是由四個部分組成的,分別是margin、border、padding和content。
在標準盒模型性中
盒子在網頁中實際占用:
寬=width + padding2 + border2 + margin2
高=height + padding2 + border2 + margin2
盒模型實際大小:
寬=width + padding2 + border2
高=height + padding2 + border2
在IE盒模型性中
盒子在網頁中實際占用:
寬=width + margin2
高=height + margin2
盒模型實際大小:
寬=width
高=height
可以通過修改元素的box-sizing屬性來改變元素的盒模型:
當需要垂直居中的元素高度未知時,一般采用一下幾種方案實現垂直居中:
使用絕對定位和transform
css復制代碼.parent {
position: relative;
width: 100%;
height: 400px;
}
.children {
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
flex實現垂直居中(最常用的)
css復制代碼.parent {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 400px;
background: #fff;
}
.children {
background: red;
}
通過table屬性
css復制代碼<div class="parent">
<div class="children">
<div>test</div>
</div>
</div>
.parent {
display: table;
text-align:center;
}
.children {
background: #ccc;
display: table-cell;
vertical-align: middle;
}
.child div {
width: 300px;
height: 150px;
background: red;
margin: 0 auto;
}
預處理器:例如LESS、Sass、Stylus,用來預編譯Sass或less,增強了css代碼的復用性,還有層級、mixin、變量、循環、函數等,具有很方便的UI組件模塊化開發能力,極大的提高工作效率。
后處理器:例如PostCSS,通常被視為在完成的樣式表中根據CSS規范處理CSS,讓其更有效;目前最常做的是給CSS屬性添加瀏覽器私有前綴,實現跨瀏覽器兼容性的問題。
CSS 預處理器為 CSS 增加一些編程的特性,無需考慮瀏覽器的兼容性問題”,例如你可以在 CSS 中使用變量、簡單的邏輯程序、函數(如右側代碼編輯器中就使用了變量$color)等等在編程語言中的一些基本特性,可以讓你的 CSS 更加簡潔、適應性更強、可讀性更佳,更易于代碼的維護等諸多好處。
問題描述: 兩個塊級元素的上外邊距和下外邊距可能會合并(折疊)為一個外邊距,其大小會取其中外邊距值大的那個,這種行為就是外邊距折疊。需要注意的是,浮動的元素和絕對定位這種脫離文檔流的元素的外邊距不會折疊。重疊只會出現在垂直方向。
計算原則: 折疊合并后外邊距的計算原則如下:
解決辦法: 對于折疊的情況,主要有兩種:兄弟之間重疊和父子之間重疊
(1)兄弟之間重疊
(2)父子之間重疊
flex知識點的話,建議大家去看阮一峰老師的文章,看完應該就明白了
Flex 布局教程:語法篇
Flex 布局教程:實例篇
@media媒體查詢是針對不同的媒體類型定義不同的樣式,特別是響應式頁面,可以針對不同屏幕的大小,編寫多套樣式,從而達到自適應效果,代碼如下:
css復制代碼@media screen and (max-width: 720px) {
body {
background-color: #6633FF;
}
}
@media screen and (max-width: 640px) {
body {
background-color: #00FF66;
}
}
/*
上述的代碼分別對分辨率在0~640px以及640px~720px的屏幕設置了不同的背景顏色。
*/
rem 是一個靈活的可擴展的單位,由瀏覽器轉化像素并顯示。與em單位不同,rem單位無論嵌套層級如何,都只相對于瀏覽器的根元素(HTML元素)的font-size
由于viewport單位得到眾多瀏覽器的兼容,lib-flexible這個過渡方案已經可以放棄使用,不管是現在的版本還是以前的版本,都存有一定的問題。建議大家開始使用viewport, 代碼如下:
js復制代碼(function flexible (window, document) {
var docEl=document.documentElement
var dpr=window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize () {
if (document.body) {
document.body.style.fontSize=(12 * dpr) + 'px'
} else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem=viewWidth / 10
function setRemUnit () {
var rem=docEl.clientWidth / 10
docEl.style.fontSize=rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >=2) {
var fakeBody=document.createElement('body')
var testElement=document.createElement('div')
testElement.style.border='.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight===1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
什么是vw/vh ?
vw/vh是一個相對單位(類似于em,rem)
相對視口的尺寸計算結果
1px的問題經常出現在移動端邊框設置上,會導致設置1px邊框看起來較粗,影響用戶體驗,對于boder的1px問題,可以通過偽元素 + transform來解決, 代碼如下:
css復制代碼/* 手機端實現真正的一像素邊框 */
.border-1px,
.border-bottom-1px,
.border-top-1px,
.border-left-1px,
.border-right-1px {
position: relative;
}
/* 線條顏色 */
.border-1px::after,
.border-bottom-1px::after,
.border-top-1px::after,
.border-left-1px::after,
.border-right-1px::after {
background-color: #000;
}
/* 底邊邊框一像素 */
.border-bottom-1px::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
transform-origin: 0 0;
}
/* 上邊邊框一像素 */
.border-top-1px::after {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1px;
transform-origin: 0 0;
}
/* 左邊邊框一像素 */
.border-left-1px::after {
content: "";
position: absolute;
left: 0;
top: 0;
width: 1px;
height: 100%;
transform-origin: 0 0;
}
/* 右邊邊框1像素 */
.border-right-1px::after {
content: "";
position: absolute;
right: 0;
top: 0;
width: 1px;
height: 100%;
transform-origin: 0 0;
box-sizing: border-box;
}
/* 邊框一像素 */
.border-1px::after {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 1px solid gray;
box-sizing: border-box;
}
/* 設備像素比 */
/* 顯示屏最小dpr為2 */
@media (-webkit-min-device-pixel-ratio: 2) {
.border-bottom-1px::after, .border-top-1px::after {
transform: scaleY(0.5);
}
.border-left-1px::after, .border-right-1px::after {
transform: scaleX(0.5);
}
.border-1px::after {
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: 0 0;
}
}
/* 設備像素比 */
@media (-webkit-min-device-pixel-ratio: 3) {
.border-bottom-1px::after, .border-top-1px::after {
transform: scaleY(0.333);
}
.border-left-1px::after, .border-right-1px::after {
transform: scaleX(0.333);
}
.border-1px::after {
width: 300%;
height: 300%;
transform: scale(0.333);
transform-origin: 0 0;
}
}
iOS 11
css復制代碼padding-top: constant(safe-area-inset-top);
padding-right: constant(safe-area-inset-right);
padding-bottom: constant(safe-area-inset-bottom);
padding-left: constant(safe-area-inset-left);
iOS 11.2+
css復制代碼padding-top: env(safe-area-inset-top);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
如果圖片設置的是背景圖
css復制代碼background-size: cover;
如果是img標簽圖片
css復制代碼object-fit: cover;
可參考:常見的CSS布局
JavaScript一共有8種數據類型
七種基本數據類型:Undefined、Null、Boolean、Number、String、Symbol(es6新增)和BigInt(es10新增)
一種復雜數據類型:Object 里面包含 Function、Array、Date等
typeof
js復制代碼/*
優點:能夠快速區分基本數據類型
缺點:不能將Object、Array和Null區分,都返回object
*/
console.log(typeof 1); // number
console.log(typeof NaN); // number
console.log(typeof true); // boolean
console.log(typeof 'mc'); // string
console.log(typeof Symbol) // function
console.log(typeof function(){}); // function
console.log(typeof console.log()); // function
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object
console.log(typeof undefined); // undefined
instanceof
js復制代碼/*
優點:能夠區分Array、Object和Function,適合用于判斷自定義的類實例對象
缺點:Number,Boolean,String基本數據類型不能判斷
*/
console.log(1 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log(function(){} instanceof Object); // true
console.log({} instanceof Function); // false
console.log({} instanceof Object); // true
js復制代碼/*
優點:精準判斷數據類型
缺點:寫法繁瑣不容易記,推薦進行封裝后使用
*/
const toString=Object.prototype.toString;
console.log(toString.call(1)); // [object Number]
console.log(toString.call(true)); // [object Boolean]
console.log(toString.call('mc')); // [object String]
console.log(toString.call([])); // [object Array]
console.log(toString.call({})); // [object Object]
console.log(toString.call(function(){})); // [object Function]
console.log(toString.call(undefined)); // [object Undefined]
console.log(toString.call(null)); // [object Null]
js復制代碼function instanceOf(left, right) {
let proto=left.__proto__
let prototype=right.prototype
while (true) {
if (proto===null) return false
if (proto===prototype) return true
proto=proto.__proto__
}
}
除了es6的new Set()去重外,可以通過以下幾種方法實現數組去重
js復制代碼// 利用filter去實現
Array.prototype.unique1=function() {
return this.filter((item, index, array)=> {
return this.indexOf(item)===index;
});
}
js復制代碼Array.prototype.unique2=function() {
const n={}, r=[]; // n為hash表,r為臨時數組
for (let i=0; i < this.length; i++) {
if (!n[this[i]]) { // 如果hash表中沒有當前項
n[this[i]]=true; //存入hash表
r.push(this[i]); //把當前數組的當前項push到臨時數組里面
}
}
return r;
}
js復制代碼// 返回后的數組順序會亂
Array.prototype.unique3=function() {
this.sort();
const r=[this[0]];
for (let i=1; i < this.length; i++) {
if (this[i] !==this[i - 1]) {
r.push(this[i]);
}
}
return r;
}
執行上下文(以下簡稱“上下文”)的概念在 JavaScript 中是頗為重要的。變量或函數的上下文決定了它們可以訪問哪些數據,以及它們的行為。每個上下文都有一個關聯的變量對象(variable object),而這個上下文中定義的所有變量和函數都存在于這個對象上。雖然無法通過代碼訪問變量對象,但后臺處理數據會用到它。
全局上下文是最外層的上下文。根據 ECMAScript 實現的宿主環境,表示全局上下文的對象可能不一 樣。在瀏覽器中,全局上下文就是我們常說的window對象,因此所有通過 var 定義的全局變量和函數都會成為 window 對象的屬性和方法。使用 let 和 const 的頂級聲明不會定義在全局上下文中,但在作用域鏈解析上效果是一樣的。上下文在其所有代碼都執行完畢后會被銷毀,包括定義在它上面的所有變量和函數(全局上下文在應用程序退出前才會被銷毀,比如關閉網頁或退出瀏覽器)。
每個函數調用都有自己的上下文。當代碼執行流進入函數時,函數的上下文被推到一個上下文棧上。 在函數執行完之后,上下文棧會彈出該函數上下文,將控制權返還給之前的執行上下文。ECMAScript 程序的執行流就是通過這個上下文棧進行控制的。
上下文中的代碼在執行的時候,會創建變量對象的一個作用域鏈(scope chain)。這個作用域鏈決定了各級上下文中的代碼在訪問變量和函數時的順序。代碼正在執行的上下文的變量對象始終位于作用域鏈的最前端。如果上下文是函數,則其活動對象(activation object)用作變量對象。活動對象最初只有一個定義變量:arguments。(全局上下文中沒有這個變量。)作用域鏈中的下一個變量對象來自包含上下文,再下一個對象來自再下一個包含上下文。以此類推直至全局上下文;全局上下文的變量對象始終是作用域鏈的最后一個變量對象。
代碼執行時的標識符解析是通過沿作用域鏈逐級搜索標識符名稱完成的。搜索過程始終從作用域鏈 的最前端開始,然后逐級往后,直到找到標識符。(如果沒有找到標識符,那么通常會報錯。) 看一看下面這個例子:
js復制代碼var color="blue";
function changeColor() {
if (color==="blue") {
color="red";
} else {
color="blue";
}
}
changeColor();
對這個例子而言,函數 changeColor()的作用域鏈包含兩個對象:一個是它自己的變量對象(就 是定義 arguments 對象的那個),另一個是全局上下文的變量對象。這個函數內部之所以能夠訪問變量color,就是因為可以在作用域鏈中找到它。
此外,局部作用域中定義的變量可用于在局部上下文中替換全局變量??匆豢聪旅孢@個例子:
js復制代碼var color="blue";
function changeColor() {
let anotherColor="red";
function swapColors() {
let tempColor=anotherColor;
anotherColor=color;
color=tempColor;
// 這里可以訪問 color、anotherColor 和 tempColor
}
// 這里可以訪問 color 和 anotherColor,但訪問不到 tempColor
swapColors();
}
// 這里只能訪問 color
changeColor();
以上代碼涉及 3 個上下文:全局上下文、changeColor()的局部上下文和 swapColors()的局部 上下文。全局上下文中有一個變量 color 和一個函數 changeColor()。changeColor()的局部上下文中有一個變量 anotherColor 和一個函數 swapColors(),但在這里可以訪問全局上下文中的變量 color。swapColors()的局部上下文中有一個變量 tempColor,只能在這個上下文中訪問到。全局上下文和changeColor()的局部上下文都無法訪問到 tempColor。而在 swapColors()中則可以訪問另外兩個 上下文中的變量,因為它們都是父上下文。下圖展示了這個例子的作用域鏈。
上圖中的矩形表示不同的上下文。內部上下文可以通過作用域鏈訪問外部上下文中的一切,但外 部上下文無法訪問內部上下文中的任何東西。上下文之間的連接是線性的、有序的。每個上下文都可以到上一級上下文中去搜索變量和函數,但任何上下文都不能到下一級上下文中去搜索。swapColors()局部上下文的作用域鏈中有 3 個對象:swapColors()的變量對象、changeColor()的變量對象和全局變量對象。swapColors()的局部上下文首先從自己的變量對象開始搜索變量和函數,搜不到就去搜索上一級變量對象。changeColor()上下文的作用域鏈中只有 2 個對象:它自己的變量對象和全局變量對象。因此,它不能訪問 swapColors()的上下文。
閉包是指有權訪問另外一個函數作用域中的變量的函數,有興趣的可以看看幾篇文章,看完會又更深刻的理解
破解前端面試(80% 應聘者不及格系列):從閉包說起
call/apply/bind都是用來修改this指向的
apply 和 call 的區別
apply 和 call 的區別是 call 方法接受的是若干個參數列表,而 apply 接收的是一個包含多個參數的數組(方便記憶:call有兩個l,表示可以傳遞多個參數)
bind 和 apply、call 區別
call、apply都是直接調用,bind生成的this指向改變函數需要手動調用
JavaScript深入之從原型到原型鏈
比較常見的幾種:
js復制代碼function Parent(name) {
this.name=name;
}
Parent.prototype.sayName=function() {
console.log('parent name:', this.name);
}
function Child(name, parentName) {
Parent.call(this, parentName);
this.name=name;
}
function create(proto) {
function F(){}
F.prototype=proto;
return new F();
}
Child.prototype=create(Parent.prototype);
Child.prototype.sayName=function() {
console.log('child name:', this.name);
}
Child.prototype.constructor=Child;
var parent=new Parent('father');
parent.sayName(); // parent name: father
var child=new Child('son', 'father');
其他幾種繼承方式,可參考:JavaScript常用八種繼承方案
深拷貝: JSON.parse(JSON.stringify(data)) 遞歸
淺拷貝: Object.assign() 擴展運算符(...) Array.prototype.concat() Array.prototype.slice()
說說事件循環機制(滿分答案來了)
防抖: 防抖就是將一段時間內連續的多次觸發轉化為一次觸發。一般可以使用在用戶輸入停止一段時間過后再去獲取數據,而不是每次輸入都去獲取
防抖應用場景:
節流: 節流,顧名思義,控制流量。用于用戶在與頁面交互時控制事件發生的頻率,一般場景是單位的時間或其它間隔內定時執行操作。一段時間內,事件在每次到達我們規定的間隔 n 秒時觸發一次
節流應用場景:
在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數且返回結果的新函數的技術。
js復制代碼function curry(fn, args) {
var length=fn.length;
var args=args || [];
return function(){
newArgs=args.concat(Array.prototype.slice.call(arguments));
if (newArgs.length < length) {
return curry.call(this,fn,newArgs);
} else {
return fn.apply(this,newArgs);
}
}
}
function multiFn(a, b, c) {
return a * b * c;
}
var multi=curry(multiFn);
multi(2)(3)(4);
multi(2,3,4);
multi(2)(3,4);
multi(2,3)(4);
這里面包含了大部分的常見手寫代碼: JavaScript手寫代碼無敵秘籍
注: const實際上保證的,并不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對于簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同于常量。但對于復合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即總是指向另一個固定的地址),至于它指向的數據結構是不是可變的,就完全不能控制了。因此,將一個對象聲明為常量必須非常小心。
promise是異步編程的一種解決方案。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息
詳細的可以參考:要就來45道Promise面試題一次爽到底
類定義
與函數類型相似,定義類也有兩種主要方式:類聲明和類表達式。這兩種方式都使用 class 關鍵 字加大括號:
js復制代碼class Person {} // 類聲明
const Animal=class {}; // 類表達式
與函數表達式類似,類表達式在它們被求值前也不能引用。不過,與函數定義不同的是,雖然函數 聲明可以提升,但類定義不能:
js復制代碼console.log(FunctionExpression); // undefined
var FunctionExpression=function() {};
console.log(FunctionExpression); // function() {}
console.log(FunctionDeclaration); // FunctionDeclaration() {}
function FunctionDeclaration() {}
console.log(FunctionDeclaration); // FunctionDeclaration() {}
console.log(ClassExpression); // undefined
var ClassExpression=class {};
console.log(ClassExpression); // class {}
console.log(ClassDeclaration); // ReferenceError: ClassDeclaration is not defined
class ClassDeclaration {}
console.log(ClassDeclaration); // class ClassDeclaration {}
類構成
類可以包含構造函數方法、實例方法、獲取函數、設置函數和靜態類方法,但這些都不是必需的。 空的類定義照樣有效。默認情況下,類定義中的代碼都在嚴格模式下執行
構造函數 constructor
constructor()方法是類的默認方法,通過new命令生成對象實例時,自動調用該方法。一個類必須有constructor()方法,如果沒有顯式定義,一個空的constructor()方法會被默認添加。
類的實例化
class 的實例化必須通過 new 關鍵字
js復制代碼class Example {}
let exam1=Example();
// Class constructor Example cannot be invoked without 'new'
使用 new 調用類的構造函數會執行如下操作。
(1) 在內存中創建一個新對象。
(2) 這個新對象內部的[[Prototype]]指針被賦值為構造函數的 prototype 屬性。
(3) 構造函數內部的 this 被賦值為這個新對象(即 this 指向新對象)
(4) 執行構造函數內部的代碼(給新對象添加屬性)。
(5) 如果構造函數返回非空對象,則返回該對象;否則,返回剛創建的新對象。
類的所有實例共享一個原型對象
js復制代碼class Example {
constructor(a, b) {
this.a=a;
this.b=b;
console.log('Example');
}
sum() {
return this.a + this.b;
}
}
let exam1=new Example(2, 1);
let exam2=new Example(3, 1);
console.log(exam1._proto_==exam2._proto_); // true
exam1._proto_.sub=function () {
return this.a - this.b;
}
console.log(exam1.sub()); // 1
console.log(exam2.sub()); // 2
上面代碼中,exam1和exam2都是Example的實例,它們的原型都是Example.prototype,所以__proto__屬性是相等的
setter、getter
在“類”的內部可以使用get和set關鍵字,對某個屬性設置存值函數和取值函數,攔截該屬性的存取行為。
靜態方法 static
類(class)通過 static 關鍵字定義靜態方法。不能在類的實例上調用靜態方法,而應該通過類本身調用。這些通常是實用程序方法,例如創建或克隆對象的功能。
類相當于實例的原型,所有在類中定義的方法,都會被實例繼承。如果在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承,而是直接通過類來調用,這就稱為“靜態方法”。
js復制代碼class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo=new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
上面代碼中,Foo類的classMethod方法前有static關鍵字,表明該方法是一個靜態方法,可以直接在Foo類上調用(Foo.classMethod()),而不是在Foo類的實例上調用。如果在實例上調用靜態方法,會拋出一個錯誤,表示不存在該方法。
關鍵字 super
super關鍵字用于訪問和調用一個對象的父對象上的函數。
繼承 extends
ES6 類支持單繼承。使用 extends 關鍵字,就可以繼承任何擁有[[Construct]]和原型的對象。 很大程度上,這意味著不僅可以繼承一個類,也可以繼承普通的構造函數(保持向后兼容):
js復制代碼class Vehicle {}
// 繼承類
class Bus extends Vehicle {}
let b=new Bus();
console.log(b instanceof Bus); // true
console.log(b instanceof Vehicle); // true
function Person() {}
// 繼承普通構造函數
class Engineer extends Person {}
let e=new Engineer();
console.log(e instanceof Engineer); // true
console.log(e instanceof Person); // true
大概步驟如下,具體要針對具體業務封裝:
js復制代碼// 創建 XMLHttpRequest 對象
var ajax=new XMLHttpRequest();
// 規定請求的類型、URL 以及是否異步處理請求。
ajax.open('GET', url);
// 發送信息至服務器時內容編碼類型
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 發送請求
ajax.send(null);
// 接受服務器響應數據
ajax.onreadystatechange=function () {
if (obj.readyState==4 && (obj.status==200 || obj.status==304)) {
}
};
狀態碼 | 含義 |
200 | 表示從客戶端發來的請求在服務器端被正常處理了 |
204 | 無內容。服務器成功處理,但未返回內容。在未更新網頁的情況下,可確保瀏覽器繼續顯示當前文檔 |
301 | 永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI。今后任何新的請求都應使用新的URI代替 |
302 | 臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI |
304 | 未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何資源。 |
400 | 表示請求報文中存在語法錯誤。當錯誤發生時,需修改請求的內容后再次發送請求 |
401 | 表示未授權(Unauthorized),當前請求需要用戶驗證 |
403 | 表示對請求資源的訪問被服務器拒絕了 |
404 | 表示服務器上無法找到請求的資源。除此之外,也可以在服務器端拒絕請求且不想說明理由時使用 |
500 | 表示服務器端在執行請求時發生了錯誤。也有可能是Web應用存在的bug或某些臨時的故障 |
502 | 作為網關或者代理工作的服務器嘗試執行請求時,從遠程服務器接收到了一個無效的響應 |
503 | 表示服務器暫時處于超負載或正在進行停機維護,現在無法處理請求 |
504 | 網關超時, 服務器作為網關或代理,但是沒有及時從上游服務器收到請求 |
Request header | 解釋 |
Accept | 指定客戶端能夠接收的內容類型,如:application/json, text/plain |
Accept-Encoding | 指定瀏覽器可以支持的web服務器返回內容壓縮編碼類型,如:gzip, deflate, br |
Accept-Language | 瀏覽器所希望的語言種類 |
Cache-Control | 緩存機制,默認no-cache |
Connec-Length | 請求頭的長度 |
Content-Type | 發送的數據類型, 如:application/x-www-form-urlencoded, |
Connection | 表示是否需要持久連接。(HTTP 1.1默認進行持久連接) |
Cookie | HTTP請求發送時,會把保存在該請求域名下的所有cookie值一起發送給web服務器 |
Host | 指定請求的服務器的域名和端口號 |
If-Modified-Since | 只有當所請求的內容在指定的日期之后又經過修改才返回它,否則返回304“Not Modified”應答 |
Referer | 包含一個URL,用戶從該URL代表的頁面出發訪問當前請求的頁面 |
User-Agent | 瀏覽器信息,如果Servlet返回的內容與瀏覽器類型有關則該值非常有用 |
Cookie | 這是最重要的請求頭信息之一 |
Response header | 解釋 |
Allow | 服務器支持哪些請求方法(如GET、POST等) |
Content-Encoding | 文檔的編碼(Encode)方法。 |
Content-Length | 表示內容長度。 |
Content-Type | 表示后面的文檔屬于什么MIME類型。 |
Date | 當前的GMT時間。你可以用setDateHeader來設置這個頭以避免轉換時間格式的麻煩 |
Expires | 應該在什么時候認為文檔已經過期,從而不再緩存它? |
Last-Modified | 文檔的最后改動時間??蛻艨梢酝ㄟ^If-Modified-Since請求頭提供一個日期, |
Location | 表示客戶應當到哪里去提取文檔。Location通常不是直接設置的,而是通過HttpServletResponse的sendRedirect方法,該方法同時設置狀態代碼為302 |
Refresh | 表示瀏覽器應該在多少時間之后刷新文檔,以秒計 |
Server | 服務器名字。Servlet一般不設置這個值,而是由Web服務器自己設置 |
Set-Cookie | 設置和頁面關聯的Cookie。Servlet不應使用response.setHeader("Set-Cookie", ...),而是應使用HttpServletResponse提供的專用方法addCookie |
WWW-Authenticate | 客戶應該在Authorization頭中提供什么類型的授權信息? |
跨域是指瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript實施的安全限制。瀏覽器從一個域名的網頁去請求另一個域名的資源時,出現域名、端口、協議任一不同,都屬于跨域。
跨域解決方案:
詳情見:九種跨域方式實現原理(完整版)
預請求就是復雜請求(可能對服務器數據產生副作用的HTTP請求方法,如put,delete都會對服務器數據進行更修改,所以要先詢問服務器)。
跨域請求中,瀏覽器自發的發起的預請求,瀏覽器會查詢到兩次請求,第一次的請求參數是options,以檢測試實際請求是否可以被瀏覽器接受
什么情況下發生
例如設置了post請求的content-type:application/json,就會發生預請求
詳細可以參考: 從輸入URL開始建立前端知識體系
三次握手
第一次握手:客戶端給服務端發一個 SYN 報文,并指明客戶端的初始化序列號 ISN(c)。此時客戶端處于 SYN_SEND 狀態。
第二次握手:服務器收到客戶端的 SYN 報文之后,會以自己的 SYN 報文作為應答,并且也是指定了自己的初始化序列號 ISN(s)。同時會把客戶端的 ISN + 1 作為ACK 的值,表示自己已經收到了客戶端的 SYN,此時服務器處于 SYN_RCVD 的狀態。
第三次握手:客戶端收到 SYN 報文之后,會發送一個 ACK 報文,當然,也是一樣把服務器的 ISN + 1 作為 ACK 的值,表示已經收到了服務端的 SYN 報文,此時客戶端處于 ESTABLISHED 狀態。服務器收到 ACK 報文之后,也處于 ESTABLISHED 狀態,此時,雙方已建立起了連接
四次揮手
第一次揮手:客戶端先發送FIN報文(第24幀),用來關閉主動方到被動關閉方的數據傳送,也就是客戶端告訴服務器:我已經不會再給你發數據了(當然,在fin包之前發送出去的數據,如果沒有收到對應的ack確認報文,客戶端依然會重發這些數據),但此時客戶端還可以接受數據。
第二次揮手:Server端接到FIN報文后,如果還有數據沒有發送完成,則不必急著關閉Socket,可以繼續發送數據。所以服務器端先發送ACK(第25幀),告訴Client端:請求已經收到了,但是我還沒準備好,請繼續等待停止的消息。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。
第三次揮手:當Server端確定數據已發送完成,則向Client端發送FIN報文(第26幀),告訴Client端:服務器這邊數據發完了,準備好關閉連接了。
第四次揮手:Client端收到FIN報文后,就知道可以關閉連接了,但是他還是不相信網絡,所以發送ACK后進入TIME_WAIT狀態(第27幀), Server端收到ACK后,就知道可以斷開連接了。Client端等待了2MSL后依然沒有收到回復,則證明Server端已正常關閉,最后,Client端也可以關閉連接了至此,TCP連接就已經完全關閉了!
為了方便記憶,整理個白話文版本,以找工作和離職舉例(客戶端=小明,服務端=人事)
第一次握手:由小明發起,小明向招聘人事發送了一份簡歷,里面包含了小明的個人基本信息
第二次握手:由人事發起,人事收到小明的簡歷后,安排面試,面試通過后,發送了一份offer給小明
第三次握手:由小明發起,小明收到offer后,會發送一個確認offer的回復,表示已經收到offer
第一次揮手:由小明發起,告訴服務器我要離職跑路了
第二次揮手:由人事發起,告訴小明我知道你要離職了,但是你先把工作交接好
第三次揮手:由人事發起,我看你的交接流程都走完了,你可以走人了
第四次揮手:由小明發起,收到人事通知離職流程已經走完了,告訴人事我明白就不來了,人事收到消息把此人從公司注銷
大概流程如下:
瀏覽器的本地存儲主要分為Cookie、WebStorage和IndexedDB, 其中WebStorage又可以分為localStorage和sessionStorage。接下來我們就來一一分析這些本地存儲方案。
Cookie
HTTP Cookie,通常叫做Cookie,一開始是在客戶端用于存儲會話信息的。
Cookie主要構成
Cookie的原理
第一次訪問網站時,瀏覽器發出請求,服務器響應請求后,會在響應頭中添加一個Set-Cookie,將cookie放入響應請求中。
在第二次發起請求時,瀏覽器通過Cookie請求頭部將cookie信息送給服務器,服務端根據cookie信息辨別用戶身份。
Cookie的過期時間、域、路徑、有效期、適用站點都可以根據需要來指定。
Cookie的生成
Cookie的生成方式主要有兩種:
服務端設置方式參考上面Cookie的原理,具體的實現方式自行查閱相關資料??蛻舳嗽O置Cookie方法如下:
js復制代碼document.cookie="name=zhangsan; age=20"
Cookie的缺點
Web Storage
Web Storage分為localStorage和sessionStorage
localStorage
localStorage有以下幾個特點:
使用方法:
js復制代碼// 設置
localStorage.setItem('name', '張三')
localStorage.age='25'
// 取值
localStorage.getItem('name')
let age=localStorage.age
// 移除
localStorage.removeItem('name')
// 移除所有
localStorage.clear()
sessionStorage
sessionStorage對象存儲特定于某個會話的數據,當這個會話的頁簽或瀏覽器關閉,sessionStorage也就消失了。
頁面刷新之后,存儲在sessionStorage中的數據仍然存在可用。
sessionStorage的特點:
使用方法:
js復制代碼// 設置
sessionStorage.setItem('name', '張三')
sessionStorage.age='25'
// 取值
sessionStorage.getItem('name')
let age=sessionStorage.age
// 移除
sessionStorage.removeItem('name')
// 移除所有
sessionStorage.clear()
sessionStorage和localStorage的區別:localStorage的數據可以長期保留,sessionStorage的數據在關閉頁面后即被清空
IndexedDB
IndexedDB,全稱Indexed Database API,是瀏覽器中保持結構化數據的一種數據庫。
IndexedDB的思想是創建一套API,方便保存和讀取JavaScript對象,同時支持查詢和搜索。
IndexedDB特點
IndexedDB的入門教程,可以查看阮一峰老師的文章:瀏覽器數據庫 IndexedDB 入門教程
總結
介紹
瀏覽器的 Javascript 具有自動垃圾回收機制(GC:Garbage Collecation),也就是說,執行環境會負責管理代碼執行過程中使用的內存。其原理是:垃圾收集器會定期(周期性)找出那些不在繼續使用的變量,然后釋放其內存。但是這個過程不是實時的,因為其開銷比較大并且GC時停止響應其他操作,所以垃圾回收器會按照固定的時間間隔周期性的執行。
不再使用的變量也就是生命周期結束的變量,當然只可能是局部變量,全局變量的生命周期直至瀏覽器卸載頁面才會結束。局部變量只在函數的執行過程中存在,而在這個過程中會為局部變量在?;蚨焉戏峙湎鄳目臻g,以存儲它們的值,然后在函數中使用這些變量,直至函數結束,而閉包中由于內部函數的原因,外部函數并不能算是結束。
還是上代碼說明吧:
js復制代碼function fn1() {
var obj={ name: 'hanzichi', age: 10 };
}
function fn2() {
var obj={ name:'hanzichi', age: 10 };
return obj;
}
var a=fn1();
var b=fn2();
我們來看代碼是如何執行的。首先定義了兩個function,分別叫做fn1和fn2,當fn1被調用時,進入fn1的環境,會開辟一塊內存存放對象{name: 'hanzichi', age: 10},而當調用結束后,出了fn1的環境,那么該塊內存會被js引擎中的垃圾回收器自動釋放;在fn2被調用的過程中,返回的對象被全局變量b所指向,所以該塊內存并不會被釋放。
這里問題就出現了:到底哪個變量是沒有用的?所以垃圾收集器必須跟蹤到底哪個變量沒用,對于不再有用的變量打上標記,以備將來收回其內存。用于標記的無用變量的策略可能因實現而有所區別,通常情況下有兩種實現方式:標記清除和引用計數。引用計數不太常用,標記清除較為常用。
標記清除
js中最常用的垃圾回收方式就是標記清除。當變量進入環境時,例如,在函數中聲明一個變量,就將這個變量標記為“進入環境”。從邏輯上講,永遠不能釋放進入環境的變量所占用的內存,因為只要執行流進入相應的環境,就可能會用到它們。而當變量離開環境時,則將其標記為“離開環境”。
垃圾回收器在運行的時候會給存儲在內存中的所有變量都加上標記(當然,可以使用任何標記方式)。然后,它會去掉環境中的變量以及被環境中的變量引用的變量的標記(閉包)。而在此之后再被加上標記的變量將被視為準備刪除的變量,原因是環境中的變量已經無法訪問到這些變量了。最后,垃圾回收器完成內存清除工作,銷毀那些帶標記的值并回收它們所占用的內存空間。 到目前為止,IE9+、Firefox、Opera、Chrome、Safari的js實現使用的都是標記清除的垃圾回收策略或類似的策略,只不過垃圾收集的時間間隔互不相同。
引用計數
引用計數的含義是跟蹤記錄每個值被引用的次數。當聲明了一個變量并將一個引用類型值賦給該變量時,則這個值的引用次數就是1。如果同一個值又被賦給另一個變量,則該值的引用次數加1。相反,如果包含對這個值引用的變量又取得了另外一個值,則這個值的引用次數減1。當這個值的引用次數變成0時,則說明沒有辦法再訪問這個值了,因而就可以將其占用的內存空間回收回來。這樣,當垃圾回收器下次再運行時,它就會釋放那些引用次數為0的值所占用的內存。
js復制代碼function test() {
var a={}; // a的引用次數為0
var b=a; // a的引用次數加1,為1
var c=a; // a的引用次數再加1,為2
var b={}; // a的引用次數減1,為1
}
Netscape Navigator3是最早使用引用計數策略的瀏覽器,但很快它就遇到一個嚴重的問題:循環引用。循環引用指的是對象A中包含一個指向對象B的指針,而對象B中也包含一個指向對象A的引用。
js復制代碼function fn() {
var a={};
var b={};
a.pro=b;
b.pro=a;
}
fn();
以上代碼a和b的引用次數都是2,fn()執行完畢后,兩個對象都已經離開環境,在標記清除方式下是沒有問題的,但是在引用計數策略下,因為a和b的引用次數不為0,所以不會被垃圾回收器回收內存,如果fn函數被大量調用,就會造成內存泄露。在IE7與IE8上,內存直線上升。
我們知道,IE中有一部分對象并不是原生js對象。例如,其內存泄露DOM和BOM中的對象就是使用C++以COM對象的形式實現的,而COM對象的垃圾回收機制采用的就是引用計數策略。因此,即使IE的js引擎采用標記清除策略來實現,但js訪問的COM對象依然是基于引用計數策略的。換句話說,只要在IE中涉及COM對象,就會存在循環引用的問題。
js復制代碼var element=document.getElementById("some_element");
var myObject=new Object();
myObject.e=element;
element.o=myObject;
這個例子在一個DOM元素(element)與一個原生js對象(myObject)之間創建了循環引用。其中,變量myObject有一個屬性e指向element對象;而變量element也有一個屬性o回指myObject。由于存在這個循環引用,即使例子中的DOM從頁面中移除,它也永遠不會被回收。
舉個栗子:
js復制代碼myObject.element=null;
element.o=null;
window.onload=function outerFunction() {
var obj=document.getElementById("element");
obj.onclick=function innerFunction(){};
obj=null;
};
這段代碼看起來沒什么問題,但是obj引用了document.getElementById('element'),而document.getElementById('element')的onclick方法會引用外部環境中的變量,自然也包括obj,是不是很隱蔽啊。(在比較新的瀏覽器中在移除Node的時候已經會移除其上的event了,但是在老的瀏覽器,特別是ie上會有這個bug)
解決辦法:
最簡單的方式就是自己手工解除循環引用,比如剛才的函數可以這樣
js復制代碼myObject.element=null;
element.o=null;
window.onload=function outerFunction(){
var obj=document.getElementById("element");
obj.onclick=function innerFunction(){};
obj=null;
};
將變量設置為null意味著切斷變量與它此前引用的值之間的連接。當垃圾回收器下次運行時,就會刪除這些值并回收它們占用的內存。
要注意的是,IE9+并不存在循環引用導致Dom內存泄露問題,可能是微軟做了優化,或者Dom的回收方式已經改變
在討論回流與重繪之前,我們要知道:
一句話:回流必將引起重繪,重繪不一定會引起回流
回流 (Reflow)
當Render Tree中部分或全部元素的尺寸、結構、或某些屬性發生改變時,瀏覽器重新渲染部分或全部文檔的過程稱為回流。
會導致回流的操作:
一些常用且會導致回流的屬性和方法:
重繪 (Repaint)
當頁面中元素樣式的改變并不影響它在文檔流中的位置時(例如:color、background-color、visibility等),瀏覽器會將新樣式賦予給元素并重新繪制它,這個過程稱為重繪。
性能影響
回流比重繪的代價要更高。
有時即使僅僅回流一個單一的元素,它的父元素以及任何跟隨它的元素也會產生回流。
現代瀏覽器會對頻繁的回流或重繪操作進行優化:
瀏覽器會維護一個隊列,把所有引起回流和重繪的操作放入隊列中,如果隊列中的任務數量或者時間間隔達到一個閾值的,瀏覽器就會將隊列清空,進行一次批處理,這樣可以把多次回流和重繪變成一次。
當你訪問以下屬性或方法時,瀏覽器會立刻清空隊列:
因為隊列中可能會有影響到這些屬性或方法返回值的操作,即使你希望獲取的信息與隊列中操作引發的改變無關,瀏覽器也會強行清空隊列,確保你拿到的值是最精確的。
如何避免
CSS
JavaScript
通俗易懂,了解什么是DNS及查詢過程
CDN是什么?使用CDN有什么優勢?
最全的 Vue 面試題+詳解答案
Vue.js 技術揭秘
高頻前端面試題匯總之React篇(上)
高頻前端面試題匯總之React篇(下)
搞懂這12個Hooks,保證讓你玩轉React
React 源碼剖析系列 - 生命周期的管理藝術
React Hooks 原理
深入理解 React 高階組件
前端性能優化手段從以下幾個方面入手:加載優化、執行優化、渲染優化、樣式優化、腳本優化
加載優化:減少HTTP請求、緩存資源、壓縮代碼、無阻塞、首屏加載、按需加載、預加載、壓縮圖像、減少Cookie、避免重定向、異步加載第三方資源
執行優化:CSS寫在頭部,JS寫在尾部并異步、避免img、iframe等的src為空、盡量避免重置圖像大小、圖像盡量避免使用DataURL
渲染優化:設置viewport、減少DOM節點、優化動畫、優化高頻事件、GPU加速
樣式優化:避免在HTML中書寫style、避免CSS表達式、移除CSS空規則、正確使用display:display、不濫用float等
腳本優化:減少重繪和回流、緩存DOM選擇與計算、緩存.length的值、盡量使用事件代理、盡量使用id選擇器、touch事件優化
加載優化
執行優化
渲染優化
樣式優化
腳本優化
Webpack面試題
當面試官問Webpack的時候他想知道什么
TypeScript免費視頻圖文教程(2W字)
算法這塊呢,應該是很多人頭疼的地方,沒有其他方法,只能去LeetCode老老實實刷題
JavaScript 數據結構與算法之美
就是攻擊者想盡一切辦法將可以執行的代碼注入到網頁中, 主要分為以下幾種
存儲型(server端)
場景:見于帶有用戶保存數據的網站功能,如論壇發帖、商品評論、用戶私信等
攻擊步驟:
反射型(Server端)
與存儲型的區別在于,存儲型的惡意代碼存儲在數據庫中,反射型的惡意代碼在URL上
場景:通過 URL 傳遞參數的功能,如網站搜索、跳轉等
攻擊步驟:
Dom 型(瀏覽器端)
DOM 型 XSS 攻擊中,取出和執行惡意代碼由瀏覽器端完成,屬于前端 JavaScript 自身的安全漏洞,而其他兩種 XSS 都屬于服務端的安全漏洞
場景:通過 URL 傳遞參數的功能,如網站搜索、跳轉等
攻擊步驟:
預防方案:
防止攻擊者提交惡意代碼,防止瀏覽器執行惡意代碼
攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站發送跨站請求。利用受害者在被攻擊網站已經獲取的注冊憑證,繞過后臺的用戶驗證,達到冒充用戶對被攻擊的網站執行某項操作的目的
攻擊流程舉例
攻擊類型
預防方案:
CSRF通常從第三方網站發起,被攻擊的網站無法防止攻擊發生,只能通過增強自己網站針對CSRF的防護能力來提升安全性。)
作者:前端老干部
鏈接:https://juejin.cn/post/7127217262133510158
、 介紹一下標準的CSS的盒子模型?與低版本IE的盒子模型有什么不同的?
標準盒子模型:寬度=內容的寬度(content)+ border + padding + margin
低版本IE盒子模型:寬度=內容寬度(content+border+padding)+ margin
2、 box-sizing屬性?
用來控制元素的盒子模型的解析模式,默認為content-box
context-box:W3C的標準盒子模型,設置元素的 height/width 屬性指的是content部分的高/寬
border-box:IE傳統盒子模型。設置元素的height/width屬性指的是border + padding + content部分的高/寬
3 、CSS選擇器有哪些?哪些屬性可以繼承?
CSS選擇符:id選擇器(#myid)、類選擇器(.myclassname)、標簽選擇器(div, h1, p)、相鄰選擇器(h1 + p)、子選擇器(ul > li)、后代選擇器(li a)、通配符選擇器(*)、屬性選擇器(a[rel="external"])、偽類選擇器(a:hover, li:nth-child)
可繼承的屬性:font-size, font-family, color
不可繼承的樣式:border, padding, margin, width, height
優先級(就近原則):!important > [ id > class > tag ]
!important 比內聯優先級高
4、 CSS優先級算法如何計算?
元素選擇符: 1
class選擇符: 10
id選擇符:100
元素標簽:1000
5、 CSS3新增偽類有那些?
p:first-of-type 選擇屬于其父元素的首個元素
p:last-of-type 選擇屬于其父元素的最后元素
p:only-of-type 選擇屬于其父元素唯一的元素
p:only-child 選擇屬于其父元素的唯一子元素
p:nth-child(2) 選擇屬于其父元素的第二個子元素
:enabled :disabled 表單控件的禁用狀態。
:checked 單選框或復選框被選中。
6 、如何居中div?如何居中一個浮動元素?如何讓絕對定位的div居中?
div:
border: 1px solid red;margin: 0 auto; height: 50px;width: 80px;
浮動元素的上下左右居中:
border: 1px solid red;float: left; position: absolute;width: 200px; height: 100px;left: 50%;top: 50%; margin: -50px 0 0 -100px;
絕對定位的左右居中:
border: 1px solid black;position: absolute; width: 200px;height: 100px;margin: 0 auto; left: 0;right: 0;
還有更加優雅的居中方式就是用flexbox,我以后會做整理。
7、 display有哪些值?說明他們的作用?
inline(默認)--內聯
none--隱藏
block--塊顯示
table--表格顯示
list-item--項目列表
inline-block
8、 position的值?
static(默認):按照正常文檔流進行排列;
relative(相對定位):不脫離文檔流,參考自身靜態位置通過 top, bottom, left, right 定位;
absolute(絕對定位):參考距其最近一個不為static的父級元素通過top, bottom, left, right 定位;
fixed(固定定位):所固定的參照對像是可視窗口。
9、 CSS3有哪些新特性?
10、 請解釋一下CSS3的flexbox(彈性盒布局模型),以及適用場景?
該布局模型的目的是提供一種更加高效的方式來對容器中的條目進行布局、對齊和分配空間。在傳統的布局方式中,block 布局是把塊在垂直方向從上到下依次排列的;而 inline 布局則是在水平方向來排列。彈性盒布局并沒有這樣內在的方向限制,可以由開發人員自由操作。
試用場景:彈性布局適合于移動前端開發,在Android和ios上也完美支持。
11、 用純CSS創建一個三角形的原理是什么?
首先,需要把元素的寬度、高度設為0。然后設置邊框樣式。
width: 0;height: 0;border-top: 40px solid transparent; border-left: 40px solid transparent;border-right: 40px solid transparent; border-bottom: 40px solid #ff0000;
12、 一個滿屏品字布局如何設計?
第一種真正的品字:
第二種全屏的品字布局:
上面的div設置成100%,下面的div分別寬50%,然后使用float或者inline使其不換行。
13 、常見的兼容性問題?
{background-color:#f1ee18;/*所有識別*/.background-color:#00deff; /*IE6、7、8識別*/+background-color:#a200ff;/*IE6、7識別*/_background-color:#1e0bd1;/*IE6識別*/}
14、 為什么要初始化CSS樣式
因為瀏覽器的兼容問題,不同瀏覽器對有些標簽的默認值是不同的,如果沒對CSS初始化往往會出現瀏覽器之間的頁面顯示差異。
15、 absolute的containing block計算方式跟正常流有什么不同?
無論屬于哪種,都要先找到其祖先元素中最近的 position 值不為 static 的元素,然后再判斷:
如果都找不到,則為 initial containing block。
補充:
16、CSS里的visibility屬性有個collapse屬性值?在不同瀏覽器下以后什么區別?
當一個元素的visibility屬性被設置成collapse值后,對于一般的元素,它的表現跟hidden是一樣的。
17、 display:none與visibility:hidden的區別?
display:none 不顯示對應的元素,在文檔布局中不再分配空間(回流+重繪)
visibility:hidden 隱藏對應元素,在文檔布局中仍保留原來的空間(重繪)
18、 position跟display、overflow、float這些特性相互疊加后會怎么樣?
display屬性規定元素應該生成的框的類型;position屬性規定元素的定位類型;float屬性是一種布局方式,定義元素在哪個方向浮動。
類似于優先級機制:position:absolute/fixed優先級最高,有他們在時,float不起作用,display值需要調整。float 或者absolute定位的元素,只能是塊元素或表格。
19 、對BFC規范(塊級格式化上下文:block formatting context)的理解?
BFC規定了內部的Block Box如何布局。
定位方案:
滿足下列條件之一就可觸發BFC
20、 為什么會出現浮動和什么時候需要清除浮動?清除浮動的方式?
浮動元素碰到包含它的邊框或者浮動元素的邊框停留。由于浮動元素不在文檔流中,所以文檔流的塊框表現得就像浮動框不存在一樣。浮動元素會漂浮在文檔流的塊框上。
浮動帶來的問題:
清除浮動的方式:
21、 上下margin重合的問題
在重合元素外包裹一層容器,并觸發該容器生成一個BFC。
例子:
<div class="aside"></div> <div class="text"> <div class="main"></div> </div> <!--下面是css代碼--> .aside { margin-bottom: 100px; width: 100px; height: 150px; background: #f66; } .main { margin-top: 100px; height: 200px; background: #fcc; } .text{ /*盒子main的外面包一個div, 通過改變此div的屬性使兩個盒子分屬于兩個不同的BFC, 以此來阻止margin重疊*/ overflow: hidden; //此時已經觸發了BFC屬性。 }
22、設置元素浮動后,該元素的display值是多少?
自動變成display:block
23、 移動端的布局用過媒體查詢嗎?
通過媒體查詢可以為不同大小和尺寸的媒體定義不同的css,適應相應的設備的顯示。
24 、使用 CSS 預處理器嗎?
Less sass
25、 CSS優化、提高性能的方法有哪些?
26、 瀏覽器是怎樣解析CSS選擇器的?
CSS選擇器的解析是從右向左解析的。若從左向右的匹配,發現不符合規則,需要進行回溯,會損失很多性能。若從右向左匹配,先找到所有的最右節點,對于每一個節點,向上尋找其父節點直到找到根元素或滿足條件的匹配規則,則結束這個分支的遍歷。
兩種匹配規則的性能差別很大,是因為從右向左的匹配在第一步就篩選掉了大量的不符合條件的最右節點(葉子節點),而從左向右的匹配規則的性能都浪費在了失敗的查找上面。
而在 CSS 解析完畢后,需要將解析的結果與 DOM Tree 的內容一起進行分析建立一棵 Render Tree,最終用來進行繪圖。在建立 Render Tree 時(WebKit 中的「Attachment」過程),瀏覽器就要為每個 DOM Tree 中的元素根據 CSS 的解析結果(Style Rules)來確定生成怎樣的 Render Tree。
27 、在網頁中的應該使用奇數還是偶數的字體?為什么呢?
使用偶數字體。偶數字號相對更容易和 web 設計的其他部分構成比例關系。Windows 自帶的點陣宋體(中易宋體)從 Vista 開始只提供 12、14、16 px 這三個大小的點陣,而 13、15、17 px時用的是小一號的點。(即每個字占的空間大了 1 px,但點陣沒變),于是略顯稀疏。
28、 margin和padding分別適合什么場景使用?
何時使用margin:
何時使用padding:
兼容性的問題:在IE5 IE6中,為float的盒子指定margin時,左側的margin可能會變成兩倍的寬度。通過改變padding或者指定盒子的display:inline解決。
29 、元素豎向的百分比設定是相對于容器的高度嗎?
當按百分比設定一個元素的寬度時,它是相對于父容器的寬度計算的,但是,對于一些表示豎向距離的屬性,例如 padding-top , padding-bottom , margin-top , margin-bottom 等,當按百分比設定它們時,依據的也是父容器的寬度,而不是高度。
30 、全屏滾動的原理是什么?用到了CSS的哪些屬性?
31、 什么是響應式設計?響應式設計的基本原理是什么?如何兼容低版本的IE?
響應式網站設計(Responsive Web design)是一個網站能夠兼容多個終端,而不是為每一個終端做一個特定的版本。
基本原理是通過媒體查詢檢測不同的設備屏幕尺寸做處理。
頁面頭部必須有meta聲明的viewport。
<meta name=’viewport’ content=”width=device-width, initial-scale=1. maximum-scale=1,user-scalable=no”>
32、 視差滾動效果?
視差滾動(Parallax Scrolling)通過在網頁向下滾動的時候,控制背景的移動速度比前景的移動速度慢來創建出令人驚嘆的3D效果。
33、 ::before 和 :after中雙冒號和單冒號有什么區別?解釋一下這2個偽元素的作用
:before 和 :after 這兩個偽元素,是在CSS2.1里新出現的。起初,偽元素的前綴使用的是單冒號語法,但隨著Web的進化,在CSS3的規范里,偽元素的語法被修改成使用雙冒號,成為::before ::after
34、 你對line-height是如何理解的?
行高是指一行文字的高度,具體說是兩行文字間基線的距離。CSS中起高度作用的是height和line-height,沒有定義height屬性,最終其表現作用一定是line-height。
單行文本垂直居中:把line-height值設置為height一樣大小的值可以實現單行文字的垂直居中,其實也可以把height刪除。
多行文本垂直居中:需要設置display屬性為inline-block。
35 、怎么讓Chrome支持小于12px 的文字?
p{font-size:10px;-webkit-transform:scale(0.8);} //0.8是縮放比例
36、 讓頁面里的字體變清晰,變細用CSS怎么做?
-webkit-font-smoothing在window系統下沒有起作用,但是在IOS設備上起作用-webkit-font-smoothing:antialiased是最佳的,灰度平滑。
37、 position:fixed;在android下無效怎么處理?
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
38、 如果需要手動寫動畫,你認為最小時間間隔是多久,為什么?
多數顯示器默認頻率是60Hz,即1秒刷新60次,所以理論上最小間隔為1/60*1000ms = 16.7ms。
39、 li與li之間有看不見的空白間隔是什么原因引起的?有什么解決辦法?
行框的排列會受到中間空白(回車空格)等的影響,因為空格也屬于字符,這些空白也會被應用樣式,占據空間,所以會有間隔,把字符大小設為0,就沒有空格了。
解決方法:
40、 display:inline-block 什么時候會顯示間隙?
41、 有一個高度自適應的div,里面有兩個div,一個高度100px,希望另一個填滿剩下的高度
外層div使用position:relative;高度要求自適應的div使用position: absolute; top: 100px; bottom: 0; left: 0
42、 png、jpg、gif 這些圖片格式解釋一下,分別什么時候用。有沒有了解過webp?
43、 style標簽寫在body后與body前有什么區別?
頁面加載自上而下 當然是先加載樣式。
寫在body標簽后由于瀏覽器以逐行方式對HTML文檔進行解析,當解析到寫在尾部的樣式表(外聯或寫在style標簽)會導致瀏覽器停止之前的渲染,等待加載且解析樣式表完成之后重新渲染,在windows的IE下可能會出現FOUC現象(即樣式失效導致的頁面閃爍問題)
44、 CSS屬性overflow屬性定義溢出元素內容區的內容會如何處理?
參數是scroll時候,必會出現滾動條。
參數是auto時候,子元素內容大于父元素時出現滾動條。
參數是visible時候,溢出的內容出現在父元素之外。
參數是hidden時候,溢出隱藏。
45、 闡述一下CSS Sprites
將一個頁面涉及到的所有圖片都包含到一張大圖中去,然后利用CSS的 background-image,background- repeat,background-position 的組合進行背景定位。利用CSS Sprites能很好地減少網頁的http請求,從而大大的提高頁面的性能;CSS Sprites能減少圖片的字節。
關注此頭條號“互聯網IT信息”——>私信發送 “天貓css” ,(注意:css全是小寫)即可得到源代碼的獲取方式。
案例和由此案例重點講解的知識點介紹
案例代碼實現
css三大特性知識點詳解
此案例是頁面,效果如下:
此頁面的技術實現解析:
使用標簽選擇器定義通用樣式,通過css層疊性和繼承性來讓通用標簽的樣式被繼承到類選擇器上
此案例中主要用到了,基于此,我們會系統的將如下知識點全部講解:
css三大特性:層疊性、繼承性、優先級
第一步:使用塊級標簽和無序列表編寫導航側邊欄的html
第二步:通過標簽選擇器定義ul li a的通用樣式
第三步:定義外層div樣式
第四步:通過類選擇器定義無序列表樣式,其中li和a標簽的基本樣式繼承自第二步的標簽選擇器
CSS三大特性:
層疊性、繼承性、優先級
1)層疊性:
1. 給一個標簽設置的樣式發生沖突的時候即樣式的覆蓋
2. 瀏覽器的渲染機制是從上到下的,當有沖突的時候就采用最后的那個樣式
例如:
h2.grape {color: purple;}
h2 {color: siver;}
層疊性代碼實例:
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>Document</title>
<styletype="text/css">
.two{
color: green;
}
.one{
color: red;
font-size: 30px;
}
.tree{
color: yellow;
font-size: 40px;
}
</style>
</head>
<body>
<pclass="one two tree">
一段文字
</p>
</body>
</html>
2)繼承性:繼承就是子標簽繼承了上級標簽的CSS樣式的屬性
1,發生的前提是:標簽之間屬于一種嵌套關系
2,文字顏色可以之間繼承
3,字體大小可以繼承
4,字體可以繼承
5,行高也可以實現繼承
6, 與文字有關的屬性都可以,實現繼承
特殊注意:
a標簽超鏈接不能實現字體顏色的繼承,字體大小可以繼承
h1不可以繼承文字的大小,繼承過來還會做一個計算
繼承性代碼實例:
<!DOCTYPEhtml>
<html>
<head>
<metacharset="UTF-8">
<title></title>
<style>
div{
color: red;
font-size: 30px;
}
</style>
</head>
<body>
<div>
<ahref="">a</a>
</div>
</body>
</html>
3) 優先級
具體解釋如下:
內聯樣式最大,內聯樣式的優先級最高。
ID選擇器的優先級,僅次于內聯樣式。
類選擇器優先級低于ID選擇器
標簽選擇器低于類選擇器。
補充:
權重相同時,CSS遵循就近原則。也就是說靠近元素的樣式具有最大的優先級,或者說排在最后的樣式優先級最大。
所有都相同時,聲明靠后的優先級大。
CSS定義了一個!important命令,該命令被賦予最大的優先級。也就是說不管權重如何以及樣式位置的遠近,!important都具有最大優先級。
綜述:
-行內樣式 > 頁內樣式 > 外部引用樣式 > 瀏覽器默認樣式
important > 內聯 > ID > 偽類|類 | 屬性選擇 > 標簽 > 偽對象 > 通配符 > 繼承
css優先級代碼實例:
<!DOCTYPE>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/>
<title>無標題文檔</title>
<style>
*{ font-size:56px;}
p{ font-size:32px; color:#60C;}
.d{ color:#F0F;}
#hei{ color:#96F;}
</style>
</head>
<body>
<h1>我是標題</h1>
<p>我是段落</p>
<p>我是段落2</p>
<pclass="d"id="hei"style="color:#FF0;">我是段落3</p>
<ahref="#">我是超鏈接</a>
<span>我是備胎標簽</span>
</body>
</html>
*請認真填寫需求信息,我們會在24小時內與您取得聯系。