前端面試題篩選摘要

2:Vue雙向數(shù)據(jù)綁定的實(shí)現(xiàn)

vue.js 則是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個(gè)屬性的setter,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給 訂閱者(文本節(jié)點(diǎn)則是作為訂閱者),在收到消息后執(zhí)行相應(yīng)的更新操作。
compile主要做的事情是解析模板指令,將模板中的變量替換成數(shù)據(jù),然后初始化渲染頁面視圖,并將每個(gè)指令對應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動(dòng),收到通知,更新視圖
MVVM作為數(shù)據(jù)綁定的入口,整合Observer、Compile和Watcher三者,通過Observer來監(jiān)聽自己的model數(shù)據(jù)變化,通過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 -> 視圖更新;視圖交互變化(input) -> 數(shù)據(jù)model變更的雙向綁定效果。
AngularJS 采用“臟值檢測”的方式,數(shù)據(jù)發(fā)生變更后,對于所有的數(shù)據(jù)和視圖的綁定關(guān)系進(jìn)行一次檢測,識別是否有數(shù)據(jù)發(fā)生了改變。

3:react和vue有哪些不同 說說你對這兩個(gè)框架的看法

都用了virtual dom的方式, 性能都很好
ui上都是組件化的寫法,開發(fā)效率很高
vue是雙向數(shù)據(jù)綁定,react是單項(xiàng)數(shù)據(jù)綁定,當(dāng)工程規(guī)模比較大時(shí)雙向數(shù)據(jù)綁定會(huì)很難維護(hù)
vue適合不會(huì)持續(xù)的 小型的web應(yīng)用,使用vue.js能帶來短期內(nèi)較高的開發(fā)效率. 否則采用react

4:let和const的區(qū)別

let聲明的變量可以改變,值和類型都可以改變,沒有限制。
const聲明的變量不得改變值 本質(zhì)就是地址不會(huì)改變,但可以改變它屬性的值

5:平時(shí)用了es6的哪些特性,體驗(yàn)如何 和es5有什么不同

let const關(guān)鍵字 箭頭函數(shù) 字符串模板 class類 模塊化 promise

es5 require react.createclass

6:瀏覽器原生支持module嗎,如果支持,會(huì)帶來哪些便利

不支持

7:介紹一下你對webpack的理解,和gulp有什么不同

Webpack是模塊打包工具,他會(huì)分析模塊間的依賴關(guān)系,然后使用loaders處理它們,最后生成一個(gè)優(yōu)化并且合并后的靜態(tài)資源。
gulp是前端自動(dòng)化工具 能夠優(yōu)化前端工作流程,比如文件合并壓縮

8:webpack打包速度慢,你覺得可能的原因是什么,該如何解決

模塊太多
Webpack 可以配置 externals 來將依賴的庫指向全局變量,從而不再打包這個(gè)庫

9:http響應(yīng)中content-type包含哪些內(nèi)容

請求中的消息主體是用何種方式編碼
application/x-www-form-urlencoded
這是最常見的 POST 提交數(shù)據(jù)的方式 按照 key1=val1&key2=val2 的方式進(jìn)行編碼
application/json
告訴服務(wù)端消息主體是序列化后的 JSON 字符串

10:瀏覽器緩存有哪些,通常緩存有哪幾種方式

強(qiáng)緩存 強(qiáng)緩存如果命中,瀏覽器直接從自己的緩存中讀取資源,不會(huì)發(fā)請求到服務(wù)器。
協(xié)商緩存 當(dāng)強(qiáng)緩存沒有命中的時(shí)候,瀏覽器一定會(huì)發(fā)送一個(gè)請求到服務(wù)器,通過服務(wù)器端依據(jù)資源的另外一些http header驗(yàn)證這個(gè)資源是否命中協(xié)商緩存,如果協(xié)商緩存命中,服務(wù)器會(huì)將這個(gè)請求返回(304),若未命中請求,則將資源返回客戶端,并更新本地緩存數(shù)據(jù)(200)。
HTTP頭信息控制緩存
Expires(強(qiáng)緩存)+過期時(shí)間 Expires是HTTP1.0提出的一個(gè)表示資源過期時(shí)間的header,它描述的是一個(gè)絕對時(shí)間
Cache-control(強(qiáng)緩存) 描述的是一個(gè)相對時(shí)間,在進(jìn)行緩存命中的時(shí)候,都是利用客戶端時(shí)間進(jìn)行判斷 管理更有效,安全一些 Cache-Control: max-age=3600
Last-Modified/If-Modified-Since(協(xié)商緩存) 標(biāo)示這個(gè)響應(yīng)資源的最后修改時(shí)間。Last-Modified是服務(wù)器相應(yīng)給客戶端的,If-Modified-Sinces是客戶端發(fā)給服務(wù)器,服務(wù)器判斷這個(gè)緩存時(shí)間是否是最新的,是的話拿緩存。
Etag/If-None-Match(協(xié)商緩存) etag和last-modified類似,他是發(fā)送一個(gè)字符串來標(biāo)識版本。

11:如何取出一個(gè)數(shù)組里的圖片并按順序顯示出來

function loadImage(imgList,callback){
        if(!$.isArray(imgList) || !$.isFunction(callback)) return ;
        var imageData = [] ;
        $.each(imgList, function(i,src){
            var img = new Image() ;
            img.onload = function(){
                $(imageData.shift()).appendTo("body") ;
                if(!imageData.length){
                    callback() ;
                    return ;
                }
                this.onload = null ;
            } ;
            img.src= src ;
            imageData.push(img) ;
        }) ;
    } ;

12:平時(shí)是怎么學(xué)新技術(shù)的

infoq 掘金 簡書 慕課網(wǎng) B站

13:Node,Koa用的怎么樣

koa是一個(gè)相對于express來說,更小,更健壯,更富表現(xiàn)力的Web框架,不用寫回調(diào)
koa是從第一個(gè)中間件開始執(zhí)行,遇到next進(jìn)入下一個(gè)中間件,一直執(zhí)行到最后一個(gè)中間件,在逆序
async await語法的支持

14:使用模塊化加載時(shí),模塊加載的順序是怎樣的,如果不知道,根據(jù)已有的知識,你覺得順序應(yīng)該是怎么樣的
commonjs 同步 順序執(zhí)行

