- 使用flex佈局: 父元素設置
display: flex
,左右兩邊設置固定寬度,中間設置flex-grow: 1
;- 使用浮動佈局:左右兩邊設置固定寬度,並且分別設置
float:left和right
,這個方法有一個須要注意的是在HTML中,中間欄須要和右邊欄進行對調;- 使用絕對定位佈局:左右兩邊設置固定寬度和
position:absolute
,並且分別設置left: 0
和right: 0
,中間欄只要設置左右margin爲左右欄的寬度就能夠了(須要注意的是左右兩邊須要設置top: 0
,否則右邊會被頂下來)
補充前端
其實還有表格佈局,網格佈局和聖盃佈局,詳細請看 三欄佈局的5種解決方案及優缺點
<div class="dialog"> <div class="dialog-content"></div> </div>
position
元素已知寬度:.dialog{ position: relative; width: 500px; height: 500px; background: goldenrod } .dialog-content{ width: 200px; height: 200px; background: rebeccapurple; position: absolute; top: 50%; left: 50%; margin:-100px 0 0 -100px; }
transform
元素未知寬度.dialog{ position: relative; width: 500px; height: 500px; background: goldenrod } .dialog-content{ width: 200px; height: 200px; background: rebeccapurple; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); }
flex
佈局.dialog { width: 500px; height: 500px; background: goldenrod; display: flex; justify-content: center; align-items: center; } .dialog-content { width: 200px; height: 200px; background: rebeccapurple; }
==
和 ===
的區別===
爲恆等符:當等號兩邊的值爲相同類型的時候,直接比較等號兩邊的值,值相同則返回true,若等號兩邊的值類型不一樣時直接返回false。
==
爲等值符: 當等號兩邊的值爲相同類型時比較值是否相同,類型不一樣時會發生類型的自動轉換,轉換爲相同的類型後再做比較。
a、若是一個是null、一個是undefined,那麼[相等]。
b、若是一個是字符串,一個是數值,把字符串轉換成數值再進行比較。
c、若是任一值是 true,把它轉換成 1 再比較;若是任一值是 false,把它轉換成 0 再比較。
d、若是一個是對象,另外一個是數值或字符串,把對象轉換成基礎類型的值再比較。對象轉換成基礎類型,利用它的toString或者valueOf方法。 js核心內置類,會嘗試valueOf先於toString;例外的是Date,Date利用的是toString轉換。非js核心的對象,令說(比較麻 煩,我也不大懂)
e、任何其餘組合,都[不相等]。vue
==
'30' 的過程是怎樣的?
- 30爲數值類型,而'30'未字符串類型,所以等號兩邊的數據類型不相等,須要進行轉換類型;
- 因爲一個是數值,另外一個字符串,因此須要將字符串轉換成數值再進行比較,即
'30' => 30
;- 這時等號兩邊一樣爲數值型數據,即
30 == 30
,因此返回true
for (var i=0; i<5; i++) { setTimeout( function timer() { console.log(i); }, 0 ); }
回答: 直接輸出 5 5 5 5 5 node
首先這裏涉及到setTimeout
的執行順序,頁面中全部由setTimeout
定義的操做,都將放在同一個隊列中(這裏涉及到兩種, 微任務隊列和 宏任務隊列,恰好下面問Promise的時候就問到了)依次執行。
這個隊列執行的時間,須要等待到函數調用棧清空以後纔開始執行。即全部可執行代碼執行完畢以後,纔會開始執行由
setTimeout
定義的操做。而這些操做進入隊列的順序,則由設定的延遲時間來決定。面試根據
setTimeout
定義的操做在函數調用棧清空以後纔會執行的特色,for循環裏定義了5個setTimeout
操做,這些setTimeout
操做是在循環執行完成後纔開始執行,這個時候i = 5
,由於每一個setTimeout
操做的延遲時間同樣,因此按順序輸出5 5 5 5 5
ajax
window.onload
執行時間?修改this指向的辦法有三種:apply
、call
和bind
apply
、call
:經過傳入須要指向的對象,從而改變this
的指向,指向傳入的第一個參數;
bind
:它會建立一個函數的實例,其this值會被綁定到傳給bind()函數的值。
window.color = 'red'; var o = { color:'blue' }; function sayColor(){ console.log(this.color); } var globalSaycolor = sayColor; var objectSaycolor = sayColor.bind(o); globalSaycolor(); // red objectSaycolor(); // blue
補充算法
其實還有一種: new關鍵字改變this指向
由於在new
的過程當中,其中有一個步驟爲將構造函數內部的this
指向實例對象,因此經過new關鍵字
也能夠改變this
的指向。
apply
和call
的區別?相同點:能夠用來代替另外一個對象調用一個方法,將一個函數的對象上下文從初始的上下文改變爲由thisObj指定的新對象。不一樣點:實際上,
apply
和call
的功能是同樣的,只是傳入的參數列表形式不一樣。apply
:最多隻能有兩個參數——新this
對象和一個數組argArray
。若是給該方法傳遞多個參數,則把參數都寫進這個數組裏面,固然,即便只有一個參數,也要寫進數組裏。若是argArray
不是一個有效的數組或arguments
對象,那麼將致使一個TypeError
。若是沒有提供argArray
和thisObj
任何一個參數,那麼Global對象將被用做thisObj
,而且沒法被傳遞任何參數。vuex
call
:它能夠接受多個參數,第一個參數與apply
同樣,後面則是一串參數列表。這個方法主要用在js對象各方法相互調用的時候,使當前this實例指針保持一致,或者在特殊狀況下須要改變this指針。若是沒有提供thisObj
參數,那麼 Global 對象被用做thisObj
。數據庫
因爲按鈕是異步生成的,因此我選擇將事件綁定在按鈕生成的父元素上,經過事件委託的機制,利用事件冒泡,把事件綁定在父元素上,能夠經過判斷event.target
按鈕是否已經生成,從而實現相應的事件。科普補充:
事件冒泡能夠形象地比喻爲把一顆石頭投入水中,泡泡會一直從水底冒出水面。也就是說,事件會從最內層的元素開始發生,一直向上傳播,直到document
對象;
事件捕獲則跟事件冒泡相反,事件會從document
對象開始發生,直到最具體的元素;npm
我處理過的跨域有兩種狀況:segmentfault
- 一種是在頁面中嵌入了一個iframe,所以父子iframe間產生了跨域,要解決這個問題,只須要把
document.domain
設置成相同的值就能夠在兩個頁面裏進行相應的操做了;- 另一種狀況是用Vue開發涉及到的跨域問題,這個問題只須要修改config文件夾下的index.js中的dev:{}部分中修改proxyTable參數便可,至關於對跨域的url進行了代理,從而能夠順利訪問。
另外說了一下本身比較熟悉的一種跨域解決方案:JSONP
JSONP解決跨域問題的本質其實就是<script>
標籤能夠請求不一樣域名下的資源,即<script>
請求不受瀏覽器同源策略影響。
面試官聽到JSONP馬上提出了一個問題:JSONP是否能夠支持POST
方法?爲何?
JSONP只支持GET
的請求方法,上面也提到了JSONP原理其實就是利用<script>
標籤發送了一個URL
給服務器,其實與ajax XMLHttpRequest
協議無關了,至關於輸入了一個url
而已,因此必然只能爲GET
請求方法。
POST
和GET
,說說二者的區別?
- 大小:
GET
提交的數據最大爲2k(原則上url長度無限制,但是瀏覽器一般限制url長度在2k左右);POST
理論上沒有限制大小(實際上IIS4中最大量爲80KB,IIS5中爲100KB)。- 發送方式:
GET
請求數據放在url上,即HTTP協議頭中,其格式爲:url?key=value&key2=value
;POST
把數據放在HTTP的包體中(Request Body)。- 安全性:
GET
請求可被緩存,請求保存在瀏覽器歷史記錄中;POST
則不能被緩存。與POST
相比,GET
的安全性較差,由於發送的數據是URL的一部分。- 發送TCP包:對
GET
請求只產生一個TCP包,瀏覽器會把http header
和data
一併發送出去,服務器響應200
(返回數據);對於POST
請求產生兩個TCP數據包,瀏覽器先發送http header
,服務器確認權限正確響應100
(continue)返回瀏覽器,瀏覽器收到100
確認繼續請求,再次發送data
,服務器響應200
(返回數據)。
瀏覽器緩存類型有兩種,強緩存和協商緩存
- 強緩存:不會向服務器發送請求,直接從緩存中讀取資源(
Expires --> HTTP 1.0
或cache-control --> HTTP 1.1
);- 協商緩存:向服務器發送請求,服務器會根據這個請求的
If-None-Match
和If-Modified-Since
來判斷是否命中協商緩存,若是命中,則返回304狀態碼並帶上新的response header
通知瀏覽器從緩存中讀取資源;具體流程參考下圖:
補充
共同點: 都是從客戶端緩存中讀取資源
不一樣點: 強緩存不會發送請求;協商緩存會發請求。
Promise 有三個狀態Pending
、Fulfilled
和Rejected
,只能從Pending
轉換爲Fulfilled
,和Pending
轉換爲Rejected
,狀態一旦改變就不能再次變化。
![]()
pending
狀態能夠中止嗎?pending
狀態能夠中止嗎?若是Promise
和setTimeout
同時存在的話,通常是先執行Promise
以後再執行setTimeout
。由於這裏涉及到 微任務隊列(Microtasks)和 宏任務隊列(Macrotasks)。
microtasks queue
中的內容常常是爲了須要直接在當前腳本執行完後當即發生的事,因此當同步執行完以後就調用隊列中的內容,而後把異步隊列中的setTimeout
放入執行棧中執行。
科普補充
理解 JavaScript 中的 macrotask 和 microtask
Tasks, microtasks, queues and schedules
- 首先能夠在
beforecreate
中添加一個loading
,而後在created
中結束這個loading
,還作一些初始化,實現函數自執行;- 能夠在
mounted
中向後臺請求數據,進行頁面的渲染;- 能夠
update
中對data中的數據進行檢測,實現對頁面的修改。
若是把數據獲取放在created
中,若是數據量很大,會出現頁面加載緩慢的結果……
這兩個問題回答的不是很是的好,但願有人能夠幫忙解答一下嗎?
經典問題,具體參考 剖析Vue原理&實現雙向綁定MVVM
重繪:當元素的一部分屬性發生變化,如外觀背景色不會引發佈局變化而須要從新渲染的過程;
迴流: 當render樹中的一部分或者所有由於大小邊距等問題發生改變而須要重建的過程;
迴流必定會發生重繪,重繪不必定引起迴流。
頁面加載的順序:
- 瀏覽器解析HTML文件構建DOM樹;
- 解析CSS文件構建Style Rules;
- 二者合併生成Render Tree;
- Layout 根據Render Tree計算每一個節點的信息;
- Painting 根據計算好的信息繪製整個頁面;
P.S 當文檔加載過程當中遇到JS文件,HTML文檔會掛起渲染過程,不只要等到文檔中JS文件加載完畢還要等待解析執行完畢,纔會繼續HTML的渲染過程
一. CSS中避免迴流
二. JS操做避免迴流
在面完第一面以後,原本覺得終於結束了,沒想到迎來的是第二技術面,後面面試官介紹說其實原本是應該兩我的同時面個人,由於有一個面試官沒空,因此就錯開了,就有了"二面"了,其實本質上仍是一面而已。
1XX系列:指定客戶端應相應的某些動做,表明請求已被接受,須要繼續處理;
2XX系列:表明請求已成功被服務器接收、理解、並接受;
3XX系列:表明須要客戶端採起進一步的操做才能完成請求,這些狀態碼用來重定向,後續的請求地址(重定向目標)在本次響應的 Location 域中指明;301:被請求的資源已永久移動到新位置;
302:請求的資源臨時從不一樣的URI響應請求,但請求者應繼續使用原有位置來進行之後的請求;
304:資源找到可是不符合請求條件,不會返回任何主體(用於協商緩存,表示瀏覽器緩存資源未改變,仍然可用);4XX系列:表示請求錯誤。表明了客戶端看起來可能發生了錯誤,妨礙了服務器的處理。
5xx系列:表明了服務器在處理請求的過程當中有錯誤或者異常狀態發生,也有多是服務器意識到以當前的軟硬件資源沒法完成對請求的處理。
/^[a-z0-9][a-z]+$/
和 /^[a-z0-9][a-z]*$/
的區別?二者的區別主要是最後的*
和+
,
+
出現一次或屢次(至少出現一次),等價於{1, }
*
出現零次或屢次(任意次),等價於{0, }
最後再借助正則可視化對比就很明顯了
![]()
display:none
和 visibility:hidden
的區別?visibility:hidden
:所佔據的空間位置仍然存在,僅爲視覺上的徹底透明;
visibility:hidden
變化不會觸發reflow。
display:none
: 不爲被隱藏的對象保留其物理空間。
display:none
變化時將觸發reflow;
科普補充
CSS魔法堂:display:none與visibility:hidden的恩怨情仇
可參考一面的第一和第二個問題。
li{ display: inline-block; background: red; width: 300px; height: 100px; } <div> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </div>
瀏覽器會把inline元素間的空白字符(空格、換行、Tab等)渲染成一個空格。而爲了美觀。咱們一般是一個<li>
放在一行,這致使<li>
換行後產生換行字符,它變成一個空格,佔用了一個字符的寬度。
解決:
方法一:爲<li>
設置float: left
。不足:有些容器是不能設置浮動,如左右切換的焦點圖等。
方法二:將全部<li>
寫在同一行。不足:代碼不美觀。
方法三:將<ul>
內的字符尺寸直接設爲0,即font-size: 0
。不足:<ul>
中的其餘字符尺寸也被設爲0,須要額外從新設定其餘字符尺寸,且在Safari瀏覽器依然會出現空白間隔。
方法四:消除<ul>
的字符間隔letter-spacing: -8px
,而這也設置了<li>
內的字符間隔,所以須要將<li>
內的字符間隔設爲默認letter-spacing: normal
。
有多種方法解決
- 使用一個空的 Vue 實例做爲中央事件總線
- 使用Vuex
- 使用localStorage和SessionStorage