前端常见面试题(8.2)

本文涵盖了前端面试中的重点,包括三栏布局(圣杯、双飞翼、弹性)的实现,跨域请求的解决方案,事件绑定与事件委托的原理,原型链和闭包的概念,以及Ajax的工作机制。此外,还讨论了浏览器渲染的重绘与回流、宏任务与微任务机制、前端缓存策略以及HTTP与HTTPS的区别。
摘要由CSDN通过智能技术生成

三栏布局(圣杯、双飞翼、弹性)

二者都是三栏左右定宽中间自适应的典型布局

圣杯布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>圣杯布局</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .header,.footer{
            height: 32px;
            background: #444;
            width:100%;
            color: #eee;
            text-align: center;/*水平居中文字*/
            line-height: 32px;
            /* lin-height是为了垂直居中文字 */
        }
        .container{ 
            width: 100%;
            box-sizing: border-box;
            padding-left: 100px;
            padding-right: 200px;
            overflow: hidden;/*形成bfc,因为里面的div块都已经float了*/
        }
        .main{
            width: 100%;
            float: left;
            background-color: dimgray;
            min-height: 300px;
        }
        .left{
            float: left;
            width: 100px;
            background-color: aquamarine;
            margin-left: -100%;/*文档流向左移动一整行*/
            position: relative;
            left: -100px;
            min-height: 200px;
        }
        .right{
            float: left;
            width: 200px;
            background-color: coral;
            margin-left: -200px;/*文档流向左移动一个自己*/
            position: relative;
            left: 200px;
            min-height: 400px;
        }
    </style>
</head>
<body>
    <div class="header">头部</div>
    <div class="container">
        <div class="main">中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间</div>
        <div class="left">左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边</div>
        <div class="right">右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边</div>
    </div>
    <div class="footer">尾部</div>
</body>
</html>

image-20200802104750657

过程就是:

  1. 首先头部、正文、尾部上中下通过width:100%分开

  2. 正文设置怪异盒模型后给左右padding分别等于left和right的宽度

  3. 然后左边中间和正文都是左浮动,且中间放到最前面,中间宽度为100%

  4. 这时候第一行只有中间,左边和右边在第二行,正文的左右padding起到作用所以都有一段为空白

  5. 然后设置left的margin-left为-100%,让其文档流退一行退到中间内部的最左边,然后使用relative定位让他左移自己的宽度

  6. right部分只需要margin-left为其本身宽度,退到中间内部的最右侧,然后使用relative定位右移自己的宽度

双飞翼布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>圣杯布局</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .header,
        .footer {
            height: 32px;
            background: #444;
            width: 100%;
            color: #eee;
            text-align: center;
            /*水平居中文字*/
            line-height: 32px;
            /* lin-height是为了垂直居中文字 */
        }
        .container {
            width: 100%;
            overflow: hidden;
            /*形成bfc,因为里面的div块都已经float了*/
        }
        .left,.middle,.right{
            float: left;
        }
        .left{
            background-color:aquamarine;
            width: 100px;
            min-height: 200px;
            margin-left: -100%;
        }
        .right{
            background-color:coral;
            width: 200px;
            min-height: 400px;
            margin-left: -200px;
        }
        .middle{
            margin: 0 200px 0 100px;
        }
        .main{
            width: 100%;
            background-color: dimgray;
        }
    </style>
</head>

<body>
    <div class="header">头部</div>
    <div class="container">
        <div class="middle">
            <div class="main">中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间</div>
        </div>
        <div class="left">左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边</div>
        <div class="right">
            右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边</div>
    </div>
    <div class="footer">尾部</div>
</body>

</html>

image-20200802110916424

过程:

  1. 和圣杯相比,对于中间块要在外面套一个middle
  2. middle、left、right都进行左浮动
  3. 不需要container的padding,代替为middle的左右margin
  4. left直接margin-left为-100%
  5. right直接为margin-left为负的自身宽度