AMD 提前加載,不管是否調(diào)用模塊,先解析所有模塊 requirejs 速度快 有可能浪費(fèi)資源
CMD 提前加載,在真正需要使用(依賴)模塊時(shí)才解析該模塊 seajs 按需解析 性能比AMD差

15: 介紹一下閉包和閉包常用場景

閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù). 創(chuàng)建閉包常見方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù).
應(yīng)用場景 設(shè)置私有變量和方法
不適合場景:返回閉包的函數(shù)是個(gè)非常大的函數(shù)
閉包的缺點(diǎn)就是常駐內(nèi)存,會(huì)增大內(nèi)存使用量,使用不當(dāng)很容易造成內(nèi)存泄露。

16: 為什么會(huì)出現(xiàn)閉包這種東西,解決了什么問題

受JavaScript鏈?zhǔn)阶饔糜蚪Y(jié)構(gòu)的影響,父級變量中無法訪問到子級的變量值,為了解決這個(gè)問題,才使用閉包這個(gè)概念

17: 介紹一下你所了解的作用域鏈,作用域鏈的盡頭是什么,為什么

每一個(gè)函數(shù)都有一個(gè)作用域,比如我們創(chuàng)建了一個(gè)函數(shù),函數(shù)里面又包含了一個(gè)函數(shù),那么現(xiàn)在 就有三個(gè)作用域,這樣就形成了一個(gè)作用域鏈。
作用域的特點(diǎn)就是,先在自己的變量范圍中查找,如果找不到,就會(huì)沿著作用域鏈往上找。

18: 一個(gè)Ajax建立的過程是怎樣的,主要用到哪些狀態(tài)碼

ajax:在不切換頁面的情況下完成異步的HTTP請求
(1)創(chuàng)建XMLHttpRequest對象,也就是創(chuàng)建一個(gè)異步調(diào)用對象.
(2)創(chuàng)建一個(gè)新的HTTP請求,并指定該HTTP請求的方法、URL及驗(yàn)證信息.
(3)設(shè)置響應(yīng)HTTP請求狀態(tài)變化的函數(shù).
(4)發(fā)送HTTP請求.
(5)獲取異步調(diào)用返回的數(shù)據(jù).
(6)使用JavaScript和DOM實(shí)現(xiàn)局部刷新.

var xmlHttp = new XMLHttpRequest();

  xmlHttp.open('GET','demo.php','true');

  xmlHttp.send()

  xmlHttp.onreadystatechange = function(){

      if(xmlHttp.readyState === 4 & xmlHttp.status === 200){

      }

  }

//使用promise封裝

function getJSON(url) { 
    return new Promise(function(resolve, reject) { 
        var XHR = new XMLHttpRequest(); 
        XHR.open('GET', url, true); 
        XHR.send(); 

        XHR.onreadystatechange = function() { 
            if (XHR.readyState == 4) { 
                if (XHR.status == 200) { 
                    try { 
                        var response = JSON.parse(XHR.responseText); 
                        resolve(response); 
                    } catch (e) { 
                        reject(e); 
                    } 
                } else { 
                    reject(new Error(XHR.statusText)); 
                } 
            } 
        } 
    }) 
} 

getJSON(url).then(res => console.log(res)); 

當(dāng)前狀態(tài)readystate
0 代表未初始化。 還沒有調(diào)用 open 方法
1 代表正在加載。 open 方法已被調(diào)用,但 send 方法還沒有被調(diào)用
2 代表已加載完畢。send 已被調(diào)用。請求已經(jīng)開始
3 代表交互中。服務(wù)器正在發(fā)送響應(yīng)
4 代表完成。響應(yīng)發(fā)送完畢

常用狀態(tài)碼status
404 沒找到頁面(not found)
403 禁止訪問(forbidden)
500 內(nèi)部服務(wù)器出錯(cuò)(internal service error)
200 一切正常(ok)
304 沒有被修改(not modified)(服務(wù)器返回304狀態(tài),表示源文件沒有被修改)

19: 說說你還知道的其他狀態(tài)碼,狀態(tài)碼的存在解決了什么問題

302/307  臨時(shí)重定向
301 永久重定向
借助狀態(tài)碼,用戶可以知道服務(wù)器端是正常處理了請求,還是出現(xiàn)了什么錯(cuò)誤

20: 知道語義化嗎?說說你理解的語義化,如果是你,平時(shí)會(huì)怎么做來保證語義化

像html5的新的標(biāo)簽header,footer,section等就是語義化
一方面,語義化就是讓計(jì)算機(jī)能夠快速的讀懂內(nèi)容,高效的處理信息,可以對搜索引擎更友好。
另一方面,便于與他人的協(xié)作,他人通過讀代碼就可以理解你網(wǎng)頁標(biāo)簽的意義。

21: 說說content-box和border-box,為什么看起來content-box更合理,但是還是經(jīng)常使用border-box

content-box 是W3C的標(biāo)準(zhǔn)盒模型 元素寬度=內(nèi)容寬度+padding+border
border-box 是ie的怪異盒模型 他的元素寬度等于內(nèi)容寬度 內(nèi)容寬度包含了padding和border
比如有時(shí)候在元素基礎(chǔ)上添加內(nèi)距padding或border會(huì)將布局撐破 但是使用border-box就可以輕松完成

22:介紹一下HTML5的新特性

新的DOCTYPE聲明 <!DOCTYPE html>
完全支持css3
video和audio
本地存儲(chǔ)
語義化標(biāo)簽
canvas
新事件 如ondrag onresize

23:對自己未來的規(guī)劃是怎樣的

對于剛畢業(yè)的人來說,前兩年是很重要的,先打好基礎(chǔ),多提升js能力。三至四年在提升JS能力的同時(shí),開始要往多方面發(fā)展,前端工程師遠(yuǎn)遠(yuǎn)不僅是JS而已。制作一個(gè)性能高、交互好、視覺美的頁面,需要從前端框架選型、架構(gòu)設(shè)計(jì)、構(gòu)建工具,到后端通信機(jī)制、設(shè)計(jì)與交互、網(wǎng)絡(luò)和瀏覽器優(yōu)化等各方面的知識。一專多長才是前端工程師的終極目標(biāo)。

24: 在一個(gè)UI李有10個(gè)li,實(shí)現(xiàn)點(diǎn)擊對應(yīng)的li,輸出對應(yīng)的下標(biāo)

