web前端面試寶典-基礎(chǔ)篇(三)

停更了基本上半年的時(shí)間了,今天繼續(xù)寫(xiě)這個(gè)面試的內(nèi)容吧。
今天從幾份我收藏的面試題開(kāi)始說(shuō)起把,如果這些面試題搞懂了,我感覺(jué)去參加BAT的面試還是可以搏一搏的。

1.1 有一個(gè)長(zhǎng)度未知的數(shù)組a,如果它的長(zhǎng)度為0就把數(shù)字1添加到數(shù)組里面,否則按照先進(jìn)先出的隊(duì)列規(guī)則讓第一個(gè)元素出列。(代碼量小于30個(gè)字)。

這個(gè)網(wǎng)上給出了明確的答案。這是對(duì)數(shù)組的隊(duì)列方法和棧方法,此題使用三元運(yùn)算符比較好。
答案: a.length === 0 ? a.push(1): a.shift();

1.2 防抖動(dòng)與節(jié)流

針對(duì)一些會(huì)頻繁觸發(fā)的事件如scroll、resize,如果正常綁定事件處理函數(shù)的話(huà),很可能在很短的時(shí)間內(nèi)多次連續(xù)觸發(fā)事件,非常影響性能。
因此針對(duì)此類(lèi)事件要進(jìn)行防抖動(dòng)或者節(jié)流處理。

它的做法就是限制下次函數(shù)調(diào)用之前必須等待的時(shí)間間隔。正確實(shí)現(xiàn)debouncing的方法是將若干個(gè)函數(shù)調(diào)用合成一次,并在給定事件過(guò)去之后僅被調(diào)用一次。

1.2.1 防抖動(dòng)

function debounce(fn, delay) {
  let timer = null;
  let context = this;
  let args = arguments;

  clearTimeout(timer);
  timer = setTimeout(function() {
    fn.apply(context, args);
  }, delay);
}

// 當(dāng)用戶(hù)滾動(dòng)時(shí)被調(diào)用的函數(shù)
function foo() {
  console.log("You are scrolling");
}

let elem = document.getElementById("container");
elem.addEventListener("click", debounce(f00, 2000));

  • 首先我們?yōu)閏lick事件綁定處理函數(shù)debounce,當(dāng)點(diǎn)擊時(shí)會(huì)立即調(diào)用,因此click事件觸發(fā)的是foo函數(shù)
  • 每一次事件被觸發(fā),都會(huì)清除當(dāng)前的timer然后重新設(shè)置超時(shí)調(diào)用。這就會(huì)導(dǎo)致每一次高頻事件都會(huì)取消前一次的超時(shí)調(diào)用,導(dǎo)致事件處理程序不能被觸發(fā)。
  • 只有當(dāng)高頻事件停止時(shí),最后一次事件觸發(fā)的超時(shí)調(diào)用才能在delay時(shí)間后執(zhí)行。

1.2.2 節(jié)流

節(jié)流是另一種處理類(lèi)似問(wèn)題的解決方法。節(jié)流函數(shù)允許在一個(gè)函數(shù)在規(guī)定的時(shí)間內(nèi)只執(zhí)行一次。它和防抖動(dòng)最大的區(qū)別是,節(jié)流函數(shù)不管事件觸發(fā)的有多頻繁,都會(huì)保證在規(guī)定時(shí)間內(nèi)一定會(huì)執(zhí)行一次真正的處理函數(shù)。
比如: 在頁(yè)面的無(wú)限加載的場(chǎng)景下,我們需要用戶(hù)滾動(dòng)頁(yè)面時(shí),每隔一段時(shí)間發(fā)一次Ajax請(qǐng)求,而不是在用戶(hù)停下滾動(dòng)頁(yè)面操作時(shí)采取請(qǐng)求數(shù)據(jù)。這樣的場(chǎng)景,就適合用節(jié)流閥技術(shù)來(lái)實(shí)現(xiàn)。
實(shí)現(xiàn)方式有兩種: 時(shí)間戳、定時(shí)器

  • 時(shí)間戳的實(shí)現(xiàn):
var throttle = function(func, delay) {
  var prev = Date.now();
  return function() {
    var context = this;
    var args = arguments;
    var now = Date.now();
    if(now->prev == delay) {
      func.apply(context, args);
      prev = Date.now();
    }
  }
}

