“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情”
不会弹吉他的铁匠不是一名好铁匠!大家好,我是拿吉他的铁匠,码字不易,希望大家多多点赞。
铁匠来到心仪的公司面试,他信心满满,暗下决心用自己技术征服面试官,毕竟复习到晚上12点(bushi);经过漫长的等待,终于来到面试环节;面试官正对着铁匠,只见他身着李宁的短袖,短裤,戴着细框黑色眼镜,嘴角带着些许笑意;铁匠意识到,今天是一场硬仗;双方介绍完毕后,铁匠知道面试官名叫大A;大A扶了下眼镜,面试正式开始:
面试官大A: 那首先问你一个简单的问题吧,请介绍一下防抖和节流吧!
铁匠:心中暗喜,防抖和节流那不嘎嘎熟悉。请听我慢慢道来。
是什么?
场景:
- 频繁的操作DOM或者请求资源,会导致前端性能的下降,设置会导致浏览器的崩溃;
- 如window对象频繁的onresize,onscroll事件;
- 如mousemove,mousedown等事件;
- 如input输入搜索事件;
为了很好的应对处理这些问题,优化前端的性能,防抖和节流应运而生;
- 节流(throttle):以电梯为例,电梯等一个人进来,在15秒内无论进来多少人,15秒后准时运送一次;
- 防抖(debounce):以电梯为例,电梯等一个人进来,等待15秒,如果期间又有人进来,则15秒重新计时,只有当15秒内没有人进来,15秒后才会运送一次;
面试官大A: 嗯,说的是挺明白的,给,写一下吧;
铁匠:终于到了手写代码的时刻了。
节流
-
首先介绍时间戳的方案:
- 主要是获取每一次操作之前的时间戳和触发操作时的时间戳,如果差值符合等待时间,就触发事件;
- 利用闭包能够延长变量生命周期的特点,所以能够得到每一次触发事件前需要的时间戳,如使用的pre变量;
- 鼠标任意滑动,每隔两秒才会打印数据;
-
然后介绍定时器方案:
- 主要是利用setTimeout()方法,定时触发事件;
- 利用闭包能够延长变量生命周期的特点,所以每一次触发操作,定时器都能生效;
防抖
-
好了,上面就是介绍的节流的两种方案,下面开始介绍防抖;
-
非立即防抖:
- 触发事件后函数不会立即执行,而是在n秒后执行,如果n秒内又触发了事件,那么定时器重新计时;等到delay时间,自动执行里面的函数;
- 还是利用闭包延长timer的生命周期,只要input事件触发,timer就会被赋值,但是因为delay时间未到,所以并不会执行里面的函数;
- 每一次操作前清除上一次的定时器,只要定时器满足延迟时间,就会执行里面的函数;达到防抖的效果;
-
立即防抖:
- 触发事件后函数会立即执行,然后n秒内没有重复触发事件才会执行;因为n秒内没有触发,timer会被赋值为null;
- 定义变量callNow控制函数的执行,这里有个误区,清除定时器不代表timer的值是null,timer的值是每一次触发定时器返回的对应的ID,这是特别要注意的地方;
- 只要input事件触发,就会触发一次定时器,并将ID赋值给timer,因为没有到达延迟时间,所以不会触发里面的函数;只有满足延迟时间,timer的值才是null,然后才会进入条件语句执行函数;
面试官大A:嗯,手写代码写的挺有条理,那这边咱们就过了,那么请说一下...?(请静待下回分解)