var lis = querySelectorAll('li')
for(var i=0;i<10;i++){
   lis[i].onclick = (function(a) {
      return function() {
       alert(a)
    }
  })(i)
}   

事件委托
利用冒泡的原理,把事件加到父級上,觸發(fā)執(zhí)行效果。
1.可以大量節(jié)省內(nèi)存占用,減少事件注冊。
2.可以方便地動(dòng)態(tài)添加和修改元素,不需要因?yàn)樵氐母膭?dòng)而修改事件綁定。

var ul = document.querySelector('ul'); 
var list = document.querySelectorAll('ul li'); 

ul.addEventListener('click', function(ev){ 
    var ev = ev || window.event; 
    var target = ev.target || ev.srcElemnt; 

    for(var i = 0, len = list.length; i < len; i++){ 
        if(list[i] == target){ 
            alert(i + "----" + target.innerHTML); 
        } 
    } 
}); 

25:實(shí)現(xiàn)三個(gè)DIV等分排布在一行(考察border-box)

1.設(shè)置border-box width33.3%
2.flexbox flex:1

26: 說說你知道JavaScript的內(nèi)存回收機(jī)制

垃圾回收器會(huì)每隔一段時(shí)間找出那些不再使用的內(nèi)存,然后為其釋放內(nèi)存。
一般使用標(biāo)記清除方法 當(dāng)變量進(jìn)入環(huán)境標(biāo)記為進(jìn)入環(huán)境,離開環(huán)境標(biāo)記為離開環(huán)境
還有引用計(jì)數(shù)方法
堆棧
stack為自動(dòng)分配的內(nèi)存空間,它由系統(tǒng)自動(dòng)釋放;而heap則是動(dòng)態(tài)分配的內(nèi)存,大小不定也不會(huì)自動(dòng)釋放。
基本數(shù)據(jù)類型存放在棧中
引用類型 存放在堆內(nèi)存中,首先從棧中獲得該對象的地址指針,然后再從堆內(nèi)存中取得所需的數(shù)據(jù)

27函數(shù)防抖和函數(shù)節(jié)流

函數(shù)防抖是指頻繁觸發(fā)的情況下,只有足夠的空閑時(shí)間,才執(zhí)行代碼一次
函數(shù)防抖的要點(diǎn),也是需要一個(gè)setTimeout來輔助實(shí)現(xiàn)。延遲執(zhí)行需要跑的代碼。
如果方法多次觸發(fā),則把上次記錄的延遲執(zhí)行代碼用clearTimeout清掉,重新開始。
如果計(jì)時(shí)完畢,沒有方法進(jìn)來訪問觸發(fā),則執(zhí)行代碼。

//函數(shù)防抖
var timer = false
document.getElementById("debounce").onScroll = function() {
        clearTimeout(timer)  
        timer = setTimeout(function(){
                console.log(‘函數(shù)防抖’) 
  }, 300)     
}
\
1
2
3
4
5
6
7
8
函數(shù)節(jié)流是指一定時(shí)間內(nèi)js方法只跑一次

函數(shù)節(jié)流的要點(diǎn)是,聲明一個(gè)變量當(dāng)標(biāo)志位,記錄當(dāng)前代碼是否在執(zhí)行。 
如果空閑,則可以正常觸發(fā)方法執(zhí)行。 
如果代碼正在執(zhí)行,則取消這次方法執(zhí)行,直接return。

//函數(shù)節(jié)流
var canScroll = true;
document.getElementById('throttle').onScroll = function() {
               if (!canScroll) {
                return;
               }
                canScroll = false;
                setTimeout(function(){
                   console.log('函數(shù)節(jié)流');
                   canScroll = true;
                },300)       
}

28:編程實(shí)現(xiàn)輸出一個(gè)數(shù)組中第N大的數(shù)據(jù)

自己寫唄

29.實(shí)現(xiàn)兩欄布局有哪些方法

*{margin:0; padding: 0;}
html,body{
        height: 100%;/*高度百分百顯示*/
}
#left{
    width: 300px;
    height: 100%;
    background-color: #ccc;
    float: left;
}
#right{
    height: 100%;
    margin-left: 300px;
    background-color: #eee;
*{margin:0; padding: 0;}
html,body{
        height: 100%;/*高度百分百顯示*/
}
#left{
    width: 300px;
    height: 100%;
    background-color: #ccc;
    float: left;
}
#right{
    height: 100%;
    overflow:hidden;
    background-color: #eee;
}

第二種方法,我利用的是創(chuàng)建一個(gè)新的BFC(塊級格式化上下文)來防止文字環(huán)繞的原理來實(shí)現(xiàn)的。BFC就是一個(gè)相對獨(dú)立的布局環(huán)境,它內(nèi)部元素的布局不受外面布局的影響。它可以通過以下任何一種方式來創(chuàng)建:
float 的值不為 none
position 的值不為 static 或者 relative
display 的值為 table-cell , table-caption , inline-block , flex , 或者 inline-flex 中的其中一個(gè)
overflow 的值不為 visible

第三種flex布局

自己想

30:設(shè)置width的flex元素,flex屬性值是多少

flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫
flex-grow屬性定義項(xiàng)目的放大比例,默認(rèn)為0
flex-shrink屬性定義了項(xiàng)目的縮小比例,默認(rèn)為1
flex-basis屬性定義了項(xiàng)目的固定空間

31get和post有什么不同

get是從服務(wù)器上獲取數(shù)據(jù),post是向服務(wù)器傳送數(shù)據(jù)
get請求可以將查詢字符串參數(shù)追加到url的末尾; post請求應(yīng)該把數(shù)據(jù)作為請求的主體提交.
get請求數(shù)據(jù)有大小限制;post沒有
post比get安全性更高

32:cookie和session有什么聯(lián)系和區(qū)別

cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。
session比cookie更安全
單個(gè)cookie保存的數(shù)據(jù)不能超過4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。
一般用cookie來存儲(chǔ)sessionid

33:判斷鏈表是否有環(huán)

使用追趕的方法,設(shè)定兩個(gè)指針slow、fast,從頭指針開始,每次分別前進(jìn)1步、2步。如存在環(huán),則兩者相遇;如不存在環(huán),fast遇到NULL退出。

34:輸出二叉樹的最小深度

判斷左子樹或右子樹是否為空,若左子樹為空,則返回右子樹的深度,反之返回左子樹的深度,如果都不為空,則返回左子樹和右子樹深度的最小值。

