阅读 58

前端的面试题(下)

7、手写函数防抖和函数节流

函数节流

函数节流是让这个函数在间隔某一段时间执行一次
以输入框为例,假设你想查询xxxx,你想实现当我开始输入多少秒之后,执行查询操作。(并不一定要输入完毕)
核心是去判断当前时间和开始时间的间隔是否到达了设置的delay值,如果达到了,就执行一次回调。没有则不执行。

函数防抖

让这个函数在执行上一次之后过了你规定的时间再执行的一种方法
核心在于每次都去clear一个延时器,然后每次执行函数的时候,都去clear以前的延时器。只有当你中断输入的时候,才会去执行相应回调。

function throttle(method,context){
  clearTimeout(method.tId)
  method.tId = setTimeout(function(){
    method.call(context) 
   },1000)
}

封装节流和防抖,通过第三参数来切换模式
const throttle = function(fn, delay, isDebounce) {
  let timer
  let lastCall = 0
  return function (...args) {
    if (isDebounce) {
      if (timer) clearTimeout(timer)
      timer = setTimeout(() => {
        fn(...args)
      }, delay)
    } else {
      const now = new Date().getTime()
      if (now - lastCall < delay) return
      lastCall = now
      fn(...args)
    }
  }
}

8、浏览器渲染过程

一图胜千言

image
  • 浏览器使用HTTP协议或者HTTPS协议,向服务端请求页面
  • 把请求回来的HTML代码经过解析,构建成DOM树
  • 计算DOM树上的CSS属性
  • 根据CSS属性对元素逐个渲染,得到内存中的位图
  • 中间可能包括对位图进行合成,极大地增加后续绘制的速度
  • 合成后,在绘制到界面上

9、回流重绘是什么?

HTML默认是流式布局的,但CSS和JS会打破这种布局,改变DOM的外观样式以及大小和位置。

reflow(回流)

当浏览器发现某个部分发生了变化从而影响了布局,这个时候就需要倒回去重新渲染
几乎是无法避免的,因为只要用户进行交互操作,就势必会发生页面的一部分的重新渲染,且通常我们也无法预估浏览器到底会reflow哪一部分的代码,因为他们会相互影响。

  • display:none是回流

减少回流的方式

  • 用transform做形变和位移.
  • 通过绝对位移来脱离当前层叠上下文,形成新的Render Layer。
repaint(重绘)

当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。

  • visibility: hidden是重绘

10、图片懒加载怎么实现的?

先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。

var viewheight = document.documentElement.clientHeight   //可视区域高度

function lazyload(){
    var eles = document.querySelectorAll('img[data-original][lazyload]')

    Array.prototype.forEach.call(eles,function(item,index){
        var rect;
        if(item.dataset.original === '') return;
        rect = item.getBoundingClientRect(); //返回元素的大小及其相对于视口的

        if(rect.bottom >= 0 && rect.top < viewheight){
            !function(){
                var img = new Image();
                img.src = item.dataset.url;
                img.onload = function(){
                    item.src = img.src
                }
                item.removeAttribute('data-original');
                item.removeAttribute('lazyload');
            }()
        }
    })
}

11、vue-lazyloader的原理

一图胜千言

image
  • vue-lazyload是通过指令的方式实现的,定义的指令是v-lazy指令
  • 指令被bind时会创建一个listener,并将其添加到listener queue里面, 并且搜索target dom节点,为其注册dom事件(如scroll事件)
  • 上面的dom事件回调中,会遍历 listener queue里的listener,判断此listener绑定的dom是否处于页面中perload的位置,如果处于则加载异步加载当前图片的资源
  • 同时listener会在当前图片加载的过程的loading,loaded,error三种状态触发当前dom渲染的函数,分别渲染三种状态下dom的内容

原文链接,很详细的源码解析:Vue-lazyload原理详解之源码解析

12、websocket握手过程

webstocket是html5的一种新的协议,是一个持久化的协议,相对于HTTP这种非持久的协议来说。它实现了浏览器与服务器的双向通道,使得数据可以快速的双向传播
通过一次简单的握手,建立了客户端和服务器的联系后,服务器可以主动推送信息给客户端,而不需要客户端的反复请求
优点

  • 客户端和服务器端之间数据交流的表头比较小。大概2个字节
  • 服务器和客户端可以主动的发送数据给对方
  • 不需要有频率的创建TCP请求和销毁,节约宽带和服务器的资源
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
// 一个Base64 encode的值,这个是浏览器随机生成的
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
// 一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议
Sec-WebSocket-Protocol: chat, superchat
// 告诉服务器所使用的Websocket Draft(协议版本)
Sec-WebSocket-Version: 13
Origin: http://example.com

服务器会返回下列东西

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
// 经过服务器确认,并且加密过后的 Sec-WebSocket-Key
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
// 表示最终使用的协议
Sec-WebSocket-Protocol: chat

表示已经接受到请求, 成功建立Websocket啦!

作者:前端阿峰

原文链接:https://www.jianshu.com/p/cbe96973a325

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