當(dāng)高頻事件觸發(fā)時(shí),第一次應(yīng)該會(huì)立即執(zhí)行,而后再怎么高頻觸發(fā)事件,也都是每delay秒才會(huì)執(zhí)行一次。而當(dāng)最后一次事件觸發(fā)完畢后,事件也不會(huì)再被執(zhí)行了。

  • 定時(shí)器實(shí)現(xiàn):
    當(dāng)觸發(fā)事件的時(shí)候,我們?cè)O(shè)置一個(gè)定時(shí)器,再觸發(fā)事件的時(shí)候,如果定時(shí)器存在,就不執(zhí)行了,直到delay后,定時(shí)器執(zhí)行處理函數(shù),清空定時(shí)器,這樣就可以設(shè)置下一個(gè)定時(shí)器。
var throttle = functon(func, delay) {
  var timer = null;
  return function() {
    var context = this;
    var args = arguments;
    
    if(!timer) {
      timer = setTimeout(function() {
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  }
}

1.2.3 總結(jié)

其實(shí)上面的方式都可以進(jìn)行調(diào)整,看自己的思路了。防止一個(gè)事件頻繁觸發(fā)回調(diào)函數(shù)的方式:

  • 防抖動(dòng)
  • 節(jié)流

趁著一點(diǎn)時(shí)間更新幾道題目

1.3 浮動(dòng)為什么會(huì)造成高度塌陷?如何解決?

這個(gè)問(wèn)題其實(shí)很多面試題都會(huì)在問(wèn),其實(shí)就是這個(gè)知識(shí)點(diǎn),沒(méi)有太多的東西。好的,現(xiàn)在咱們先高清一些概念吧。

1.3.1 清除浮動(dòng)

清除對(duì)應(yīng)的單詞是 clear,對(duì)應(yīng)CSS中的屬性是 clear:left | right | both | none;代碼如下看效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .clearfix {
            clear: both;
            height: 0;
        }

        .demo1 {
            width: 300px;
            /*height: auto;*/
            border: 1px solid red;
        }

        .div1 {
            width: 100px;
            height: 100px;
            background: red;
            float: left;
        }

        .div2 {
            width: 100px;
            height: 100px;
            background: blue;
            float: right;
        }

        /**/
        .demo2 {
            width: 100px;
            height: 50px;
            background: yellow;
        }
    </style>
</head>
<body>
    <!-- 雖然下面清除了浮動(dòng),里面的元素依然不能將demo1的高度撐開(kāi) -->
    <div class="demo1">
        <div class="div1"></div>
        <div class="div2"></div>
    </div>
    <!-- 清除浮動(dòng) -->
    <div class="clearfix"></div>

    <!-- 上面清除浮動(dòng),下面的排列正常 -->
    <div class="demo2"></div>
</body>
</html>
效果圖1

1.3.2 閉合浮動(dòng)

更確切的含義是使浮動(dòng)元素閉合,從而減少浮動(dòng)帶來(lái)的影響。代碼如下,看相應(yīng)的效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .clearfix {
            clear: both;
            height: 0;
        }

        .demo1 {
            width: 300px;
            /*height: auto;*/
            border: 5px solid blue;
        }

        .div1 {
            width: 100px;
            height: 100px;
            background: red;
            float: left;
        }

        .div2 {
            width: 100px;
            height: 100px;
            background: blue;
            float: left;
        }

        .demo1::after {
            clear: both;
            content: "";
            display: block;
            height: 0;
        }

        /**/
        .demo2 {
            width: 100px;
            height: 50px;
            background: yellow;
        }
    </style>
</head>
<body>
    <!-- 雖然下面清除了浮動(dòng),里面的元素依然不能將demo1的高度撐開(kāi) -->
    <div class="demo1">
        <div class="div1"></div>
        <div class="div2"></div>
    </div>

    <!-- 上面清除浮動(dòng),下面的排列正常 -->
    <div class="demo2"></div>
</body>
</html>
效果圖2

1.3.3 總結(jié)

通過(guò)以上實(shí)例發(fā)現(xiàn),其實(shí)我們想要達(dá)到的效果更確切地說(shuō)是閉合浮動(dòng),而不是單純的清除浮動(dòng),雖然設(shè)置了新標(biāo)簽來(lái)清除浮動(dòng)但并不能解決wrap高度塌陷的問(wèn)題。

用閉合浮動(dòng)比清除浮動(dòng)更加嚴(yán)謹(jǐn),因此稱(chēng)之為:“閉合浮動(dòng)”會(huì)更加嚴(yán)謹(jǐn)。

1.3.3 為什么要閉合浮動(dòng)?

其實(shí)這個(gè)問(wèn)題很簡(jiǎn)單,是因?yàn)楦?dòng)會(huì)給你的布局帶來(lái)影響,否則閉合浮動(dòng)干什么?。。〔贿^(guò)還得需要認(rèn)識(shí)兩個(gè)概念,普通流和浮動(dòng)。
1)普通流:很多人或者文章稱(chēng)之為文檔流或者普通文檔流,其實(shí)標(biāo)準(zhǔn)里根本就沒(méi)有這個(gè)詞。如果把文檔流直譯為英文就是 document flow ,但標(biāo)準(zhǔn)里只有另一個(gè)詞,叫做 普通流或者稱(chēng)之為常規(guī)流。但似乎大家更習(xí)慣文檔流的稱(chēng)呼,因?yàn)楹芏嘀形姆g的書(shū)就是這么來(lái)的。比如《CSS Mastery》,英文原書(shū)中至始至終都只有普通流 normal flow(普通流) 這一詞,從來(lái)沒(méi)出現(xiàn)過(guò)document flow (文檔流)