35: javaScript中的this是什么,有什么用,它的指向是什么

全局代碼中的this 是指向全局對象
作為對象的方法調(diào)用時(shí)指向調(diào)用這個(gè)函數(shù)的對象。
作為構(gòu)造函數(shù)指向新創(chuàng)建的對象
使用apply和call設(shè)置this

36:寫一個(gè)快速排序

var quickSort = function (arr){
        if(arr.lenght <= 1) {
           return arr;
          }

       var left = [];
       var right = [];
       var mid = arr.splice(Math.floor(arr.length/2), 1);

       for(var i=0;i<arr.length;i++){
             if(arr[i]<mid) {
                 left.push(arr[i]);
            }
             if(arr[i]>mid) {
                 right.push(arr[i]);
            }
          return quickSort(left).concat(mid, quickSort(right));
     }  
}  

37怎么實(shí)現(xiàn)從一個(gè)DIV左上角到右下角的移動(dòng),有哪些方法,都怎么實(shí)現(xiàn)

改變left值為window寬度-div寬度 top值為window高度-div高度
jquery的animate方法
css3的transition

38: 簡單介紹一下promise,他解決了什么問題

Promise,就是一個(gè)對象,用來傳遞異步操作的消息。有三種狀態(tài):
Pending(進(jìn)行中)、Resolved(已完成,又稱 Fulfilled)和 Rejected(已失?。?。
有了 Promise 對象,就可以將異步操作以同步操作的流程表達(dá)出來,避免了層層嵌套的回調(diào)函數(shù)。

39: 寫一個(gè)組合繼承

var Super = function(name){
  this.name = name;
}
Super.prototype.func1 = function() { console.log('func1'); }
var Sub = function(name,age) {
  Super.call(this, name);
  this.age = age;
}
Sub.prototype = new Super();

40:深拷貝方案有哪些,手寫一個(gè)深拷貝

var clone = function(v) {
  var o = v.constructor === Array ? [] : {};
  for (var i in v) {
    o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i];
  }
  return o;
}

41:判斷數(shù)組有哪些方法

a instanceof Array
a.constructor == Array
Object.prototype.toString.call(a) == [Object Array]

42: 跨域通信有哪些方案,各有什么不同

JSONP:由于同源策略的限制,XmlHttpRequest只允許請求當(dāng)前源,script標(biāo)簽沒有同源限制
通過動(dòng)態(tài)<script>元素使用,使用時(shí)為src指定一個(gè)跨域url。回調(diào)函數(shù)處理JSON數(shù)據(jù) 兼容性好 不支持post
簡述原理與過程:首先在客戶端注冊一個(gè)callback, 然后把callback的名字傳給服務(wù)器。此時(shí),服務(wù)器先生成一個(gè)function , function 名字就是傳遞上來的參數(shù)。最后將 json 數(shù)據(jù)直接以入?yún)⒌姆绞?,放置?function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端??蛻舳藶g覽器,解析script標(biāo)簽,并執(zhí)行返回的 javascript 文檔,此時(shí)數(shù)據(jù)作為參數(shù),傳入到了客戶端預(yù)先定義好的 callback 函數(shù)里

<script> 
    var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction";  
    var script = document.createElement('script');  
    script.setAttribute('src', url);  //load javascript   
    document.getElementsByTagName('head')[0].appendChild(script);  

  //回調(diào)函數(shù) 
    function callbackfunction(data){ 
        var html=JSON.stringify(data.RESULTSET); 
alert(html); 
     } 
</script> 

cors:通過設(shè)置Access-Control-Allow-Origin來允許跨域 cors可用ajax發(fā)請求獲取數(shù)據(jù) 但是兼容性沒有jsonp好

43:多頁面通信有哪些方案,各有什么不同

localstorge在一個(gè)標(biāo)簽頁里被添加、修改或刪除時(shí),都會(huì)觸發(fā)一個(gè)storage事件,通過在另一個(gè)標(biāo)簽頁里監(jiān)聽storage事件,即可得到localstorge存儲(chǔ)的值,實(shí)現(xiàn)不同標(biāo)簽頁之間的通信。
settimeout+cookie

44:用Node實(shí)現(xiàn)一個(gè)用戶上傳文件的后臺(tái)服務(wù)應(yīng)該怎么做

multer模塊

45: XSS和CSRF攻擊

xss:比如在一個(gè)論壇發(fā)帖中發(fā)布一段惡意的JavaScript代碼就是腳本注入,如果這個(gè)代碼內(nèi)容有請求外部服務(wù)器,那么就叫做XSS
寫一個(gè)腳本將cookie發(fā)送到外部服務(wù)器這就是xss攻擊但是沒有發(fā)生csrf
防范:對輸入內(nèi)容做格式檢查 輸出的內(nèi)容進(jìn)行過濾或者轉(zhuǎn)譯
CSRF:又稱XSRF,冒充用戶發(fā)起請求(在用戶不知情的情況下),完成一些違背用戶意愿的請求 如惡意發(fā)帖,刪帖
比如在論壇發(fā)了一個(gè)刪帖的api鏈接 用戶點(diǎn)擊鏈接后把自己文章給刪了 這里就是csrf攻擊沒有發(fā)生xss
防范:驗(yàn)證碼 token 來源檢測

46:圣杯布局和雙飛翼布局

【圣杯布局】
html代碼中 middle部分首先要放在container的最前部分。然后是left,right
1.將三者都 float:left , 再加上一個(gè)position:relative (因?yàn)橄鄬Χㄎ缓竺鏁?huì)用到)
2.middle部分 width:100%占滿
3.此時(shí)middle占滿了,所以要把left拉到最左邊,使用margin-left:-100%
4.這時(shí)left拉回來了,但會(huì)覆蓋middle內(nèi)容的左端,要把middle內(nèi)容拉出來,所以在外圍container加上 padding:0 220px 0 200px
5.middle內(nèi)容拉回來了,但left也跟著過來了,所以要還原,就對left使用相對定位 left:-200px 同理,right也要相對定位還原 right:-220px
6.到這里大概就自適應(yīng)好了。如果想container高度保持一致可以給left middle right都加上min-height:130px

【雙飛翼布局】
前幾步都一樣 后邊把外圍padding和相對定位做法換成內(nèi)層margin
給middle增加一個(gè)內(nèi)層div-- middle-inner, 然后margin:0 220px 0 200px