扩展一下:用flex弹性布局写三栏布局

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>弹性三栏布局</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .body{
            display: flex;
            flex-direction: column;
        }
        .header,
        .footer {
            height: 32px;
            background: #444;
            width: 100%;
            color: #eee;
            text-align: center;
            /*水平居中文字*/
            line-height: 32px;
            /* lin-height是为了垂直居中文字 */
        }
        .container {
            display: flex;

        }
        .left {
            background-color: aquamarine;
            width: 100px;
            min-height: 200px;
            order: -1;
        }
        .right {
            background-color: coral;
            width: 200px;
            min-height: 400px;
        }
        .main {
            flex: 1;
            background-color: dimgray;
        }
    </style>
</head>

<body>
    <div class="body">
        <div class="header">头部</div>
        <div class="container">
            <div class="main">中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间中间</div>
            <div class="left">左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边左边</div>
            <div class="right">
                右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边右边</div>
        </div>
        <div class="footer">尾部</div>
    </div>
</body>

</html>

image-20200802112318975

过程:

  1. 整体有三行,所以column模式把header、container、footer先布置好
  2. 然后container中有三列,直接用正常的flex模式
  3. 对于之前的left忘记变动位置,所以order要小一些这里用-1(如果布局上用left、main、right的顺序就不需要了)
  4. 之后设置felx:1的模式即可(grow为1 shrink为1 basic为0),用于占用剩余所有宽度

跨域请求的方法

跨域的原因:浏览器的同源策略,协议、域名、端口号都要一致

解决:

  1. jsonp,只能get
  2. 服务器代理
  3. cors后端设置响应头部
  4. iframe嵌套通信postmessage

事件绑定和事件委托

image-20200802151151773

image-20200802151244058

什么是原型链

实例对象函数都有_proto_,函数有prototype才可以new出新对象(箭头函数就不行)

img

什么是闭包

如果有一个函数,内部访问了外部的变量,就形成了闭包。这个访问了外部变量的函数被调用了,外部变量就不会被销毁

image-20200802152822771

例子中的times就会被newFn记住并且达成需求

Ajax

ajax是客户端异步请求数据并且动态更新内容无需重新加载的一种方式。

现在虽然有很多ajax的工具甚至已经有fetch这种html5新加入的异步获取ajax的方式

但是原生还是很重要的

//get请求
let xml
if(window.XMLHttpRequest){
    xml=new XMLHttpRequest()
}else{
    //兼容老版本
    xml=new ActiveObject("Microsoft.XML.HTTP")
}
xml.onreadystatechange=()=>{
    if(xml.readyState===4%%xml.status==200){
        console.log(xml.responseText)
    }
}
xml.open('get',url,true)
xml.send();

//post请求
let xml
if(window.XMLHttpRequest){
    xml=new XMLHttpRequest()
}else{
    //兼容老版本
    xml=new ActiveXObject("Microsoft.XML.HTTP")
}
xml.onreadystatechange=()=>{
    if(xml.readyState===4%%xml.status==200){
        console.log(xml.responseText)
    }
}
xml.open('post',url,true)
xml.send(data);

ajax的优点

  1. 交互性更好
  2. 减少与服务器的连接
  3. 状态可以维护到一个页面上,更改dom即可
  4. 基本上SPA单页面应用很支持

ajax的缺点

  1. 动态网页很难收藏
  2. 受限于js代码,如果被禁用则获取不了数据
  3. 不适合于搜索引擎优化SEO

原生ajax和fetch的区别:

  1. fetch更简单
  2. fetch无法取消请求,因为基于promise
  3. 默认情况下fetch不会接受和发送cookies
  4. fetch无法实时获取进度
  5. fetch只对网络请求报错,需要自己判断返回请求码
  6. fetch兼容性比不上XMLHttpRequest

cookie、loaclStorage、sessionStorage

image-20200802163134896

创建对象几种方式

image-20200802163432793

改变this指向

  1. bind、call、apply改变绑定
  2. 箭头函数没有自己的this,拿到父级上下文的this
  3. new新建实例对象,this指向对象

浏览器渲染的重绘和回流(重排)

html->dom,css->cssom

dom+cssom->render tree

重绘:由于节点的属性、样式变化不会影响布局的成为重绘,比如outline、visibility、color、baackground等触发的是重绘。重绘代价相比于回流还可以,是因为浏览器要分析其他节点的可见性。

