前端面试查漏补缺--(一) 防抖和节流
前言
本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家.
为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏,关注我!谢谢!
文章链接
- 前端面试查漏补缺--(一) 防抖和节流
- 前端面试查漏补缺--(二) 垃圾回收机制
- 前端面试查漏补缺--(三) 跨域及常见解决办法
- 前端面试查漏补缺--(四) 前端本地存储
- 前端面试查漏补缺--(五) 渲染机制及重绘和回流
- 前端面试查漏补缺--(六) 浏览器缓存
- 前端面试查漏补缺--(七) XSS攻击与CSRF攻击
- 前端面试查漏补缺--(八) 前端加密
- 前端面试查漏补缺--(九) HTTP与HTTPS
- 前端面试查漏补缺--(十) 前端鉴权
- 前端面试查漏补缺--(十一) 前端软件架构模式MVC/MVP/MVVM
- 前端面试查漏补缺--(十二) 从输入URL到看到页面发生的全过程(含三握手,四挥手详解)
- 前端面试查漏补缺--(十三) 内存泄漏
- 前端面试查漏补缺--(十四) 算法及排序
- 前端面试查漏补缺--(十五) Event Loop
合集篇:
前端面试查漏补缺--Index篇(12万字符合集) 包含目前已写好的系列其他十几篇文章.后续新增值文章不会再在每篇添加链接,强烈建议议点赞,关注合集篇!!!!,谢谢!~
后续更新计划
后续还会继续添加设计模式,前端工程化,项目流程,部署,闭环,vue常考知识点 等内容.如果觉得内容不错的话欢迎收藏,关注我!谢谢!
求一份内推
目前本人也在准备跳槽,希望各位大佬和HR小姐姐可以内推一份靠谱的武汉 前端岗位!邮箱:bupabuku@foxmail.com.谢谢啦!~
防抖和节流
相同:在不影响客户体验的前提下,将频繁的回调函数,进行次数缩减.避免大量计算导致的页面卡顿.
不同:防抖是将多次执行变为最后一次执行,节流是将多次执行变为在规定时间内只执行一次.
防抖
定义:
指触发事件后在规定时间内回调函数只能执行一次,如果在规定时间内又触发了该事件,则会重新开始算规定时间。
网上有这个比喻:函数防抖就是法师发技能的时候要读条,技能读条没完再按技能就会刷新技能,重新进行读条。
四个字总结就是 延时执行
应用场景:
两个条件:
1,如果客户连续的操作会导致频繁的事件回调(可能引起页面卡顿).
2,客户只关心"最后一次"操作(也可以理解为停止连续操作后)所返回的结果.
例如:
- 输入搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- 按钮点击:收藏,点赞,心标等
原理:
通过定时器将回调函数进行延时.如果在规定时间内继续回调,发现存在之前的定时器,则将该定时器清除,并重新设置定时器.这里有个细节,就是后面所有的回调函数都要能访问到之前设置的定时器,这时就需要用到闭包(详见后面提到的)
两种版本
防抖分为两种:
- 1)非立即执行版:事件触发->延时->执行回调函数;如果在延时中,继续触发事件,则会重新进行延时.在延时结束后执行回调函数.常见例子:就是input搜索框,客户输完过一会就会自动搜索
- 2)立即执行版:事件触发->执行回调函数->延时;如果在延时中,继续触发事件,则会重新进行延时.在延时结束后,并不会执行回调函数.常见例子:就是对于按钮防点击.例如点赞,心标,收藏等有立即反馈的按钮.
实现代码及思路:
//非立即执行版:
//首先准备我们要使用的回调函数
function shotCat (content) {console.log('shotCat出品,必属精品!必须点赞!(滑稽)')
}//然后准备包装函数:
//1,保存定时器标识
//2,返回闭包函数: 1)对定时器的判断清除;2)一般还需要保存函数的参数(一般就是事件返回的对象)和上下文(定时器存在this隐式丢失,详情可以看我不知道的js上)
//最后补充一句,这里不建议通过定义一个全局变量来替代闭包保存定时器标识.
function debounce(fun, delay = 500) {
//let timer = null 保存定时器return function (args) {let that = thislet _args = args//这里对定时器的设置有两种方法,第一种就是将定时器保存在函数(函数也是对象)的属性上,//这种写法,很简便,但不是很常用clearTimeout(fun.timer)fun.timer = setTimeout(function () {fun.call(that, _args)}, delay)//另外一种写法就是我们比较常见的//if (timer) clearTimeout(timer); 相比上面的方法,这里多一个判断//timer = setTimeout(function () {// fun.call(that, _args)//}, delay)}
}//接着用变量保存保存 debounce 返回的带有延时功能的函数
let debounceShotCat = debounce(shotCat, 500) //最后添加事件监听 回调debounceShotCat 并传入事件返回的对象
let input = document.getElementById('debounce')
input.addEventListener('keyup', function (e) {debounceShotCat(e.target.value)
})//带有立即执行选项的防抖函数:
//思路和上面的大致相同,如果是立即执行,则定时器中不再包含回调函数,而是在回调函数执行后,仅起到延时和重置定时器标识的作用
function debounce(fun, delay = 500,immediate = true) {let timer = null //保存定时器return function (args) {let that = thislet _args = argsif (timer) clearTimeout(timer); //不管是否立即执行都需要首先清空定时器if (immediate) {if ( !timer) fun.apply(that, _args) //如果定时器不存在,则说明延时已过,可以立即执行函数//不管上一个延时是否完成,都需要重置定时器timer = setTimeout(function(){timer = null; //到时间后,定时器自动设为null,不仅方便判断定时器状态还能避免内存泄露}, delay)}else {//如果是非立即执行版,则重新设定定时器,并将回调函数放入其中timer = setTimeout(function(){fun.call(that, _args)}, delay);}}
}复制代码
节流
定义:
当持续触发事件时,在规定时间段内只能调用一次回调函数。如果在规定时间内又触发了该事件,则什么也不做,也不会重置定时器.
与防抖比较:
防抖是将多次执行变为最后一次执行,节流是将多次执行变为在规定时间内只执行一次.一般不会重置定时器. 即不会if (timer) clearTimeout(timer);
(时间戳+定时器版除外)
应用场景:
两个条件:
1,客户连续频繁地触发事件
2,客户不再只关心"最后一次"操作后的结果反馈.而是在操作过程中持续的反馈.
例如:
- 鼠标不断点击触发,点击事件在规定时间内只触发一次(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
注意 :何为连续频繁地触发事件,就是事件触发的时间间隔至少是要比规定的时间要短.
原理:
节流有两种实现方式
- 时间戳方式:通过闭包保存上一次的时间戳,然后与事件触发的时间戳比较.如果大于规定时间,则执行回调.否则就什么都不处理.
- 特点:一般第一次会立即执行,之后连续频繁地触发事件,也是超过了规定时间才会执行一次。最后一次触发事件,也不会执行(说明:如果你最后一次触发时间大于规定时间,这样就算不上连续频繁触发了).
- 定时器方式:原理与防抖类似.通过闭包保存上一次定时器状态.然后事件触发时,如果定时器为null(即代表此时间隔已经大于规定时间),则设置新的定时器.到时间后执行回调函数,并将定时器置为null.
- 特点:当第一次触发事件时,不会立即执行函数,到了规定时间后才会执行。 之后连续频繁地触发事件,也是到了规定时间才会执行一次(因为定时器)。当最后一次停止触发后,由于定时器的延时,还会执行一次回调函数(那也是上一次成功成功触发执行的回调,而不是你最后一次触发产生的)。一句话总结就是延时回调,你能看到的回调都是上次成功触发产生的,而不是你此刻触发产生的.
- 说明: 这两者最大的区别:是时间戳版的函数触发是在规定时间开始的时候,而定时器版的函数触发是在规定时间结束的时候。 其他差异可以看我加粗的字. 具体理解请结合后面的代码实例,
实现代码及思路:
//时间戳版:
//这里fun指的就是回调函数,我就不写出来了
function throttle(fun, delay = 500) {let previous = 0; //记录上一次触发的时间戳.这里初始设为0,是为了确保第一次触发产生回调return function(args) {let now = Date.now(); //记录此刻触发时的时间戳let that = this;let _args = args;if (now - previous > delay) { //如果时间差大于规定时间,则触发fun.apply(that, _args);previous = now;}}
}//定时器版:
function throttle(fun, delay = 500) {let timer;return function(args) {let that = this;let _args = args;if (!timer) { //如果定时器不存在,则设置新的定时器,到时后,才执行回调,并将定时器设为nulltimer = setTimeout(function(){timer = null;fun.apply(that, _args)}, delay)}}
}//时间戳+定时器版: 实现第一次触发可以立即响应,结束触发后也能有响应 (该版才是最符合实际工作需求)
//该版主体思路还是时间戳版,定时器的作用仅仅是执行最后一次回调
function throttle(fun, delay = 500) {let timer = null;let previous = 0;return function(args) {let now = Date.now();let remaining = delay - (now - previous); //距离规定时间,还剩多少时间let that = this;let _args = args;clearTimeout(timer); //清除之前设置的定时器if (remaining <= 0) {fun.apply(that, _args);previous = Date.now();} else {timer = setTimeout(fun, remaining); //因为上面添加的clearTimeout.实际这个定时器只有最后一次才会执行}}
}复制代码
前端面试查漏补缺--(一) 防抖和节流相关推荐
- 前端面试查漏补缺--(二) 垃圾回收机制
前言 本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家. 为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏 ...
- 前端面试查漏补缺--(三) 跨域及常见解决办法
前言 本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家. 为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏 ...
- 前端面试查漏补缺--(十) 前端鉴权
前言 本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家. 为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏 ...
- 前端基础查漏补缺知识
一.JS基础 1. 如何在ES5环境下实现let 对于这个问题,我们可以直接查看babel转换前后的结果,看一下在循环中通过let定义的变量是如何解决变量提升的问题 babel在let定义的变量前加了 ...
- Java面试查漏补缺
一.基础 1.&和&&的区别. [概述] &&只能用作逻辑与(and)运算符(具有短路功能):但是&可以作为逻辑与运算符(是"无条件与&quo ...
- cvte面试查漏补缺
1.tcp3次握手 第一次客户端发送syn包,第二次服务端发送syn+ack包,第3次客户端接收syn+ack之后再发送ACK确认包 2.jvm算法介绍 1)复制算法,新生代采用的,复制一个一样的空间 ...
- 算法岗面经整理!查漏补缺
↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:阿毛冲冲冲,来源:NewBeeNLP(牛客网) 写在前面 三月面试 ...
- 前端查漏补缺 全知识点合集(更新中9.3)
该篇文章用于本人查漏补缺,会有大量知识点,不定期更新,有人愿意看就随便看看. HTML 浏览器的运行机制: 构建DOM树(parse):渲染引擎解析HTML文档,首先将标签转换成DOM树中的DOM n ...
- 【C++后台开发面经】面试总结第八波:整个知识的查漏补缺
前言 面试总结第八波,面试了腾讯.百度.阿里.虎牙直播等几个公司,然后总结了这一波面经,主要针对前面总结的那些,在面试时,有些被问到了,所以进行的一个查漏补缺总结. 1.C++ unique_ptr的 ...
最新文章
- Flex 元数据标签使用
- 浪度九州城首页到内容页
- 广西大学计算机科学与技术中法,广西大学
- 深入理解Lambda
- 等待多线程完成的CountDownLatch
- html比较难记的点
- POJ 1047 Round and Round We Go
- RNQOJ 98 逃亡的准备
- 【HihoCoder - 1880】地铁环线 (前缀和,水题,模拟)
- 朴素贝叶斯算法注意事项(有待完善)
- 女生最想让男生知道的58件事[[急转]]
- java 可变 不可变_java中的不可变类型的探究
- 烧脑又走心,CCF BDCI大赛这波儿操作有点赞!
- 数据库课设——企业员工人事管理系统
- sony z及泛泰a870 安装optware记录
- js实现中文简繁切换效果
- C-DOCSIS业务流
- 计算机考研考线代和概率论吗,关于考研数学线代和概率论的暑期复习扫尾建议...
- [音乐欣赏]花与琴的流星
- mysql 实现批量添加和更新功能