47:offsetHeight, scrollHeight, clientHeight分別代表什么

clientHeight:包括內(nèi)容可見部分的高度,可見的padding;不包括border,水平方向的scrollbar,margin。
offsetHeight:包括內(nèi)容可見部分的高度,border,可見的padding,水平方向的scrollbar(如果存在);不包括margin。
scrollHeight:包括內(nèi)容的高度(可見與不可見),padding(可見與不可見);不包括border,margin。

48:垂直居中

單行行內(nèi)元素 1.可以設(shè)置padding-top,padding-bottom 2.將height和line-height設(shè)為相等
多行行內(nèi)元素 1.可以將元素轉(zhuǎn)為table樣式,再設(shè)置vertical-align:middle; 2.使用flex布局

塊級元素
已知高度絕對定位負(fù)邊距
未知高度transform: translateY(-50%);

flex布局
display: flex;
justify-content: center;
align-items: center;

49:transition的屬性值和應(yīng)用

屬性的名稱 過渡時(shí)間 時(shí)間曲線 延遲

50:rem和em的區(qū)別

em相對于父元素,rem相對于根元素

51:嚴(yán)格模式的特性

嚴(yán)格模式對Javascript的語法和行為,都做了一些改變。
全局變量必須顯式聲明。
對象不能有重名的屬性
函數(shù)必須聲明在頂層
消除Javascript語法的一些不合理、不嚴(yán)謹(jǐn)之處,減少一些怪異行為;
消除代碼運(yùn)行的一些不安全之處,保證代碼運(yùn)行的安全;
提高編譯器效率,增加運(yùn)行速度;
為未來新版本的Javascript做好鋪墊。

52:js的原型鏈,如何實(shí)現(xiàn)繼承?

function foo(){}
foo.prototype.z = 3;
var obj = new foo();
obj.x=1;
obj.y=2;
obj.x //1
obj.y //2
obj.z //3

53:圖片預(yù)加載和懶加載

預(yù)加載:

function loadImage(url, callback) {
    var img = new Image();
    img.src = url;
    if (img.complete) { // 如果圖片已經(jīng)存在于瀏覽器緩存,直接調(diào)用回調(diào)函數(shù) 防止IE6不執(zhí)行onload BUG
        callback.call(img);
        return;
    }
    img.onload = function () {
        callback.call(img);//將回調(diào)函數(shù)的this替換為Image對象
    };
};

懶加載:

當(dāng)網(wǎng)頁滾動(dòng)的事件被觸發(fā) -> 執(zhí)行加載圖片操作 -> 判斷圖片是否在可視區(qū)域內(nèi) -> 在,則動(dòng)態(tài)將data-src的值賦予該圖片。

<script>
    var aImages = document.getElementById("SB").getElementsByTagName('img'); //獲取id為SB的文檔內(nèi)所有的圖片
    loadImg(aImages);
    window.onscroll = function () { //滾動(dòng)條滾動(dòng)觸發(fā)
        loadImg(aImages);
    };

    //getBoundingClientRect 是圖片懶加載的核心
    function loadImg(arr) {
        for (var i = 0, len = arr.length; i < len; i++) {
            if (arr[i].getBoundingClientRect().top < document.documentElement.clientHeight && !arr[i].isLoad) {
                arr[i].isLoad = true; //圖片顯示標(biāo)志位
                //arr[i].style.cssText = "opacity: 0;";
                (function (i) {
                    setTimeout(function () {
                        if (arr[i].dataset) { //兼容不支持data的瀏覽器
                            aftLoadImg(arr[i], arr[i].dataset.imgurl);
                        } else {
                            aftLoadImg(arr[i], arr[i].getAttribute("data-imgurl"));
                        }
                        arr[i].style.cssText = "transition: 1s; opacity: 1;" //相當(dāng)于fadein
                    }, 500)
                })(i);
            }
        }
    }

    function aftLoadImg(obj, url) {
        var oImg = new Image();
        oImg.onload = function () {
            obj.src = oImg.src; //下載完成后將該圖片賦給目標(biāo)obj目標(biāo)對象
        }
        oImg.src = url; //oImg對象先下載該圖像
    }
</script>

54.輸入網(wǎng)址后到頁面展現(xiàn)的過程

通過dns解析獲取ip
tcp鏈接
客戶端發(fā)送http請求
tcp傳輸報(bào)文
服務(wù)器處理請求返回http報(bào)文
客戶端解析渲染頁面 (構(gòu)建DOM樹 –> 構(gòu)建渲染樹 –> 布局渲染樹:計(jì)算盒模型位置和大小 –> 繪制渲染樹)

55:UMD規(guī)范和ES6模塊化,Commonjs的對比

CommonJS是一個(gè)更偏向于服務(wù)器端的規(guī)范。用于NodeJS 是同步的
AMD是依賴前置的
CMD推崇依賴就近,延遲執(zhí)行??梢园涯愕囊蕾噷戇M(jìn)代碼的任意一行
AMD和CMD都是用difine和require,但是CMD標(biāo)準(zhǔn)傾向于在使用過程中提出依賴,就是不管代碼寫到哪突然發(fā)現(xiàn)需要依賴另一個(gè)模塊,那就在當(dāng)前代碼用require引入就可以了,規(guī)范會(huì)幫你搞定預(yù)加載,你隨便寫就可以了。但是AMD標(biāo)準(zhǔn)讓你必須提前在頭部依賴參數(shù)部分寫好(沒有寫好? 倒回去寫好咯)。這就是最明顯的區(qū)別。
UMD寫一個(gè)文件需要兼容不同的加載規(guī)范
ES6通過import、export實(shí)現(xiàn)模塊的輸入輸出。其中import命令用于輸入其他模塊提供的功能,export命令用于規(guī)定模塊的對外接口。

56:http請求頭

get post delete put head options trace connect
OPTIONS:返回服務(wù)器針對特定資源所支持的HTTP請求方法

57:nginx的好處?和node的比較

高并發(fā) 響應(yīng)快
區(qū)別不是很大,一個(gè)更專業(yè),一個(gè)更全面:
1.相似點(diǎn):
1.1異步非阻塞I/O, 事件驅(qū)動(dòng);
2.不同點(diǎn):
2.1Nginx 采用C編寫,更性能更高,但是它僅適合于做web服務(wù)器,用于反向代理或者負(fù)載均衡等服務(wù);Nginx背后的業(yè)務(wù)層編程思路很還是同步編程方式,例如PHP.
2.2NodeJs高性能平臺(tái),web服務(wù)只是其中一塊,NodeJs在處理業(yè)務(wù)層用的是JS編寫,采用的是異步編程方式和思維方式。