回流:也称重排,表示布局发生变化,一定会触发重绘。代价更大,会导致其子节点和后面所有节点的回流

如何减少:

  1. 使用transform
  2. 使用visibility代替display:none
  3. 避免table布局
  4. 尽可能在最末端改变class
  5. 避免设置多层内联样式
  6. 将动画效果应用到absolute或者fixed的元素上
  7. 选择使用requestAnimationFrame执行动画
  8. 避免使用clac表达式
  9. 频繁重绘回流的节点设置为图层(will-change、video、iframe等)
  10. css3硬件加速(GPU加速),可以让transform、opacity、filter等动画不引起重绘
  11. js避免直接操作样式,最好通过class操作
  12. 避免频繁操作dom,尽量使用变量缓存节点
  13. 复杂的js操作dom的节点最好放在脱离文档流中

image-20200802164745745

浏览器和node的宏任务与微任务机制

浏览器中

微任务比如:promise的then回调、async的await的返回值等

浏览器中,有两个任务队列一个执行栈,在我们执行js代码的时候执行顺序是这样的

首先第一次在执行队列顺序执行一遍所有的宏任务(因为第一次js把整个script当成一个宏任务执行)

并且途中把所有的微任务加入到微任务队列

此时会执行所有的微任务并且把微任务所形成的宏任务都依次放到宏任务队列

在执行每个宏任务的同时把形成的微任务栈清空

node中

image-20200802170241802

image-20200802170431466

image-20200802170504855

emmm现在的node版本已经普遍12+了,除了nextTick基本上都能统一规范了

详细

image-20200802170848774

image-20200802170916103

image-20200802171026036

image-20200802171115122

image-20200802171411813

image-20200802171520151

image-20200802171541234

image-20200802171913281

这道题对于的顺序:

  1. 整体作为script代码一个宏任务逐行执行完毕,发现没有输出并且把第2-5行的代码加入到微任务队列,把8-11放入到宏任务队列。
  2. 由于setTimeout是宏任务所以在微任务的后面执行,所以这时候输出Promise1
  3. 并且把3-5行的setTimeout也追加到宏任务队列
  4. 微任务队列空,执行第一个宏任务,输出setTimeout1,并执行promiese,把then的部分加入到微任务队列
  5. 此时刚执行完宏任务,执行微任务输出Promise2
  6. 此时微任务队列空,执行最后一个宏任务,输出SetTimeout2
  7. 微任务空且宏任务空,事件循环结束

image-20200802172647801

image-20200802172838964

image-20200802173006214

image-20200802173047312

image-20200802173229164

image-20200802173548648

image-20200802173620703

image-20200802173800858

image-20200802174009183

image-20200802174054531

image-20200802174210211

image-20200802174406064

image-20200802174556832

浏览器缓存详解

image-20200802174826195

image-20200802174851842

image-20200802174948960

image-20200802175031833

image-20200802175230085

image-20200802175332030

image-20200802175516801

image-20200802175620094

image-20200802175858144

image-20200802180035936

image-20200802180202351

image-20200802180225067

image-20200802180319723

image-20200802180337616

image-20200802180513219

Token服务端身份验证方案

image-20200802180609400

image-20200802180644188

image-20200802180752715

image-20200802181118588

image-20200802181222370

image-20200802181331551

image-20200802181651622

image-20200802181720796

image-20200802181859581

前端与数据埋点

所谓埋点就是前端应用中手机的数据,比如访问数、访客数、停留时长、页面浏览数、跳出率等等,基本上就是页面统计和操作统计

image-20200802182322653

image-20200802182552555

创建img标签之后还要追加到dom中才能够发送请求

http和https的理解

image-20200802183757482

image-20200802183900236

image-20200802184219358

image-20200802184407287

image-20200802184732542

image-20200802184852696

image-20200802185003834

image-20200802185157081

image-20200802185350139

image-20200802185530495

image-20200802185635292

image-20200802185747582

image-20200802190333240

http数据接口防刷

image-20200802190530425

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值