1. 程式人生 > >2019春招前端面試預測題!

2019春招前端面試預測題!

使用css實現一個持續的動畫效果

1
2
3
4
5
animation:mymove 5s infinite;
@keyframes mymove {
from {top:0px;}
to {top:200px;}
}

主要考:animation 用法

描述
animation-name 規定需要繫結到選擇器的 keyframe 名稱。
animation-duration 規定完成動畫所花費的時間,以秒或毫秒計。
animation-timing-function 規定動畫的速度曲線。
animation-delay
規定在動畫開始之前的延遲。
animation-iteration-count 規定動畫應該播放的次數。
animation-direction 規定是否應該輪流反向播放動畫。

使用js實現一個持續的動畫效果

最開始的思路是用定時器實現,最後沒有想的太完整,面試官給出的答案是用requestAnimationFrame

  • 定時器思路
1
2
3
4
5
6
7
var e = document.getElementById('e')
var flag = true;
var left = 0;
setInterval(() => {
    left == 0 ? flag = true : left == 100 ? flag = false : ''
    flag ? e.style.left = ` ${left++}px` : e.style.left = ` ${left--}px`
}, 1000 / 60)
  • requestAnimationFrame
    由於之前沒有用過這個 API 所以是現學的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//相容性處理
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function(callback){
            window.setTimeout(callback, 1000 / 60);
          };
})();

var e = document.getElementById("e");
var flag = true;
var left = 0;

function render() {
    left == 0 ? flag = true : left == 100 ? flag = false : '';
    flag ? e.style.left = ` ${left++}px` :
        e.style.left = ` ${left--}px`;
}

(function animloop() {
    render();
    requestAnimFrame(animloop);
})();

不足之處請指正(畢竟是現學的)順便查了一下優勢:

  • 瀏覽器可以優化並行的動畫動作,更合理的重新排列動作序列,並把能夠合併的動作放在一個渲染週期內完成,從而呈現出更流暢的動畫效果
  • 解決毫秒的不精確性
  • 避免過度渲染(渲染頻率太高、tab 不可見暫停等等)
    注:requestAnimFrame 和 定時器一樣也頭一個類似的清除方法 cancelAnimationFrame

右邊寬度固定,左邊自適應

第一種:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
body{
    display: flex;
}
.left{
    background-color: rebeccapurple;
    height: 200px;
    flex: 1;
}
.right{
    background-color: red;
    height: 200px;
    width: 100px;
}
</style>
<body>
    <div class="left"></div>
    <div class="right"></div>
</body>

第二種

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style>
    div {
        height: 200px;
    }
    .left {
        float: right;
        width: 200px;
        background-color: rebeccapurple;
    }
    .right {
        margin-right: 200px;
        background-color: red;
    }
</style>
<body>
    <div class="left"></div>
    <div class="right"></div>
</body>

暫時想到了兩種。

水平垂直居中

第一種

1
2
3
4
5
6
7
8
9
10
11
12
#container{
    position:relative;
}

#center{
    width:100px;
    height:100px;
    position:absolute;
    top:50%;
    left:50%;
    transform: translate(-50%,-50%);
}

第二種

1
2
3
4
5
6
7
8
9
10
11
12
#container{
    position:relative;
}

#center{
    width:100px;
    height:100px;
    position:absolute;
    top:50%;
    left:50%;
    margin:-50px 0 0 -50px;
}

第三種

1
2
3
4
5
6
7
8
9
10
11
12
#container{
    position:relative;
}

#center{
    position:absolute;
    margin:auto;
    top:0;
    bottom:0;
    left:0;
    right:0;
}

第四種 flex

1
2
3
4
5
#container{
    display:flex;
    justify-content:center;
    align-items: center;
}

四種定位的區別

  • static 是預設值
  • relative 相對定位 相對於自身原有位置進行偏移,仍處於標準文件流中
  • absolute 絕對定位 相對於最近的已定位的祖先元素, 有已定位(指position不是static的元素)祖先元素, 以最近的祖先元素為參考標準。如果無已定位祖先元素, 以body元素為偏移參照基準, 完全脫離了標準文件流。
  • fixed 固定定位的元素會相對於視窗來定位,這意味著即便頁面滾動,它還是會停留在相同的位置。一個固定定位元素不會保留它原本在頁面應有的空隙。

Flex佈局用的多嗎?

因為專案考慮相容 IE9 所以直接說用的不多

移動端適配怎麼做的?

使用媒體查詢做的響應式佈局,根據不同螢幕寬度載入不同css.

let與var的區別?

let 為 ES6 新新增申明變數的命令,它類似於 var,但是有以下不同:

  • var 宣告的變數,其作用域為該語句所在的函式內,且存在變數提升現象
  • let 宣告的變數,其作用域為該語句所在的程式碼塊內,不存在變數提升
  • let 不允許重複宣告.

為什麼 var 可以重複宣告?(這個就不知道了)

當我們執行程式碼時,我們可以簡單的理解為新變數分配一塊兒記憶體,命名為a,並賦值為2,但在執行的時候編譯器與引擎還會進行兩項額外的操作:判斷變數是否已經宣告:

  • 首先編譯器對程式碼進行分析拆解,從左至右遇見var a,則編譯器會詢問作用域是否已經存在叫 a 的變量了,如果不存在,則招呼作用域宣告一個新的變數a,若已經存在,則忽略var 繼續向下編譯,這時a = 2被編譯成可執行的程式碼供引擎使用。
  • 引擎遇見a=2時同樣會詢問在當前的作用域下是否有變數a,若存在,則將a賦值為2(由於第一步編譯器忽略了重複宣告的var,且作用域中已經有a,所以重複宣告會發生值得覆蓋而並不會報錯)。若不存在,則順著作用域鏈向上查詢,若最終找到了變數a則將其賦值2,若沒有找到,則招呼作用域宣告一個變數a並賦值為2
    參考連結

封裝一個函式,引數是定時器的時間,.then執行回撥函式。

1
2
3
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

一個關於 this 指向的問題

差不多應該是這樣,記不太清了

1
2
3
4
5
6
7
8
9
10
11
12
obj = {
    name: 'a',
    getName : function () {
        console.log(this.name);
    }
}

var fn = obj.getName
obj.getName()
var fn2 = obj.getName()
fn()
fn2()

CommonJS 中的 require/exports 和 ES6 中的 import/export 區別?

  • CommonJS 模組的重要特性是載入時執行,即指令碼程式碼在 require 的時候,就會全部執行。一旦出現某個模組被”迴圈載入”,就只輸出已經執行的部分,還未執行的部分不會輸出。
  • ES6 模組是動態引用,如果使用 import 從一個模組載入變數,那些變數不會被快取,而是成為一個指向被載入模組的引用,需要開發者自己保證,真正取值的時候能夠取到值。
  • import/export 最終都是編譯為 require/exports 來執行的。
  • CommonJS 規範規定,每個模組內部,module 變數代表當前模組。這個變數是一個物件,它的 exports 屬性(即 module.exports )是對外的介面。載入某個模組,其實是載入該模組的 module.exports 屬性。
  • export 命令規定的是對外的介面,必須與模組內部的變數建立一一對應關係。

一行程式碼實現陣列去重?

1
[...new Set([1,2,3,1,'a',1,'a'])]

使用addEventListener點選li彈出內容,並且動態新增li之後有效

1
2
3
4
5
6
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>

這個題沒答出來