58.框架問題

什么是 MVVM , 和 MVC 是什么區(qū)別, 原理是什么?
  mvc的界面和邏輯關(guān)聯(lián)緊密,數(shù)據(jù)直接從數(shù)據(jù)庫讀取,必須通過Controller來承上啟下,通信都是單向的。mvvm的View 和 ViewModel可以互相通信,界面數(shù)據(jù)從viewmodel中獲取。

父子組件怎么通信的?
  vue:父組件是通過props屬性給子組件通信 在子組件里面emit,在父組件監(jiān)聽
  react:props傳遞 父給子傳一個(gè)回調(diào)函數(shù) 將數(shù)據(jù)傳給父親處理

兄弟組件怎么通信的?
  vuex 建立一個(gè)vue實(shí)例 emit觸發(fā)事件 on監(jiān)聽事件
  redux 子A -> 父 -> 子B

生命周期有哪些, 怎么用?
  beforecreated:el 和 data 并未初始化
  created:完成了 data 數(shù)據(jù)的初始化,el沒有
  beforeMount:完成了 el 和 data 初始化
  mounted :完成掛載  updated;destroyed
  react:初始化階段、運(yùn)行中階段、銷毀階段
  初始化getDefaultProps()和getInitialState()初始化
componentWillMount() 在組件即將被渲染到頁面
  render() 組件渲染
componentDidMount() 組件被渲染到頁面上,
  運(yùn)行中shouldComponentUpdate() componentWillUpdate() render() componentDidUpdate()
  銷毀componentWillUnmount()

59:清除浮動(dòng)
兩種原理:

1、利用clear屬性進(jìn)行清理
具體的實(shí)現(xiàn)原理是通過引入清除區(qū)域,這個(gè)相當(dāng)于加了一塊看不見的框把定義clear屬性的元素向下擠
父容器結(jié)尾插入空標(biāo)簽<div style="clear: both;"></div>
利用CSS偽元素:

.clearfix:after {
  content: ".";
  height: 0;
  visibility: hidden;
  display: block;
  clear: both;
}

通過將這個(gè)類添加到父容器當(dāng)中,會(huì)在父容器的末尾增加了一個(gè)高度為0、具有清除屬性的、不可見的塊級元素。

2、將父容器形成BFC
BFC能清理浮動(dòng)主要運(yùn)用的是它的布局規(guī)則:
內(nèi)部的Box會(huì)在垂直方向,一個(gè)接一個(gè)地放置。
Box垂直方向的距離由margin決定。屬于同一個(gè)BFC的兩個(gè)相鄰Box的margin會(huì)發(fā)生重疊
每個(gè)元素的margin box的左邊, 與包含塊border box的左邊相接觸(對于從左往右的格式化,否則相反)。即使存在浮動(dòng)也是如此。
BFC的區(qū)域不會(huì)與float box重疊。
BFC就是頁面上的一個(gè)隔離的獨(dú)立容器,容器里面的子元素不會(huì)影響到外面的元素。反之也如此。
計(jì)算BFC的高度時(shí),浮動(dòng)元素也參與計(jì)算
浮動(dòng)清理利用的主要是第六條規(guī)則,只要將父容器觸發(fā)為BFC,就可以實(shí)現(xiàn)包含的效果。

那么觸發(fā)BFC有哪幾種方法?
根元素
float屬性不為none
position為absolute或fixed
display為inline-block, table-cell, table-caption, flex, inline-flex
overflow不為visible

60.前端性能優(yōu)化

1.減少http請求 使用sprite圖、合并js和css文件
2.使用cdn 將用戶安排在近的服務(wù)器上
3.使用緩存 緩存ajax 使用外部的css和js以便緩存 使用expire cach-control etag
4.壓縮資源 使用gzip壓縮js和css文件
5.代碼層面 避免使用樣式表達(dá)式、通配符選擇器、樣式放在頂部、腳本放在底部

61.事件模型和事件代理

事件三個(gè)階段:事件捕獲,目標(biāo),事件冒泡(低版本ie不支持捕獲階段)
w3c綁定事件target.addEventListener(event,handler,false)
解綁target.removeEventListener(eventType, handler, false)
ie綁定 target.attachEvent(on+event, handler)
解綁target.detachEvent("on"+eventType, handler)

事件代理優(yōu)點(diǎn):
可以大量節(jié)省內(nèi)存占用,減少事件注冊,比如在table上代理所有td的click事件就非常棒
可以實(shí)現(xiàn)當(dāng)新增子對象時(shí)無需再次對其綁定事件,對于動(dòng)態(tài)內(nèi)容部分尤為合適

bind和trigger實(shí)現(xiàn):
創(chuàng)建一個(gè)類或是匿名函數(shù),在bind和trigger函數(shù)外層作用域創(chuàng)建一個(gè)字典對象,用于存儲(chǔ)注冊的事件及響應(yīng)函數(shù)列表,bind時(shí),如果字典沒有則創(chuàng)建一個(gè),key是事件名稱,value是數(shù)組,里面放著當(dāng)前注冊的響應(yīng)函數(shù),如果字段中有,那么就直接push到數(shù)組即可。trigger時(shí)調(diào)出來依次觸發(fā)事件響應(yīng)函數(shù)即可。

function Emitter() {
    this._listener = [];//_listener[自定義的事件名] = [所用執(zhí)行的匿名函數(shù)1, 所用執(zhí)行的匿名函數(shù)2]
}

//注冊事件
Emitter.prototype.bind = function(eventName, callback) {
    var listener = this._listener[eventName] || [];//this._listener[eventName]沒有值則將listener定義為[](數(shù)組)。
    listener.push(callback);
    this._listener[eventName] = listener;
}

 //觸發(fā)事件
Emitter.prototype.trigger = function(eventName) {
    var args = Array.prototype.slice.apply(arguments).slice(1);//atgs為獲得除了eventName后面的參數(shù)(注冊事件的參數(shù))
    var listener = this._listener[eventName];

    if(!Array.isArray(listener)) return;//自定義事件名不存在
    listener.forEach(function(callback) {
        try {
            callback.apply(this, args);
        }catch(e) {
            console.error(e);
        }
    })
}