2)浮動(dòng):浮動(dòng)的框可以左右移動(dòng),直至它的外邊緣遇到包含框或者另一個(gè)浮動(dòng)框的邊緣。浮動(dòng)框不屬于文檔中的普通流,當(dāng)一個(gè)元素浮動(dòng)之后,不會(huì)影響到塊級(jí)框的布局而只會(huì)影響內(nèi)聯(lián)框(通常是文本)的排列,文檔中的普通流就會(huì)表現(xiàn)得和浮動(dòng)框不存在一樣,當(dāng)浮動(dòng)框高度超出包含框的時(shí)候,也就會(huì)出現(xiàn)包含框不會(huì)自動(dòng)伸高來(lái)閉合浮動(dòng)元素(“高度塌陷”現(xiàn)象)。顧名思義,就是漂浮于普通流之上,像浮云一樣,但是只能左右浮動(dòng)。

正是因?yàn)楦?dòng)的這種特性,導(dǎo)致本屬于普通流中的元素浮動(dòng)之后,包含框內(nèi)部由于不存在其他普通流元素了,也就表現(xiàn)出高度為0(高度塌陷)。在實(shí)際布局中,往往這并不是我們所希望的,所以需要閉合浮動(dòng)元素,使其包含框表現(xiàn)出正常的高度。

1.3.4 最后就是怎么閉合浮動(dòng)和原理?

這個(gè)問(wèn)題之前咱們都已經(jīng)談?wù)撨^(guò)怎么閉合浮動(dòng)了,至于原理需要移步對(duì)BFC的了解。希望同學(xué)們可以自己去查詢(xún)。

1.4 img 3像素或者4像素的問(wèn)題?

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>img三像素問(wèn)題</title>
    <style>
        img {
            /*vertical-align: top;*/
        }
    </style>
</head>
<body>
    <div><img src="1.png" alt=""></div>
</body>
</html>

執(zhí)行結(jié)果如下:


執(zhí)行效果

1.4.1這是什么原因?

1.4.1

從圖中可以看到,baseline和bottom之間有一定的距離。實(shí)際上,inline的圖片下面空白正是baseline和bottom之間的這段距離。即使只有圖片沒(méi)有文字,只要是inline的圖片這段空白都會(huì)存在。
因此,想要去掉這段空白,最直接的方法是將圖片的vertical-align設(shè)置為其他的值。或者咱們知道top和bottom直接的距離就是line-height的高度,當(dāng)你設(shè)置外層div的行高為0時(shí),也就意味這baseline和bottom之間的距離為0,那么空白也就會(huì)消失了。因此代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>img三像素問(wèn)題</title>
    <style>
        div {
            /*解決方案一:在div上增加line-height:0*/
            /*line-height: 0;*/
        }

        img {
            /*解決方案二: 設(shè)置img的vertical-align為其他值*/
            vertical-align: middle;
        }
    </style>
</head>
<body>
    <div><img src="1.png" alt=""></div>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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