62.將url的查詢參數(shù)解析成字典對象

function getQueryObject(url) {
    url = url == null ? window.location.href : url;
    var search = url.substring(url.lastIndexOf("?") + 1);
    var obj = {};
    var reg = /([^?&=]+)=([^?&=]*)/g;
    search.replace(reg, function (rs, $1, $2) {
        var name = decodeURIComponent($1);
        var val = decodeURIComponent($2);              
        val = String(val);
        obj[name] = val;
        return rs;
    });
    return obj;
}

getQueryObject("http://www.cnblogs.com/leee/p/4456840.html?name=1&dd=ddd**")
Object {name: "1", dd: "ddd**"}

63.position的值, relative和absolute分別是相對于誰進(jìn)行定位的?

<1>、relative:相對定位,相對于自己本身在正常文檔流中的位置進(jìn)行定位。
<2>、absolute:生成絕對定位,相對于最近一級定位不為static的父元素進(jìn)行定位。
<3>、fixed: 生成絕對定位,相對于瀏覽器窗口或者frame進(jìn)行定位。
<4>、static:默認(rèn)值,沒有定位,元素出現(xiàn)在正常的文檔流中。
<5>、sticky:生成粘性定位的元素,容器的位置根據(jù)正常文檔流計(jì)算得出。

64.position:absolute和float屬性的異同?

共同點(diǎn):對內(nèi)聯(lián)元素設(shè)置float和absolute屬性,可以讓元素脫離文檔流,并且可以設(shè)置其寬高。
不同點(diǎn):float仍可占據(jù)位置,不會(huì)覆蓋在另一個(gè)BFC區(qū)域上,浮動(dòng)的框可以向左或向右移動(dòng),直到它的外邊緣碰到包含框或另一個(gè)浮動(dòng)框的邊框?yàn)橹?。absolute會(huì)覆蓋文檔流中的其他元素。

65.CSS 選擇符有哪些?哪些屬性可以繼承?優(yōu)先級算法如何計(jì)算? CSS3新增偽類有那些?

選擇符:
<1>、id選擇器(#myId);
<2>、類選擇器(.myClassName);
<3>、標(biāo)簽選擇器(div,p,h1);
<4>、相鄰選擇器(h1 + p);
<5>、子選擇器(ul > li);
<6>、后代選擇器(li a);
<7>、通配符選擇器(*);
<8>、屬性選擇器(button[disabled="true"]);
<9>、偽類選擇器(a:hover,li:nth-child);表示一種狀態(tài)
<10>、偽元素選擇器(li:before、:after,:first-letter,:first-line,:selecton);表示文檔某個(gè)部分的表現(xiàn)

優(yōu)先級:
!important > 行內(nèi)樣式(比重1000) > id(比重100) > class/屬性(比重10) > tag / 偽類(比重1);

偽類和偽元素區(qū)別:
1>、偽類:a:hover,li:nth-child;
2>、偽元素:li:before、:after,:first-letter,:first-line,:selecton;

65.兩個(gè)數(shù)組合并成一個(gè)數(shù)組排序返回

先依次比較兩個(gè)數(shù)組,按照小的就傳入新的數(shù)組。當(dāng)這次比較完之后可能有一個(gè)數(shù)組的長度很長,留下一些數(shù)組,然后在新數(shù)組的末尾插入即可。

<script>
    functiongetRes(arr1, arr2){
       var len1 = arr1.length,
           len2 = arr2.length,
           i = 0,
           j = 0,
           k = 0,
           res = new Array(len1+len2);

           while(i < len1 && j <len2){
                res[k++] = arr[(arr[i] > arr[j]) ? j++ : i++];
            }
            While(i < len1)   res[k++]= arr1[i++];
            While(j < len2)   res[k++]= arr2[j++];
            Return res;
    }
</script>

66.zepto和jquery區(qū)別

zepto比jquery體積小很多,移動(dòng)端的兼容性不需要要考慮很多,jquery中的很多功能都沒有。
width()和height()不一樣 解決用.css('width')

67.css3動(dòng)畫和jquery動(dòng)畫的差別

1.css3中的過渡和animation動(dòng)畫都是基于css實(shí)現(xiàn)機(jī)制的,屬于css范疇之內(nèi),并沒有涉及到任何語言操作。效率略高與jQuery中的animate()函數(shù),但兼容性很差。
2.jQuery中的animate()函數(shù)可以簡單的理解為css樣式的“逐幀動(dòng)畫”,是css樣式不同狀態(tài)的快速切換的結(jié)果。效率略低于css3動(dòng)畫執(zhí)行效率,但是兼容性好。?

68.如何解決ajax無法后退的問題

HTML5里引入了新的API,即:history.pushState, history.replaceState
可以通過pushState和replaceState接口操作瀏覽器歷史,并且改變當(dāng)前頁面的URL。
onpopstate監(jiān)聽后退

69.實(shí)現(xiàn)一個(gè)once函數(shù)

<script>
    function test () {console.log('test')}

        var once = function (fn) {
          var isFirst = true;
          return function () {
            if (isFirst) {
              isFirst = !isFirst;
              fn();
            }
          };
    };

    var b = once(test);
    b(); // 'test'
    b(); // nothing
</script>

70.分域名請求圖片的原因和好處

瀏覽器的并發(fā)請求數(shù)目限制是針對同一域名的,超過限制數(shù)目的請求會(huì)被阻塞
瀏覽器并發(fā)請求有個(gè)數(shù)限制,分域名可以同時(shí)并發(fā)請求大量圖片

71.頁面的加載順序

html順序加載,其中js會(huì)阻塞后續(xù)dom和資源的加載,css不會(huì)阻塞dom和資源的加載但是會(huì)阻塞js的加載。
瀏覽器會(huì)使用prefetch對引用的資源提前下載
1.沒有 defer 或 async,瀏覽器會(huì)立即加載并執(zhí)行指定的腳本
2.有 async,加載和渲染后續(xù)文檔元素的過程將和 script.js 的加載與執(zhí)行并行進(jìn)行(下載異步,執(zhí)行同步,加載完就執(zhí)行)。
3.有 defer,加載后續(xù)文檔元素的過程將和 script.js 的加載并行進(jìn)行(異步),但是 script.js 的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成。

72.生成10個(gè)20-50之間的隨機(jī)數(shù),存在數(shù)組中,常見排序方法,數(shù)組亂序方法

var arr = [];
for(var i = 0;i<10;i++){
    var num = Math.random()*30 + 20;
    num = parseInt(num, 10);
    arr.push(num);
}

arr.sort(function(a,b){
    return 0.5 - Math.random();
})

73.計(jì)算機(jī)網(wǎng)絡(luò)的分層概述

tcp/ip模型:從下往上分別是鏈路層,網(wǎng)絡(luò)層,傳輸層,應(yīng)用層
osi模型:從下往上分別是物理層,鏈路層,網(wǎng)絡(luò)層,傳輸層,會(huì)話層,表示層,應(yīng)用層。

73.jscss緩存問題

瀏覽器緩存的意義在于提高了執(zhí)行效率,但是也隨之而來帶來了一些問題,導(dǎo)致修改了js、css,客戶端不能更新
都加上了一個(gè)時(shí)間戳作為版本號
<script type=”text/javascript” src=”{JS文件連接地址}?version=XXXXXXXX”></script>

74.setTimeout,setInterval,requestAnimationFrame之間的區(qū)別

setInterval如果函數(shù)執(zhí)行的時(shí)間很長的話,第二次的函數(shù)會(huì)放到隊(duì)列中,等函數(shù)執(zhí)行完再執(zhí)行第二次,導(dǎo)致時(shí)間間隔發(fā)生錯(cuò)誤。
而settimeout一定是在這個(gè)時(shí)間定時(shí)結(jié)束之后,它才會(huì)執(zhí)行
requestAnimationFrame是為了做動(dòng)畫專用的一個(gè)方法,這種方法對于dom節(jié)點(diǎn)的操作會(huì)比較頻繁。

75.webpack常用到哪些功能
>設(shè)置入口 設(shè)置輸出目 設(shè)置loader extract-text-webpack-plugin將css從js代碼中抽出并合并 處理圖片文字等功能 解析jsx解析bable

76.介紹sass

&定義變量 css嵌套 允許在代碼中使用算式 支持if判斷for循環(huán)

77.websocket和ajax輪詢

Websocket是HTML5中提出的新的協(xié)議,注意,這里是協(xié)議,可以實(shí)現(xiàn)客戶端與服務(wù)器端的通信,實(shí)現(xiàn)服務(wù)器的推送功能。
其優(yōu)點(diǎn)就是,只要建立一次連接,就可以連續(xù)不斷的得到服務(wù)器推送的消息,節(jié)省帶寬和服務(wù)器端的壓力。
ajax輪詢模擬長連接就是每個(gè)一段時(shí)間(0.5s)就向服務(wù)器發(fā)起ajax請求,查詢服務(wù)器端是否有數(shù)據(jù)更新
其缺點(diǎn)顯而易見,每次都要建立HTTP連接,即使需要傳輸?shù)臄?shù)據(jù)非常少,所以這樣很浪費(fèi)帶寬

78.tansition和margin的百分比根據(jù)什么計(jì)算

transition是相對于自身,margin相對于參照物

79.冒泡排序、快速排序、去重、查找字符串最多值

//冒泡排序
var bubbleSort = function(arr) {
   for (var i = 0; i < arr.length-1; i++) {
     for (var j = i+1; j < arr.length; j++) {
       if (arr[i]>arr[j]) {
         var temp = arr[i];
         arr[i] = arr[j];
         arr[j] = temp;
       }
     }
   }
   return arr;
};

//快速排序
var quickSort = function(arr) {
  if (arr.length <= 1) {
    return arr;
  }
  var len = arr.length;
  var midIndex = Math.floor(len/2);
  var mid = arr.splice(midIndex,1);
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] < mid) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat(mid,quickSort(right))
}

// 去重
 var distinct = function(arr) {
   var map = {};
   var result = [];
   for (var i = 0; i < arr.length; i++) {
      if (!map[arr[i]]) {
        map[arr[i]] = true;
        result.push(arr[i]);
      }
   }
   return result;
 }

//查找字符串中最多的值
var search = function(str) {
  var json = {};
  var max = 0;
  var char;
  for (var i = 0; i < str.length; i++) {
    if (!json[str[i]]) {
      json[str[i]]=1;
    } else {
      json[str[i]]++;
    }
  }
  console.log(json);
  for(var i in json){
        if(json[i]>max){
                max = json[i];
                char = i;
        }
}
  console.log(max, char);
}

80.函數(shù)組合繼承

原型繼承、構(gòu)造函數(shù)繼承、call aplly繼承

var Super = function(name){
  this.name = name;
}
Super.prototype.func1 = function() { console.log('func1'); }
var Sub = function(name,age) {
  Super.call(this, name);
  this.age = age;
}
Sub.prototype = new Super();

81.事件綁定

var addEvent = function(e, type, handler, capture ) {
  if (e.addEventListener) {
    e.addEventListener(type, handler, capture);
  } else if (e.attachEvent) {
    e.attachEvent('on'+type, handler);
  } else {
    e['on'+type] = handler;
  }
}

82.淺克隆和深度克隆

//淺克隆
function extendCopy(p) {
    var c = {};
    for (var i in p) {
      c[i] = p[i];
    }
    c.uber = p;
    return c;
 }

//深度克隆
var clone = function(v) {
  var o = v.constructor === Array ? [] : {};
  for (var i in v) {
    o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i];
  }
  return o;
}

83.實(shí)現(xiàn)一個(gè)秒針繞一點(diǎn)轉(zhuǎn)動(dòng)的效果

  animation: move 60s infinite steps(60); 
 /*設(shè)置旋轉(zhuǎn)的中心點(diǎn)為中間底部*/ 
  transform-origin: center bottom; 
/*旋轉(zhuǎn)從0度到360度*/ 
@keyframes move { 
    from { 
        transform: rotate(0deg); 
    } 
    to { 
        transform: rotate(360deg); 
    } 
} 

84.移動(dòng)端兼容問題

IOS移動(dòng)端click事件300ms的延遲響應(yīng)
一些情況下對非可點(diǎn)擊元素如(label,span)監(jiān)聽click事件,ios下不會(huì)觸發(fā),css增加cursor:pointer就搞定了

85.bootstrap的柵格系統(tǒng)如何實(shí)現(xiàn)的

box-sizing: border-box;
container row column設(shè)置百分比

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容