最近身体疲惫,每天感觉脑子跟不上,并且很容易犯困,还好有人一直给充电,本来不太精神但是瞬间就充满能量。经过一番思想斗争之后,终于决定昨天鸽了一下,哇,真的好爽,今天早上来了还被嘲讽提前过上了公园大爷的生活,哈哈哈,不过休班一时爽,一直休班一直爽啊 ,不不不,说错了,一直休班木有qian啊,最近怎么话这么多,步入正题吧,今天来研究一下截流和防抖原理。(接着奏乐,接着舞)
-
什么情况出现的截流和防抖
- 当我们在鼠标移动和页面滚动的时候频繁的触犯一个函数
- 当属一个输入框中,输入进行查询的时候
- 屏幕尺寸发生改变的时候(一直在缩小放大浏览器)
以上情况都会高频的触发函数,这个时候浏览器就容易卡死,难道这样就放任不管么?兄弟你不是在开玩笑吧?怎么可能不管呢。这属于前端的性能优化之一啊。
-
防抖原理和实现
-
原理:什么是防抖呢?顾名思义那就是防止抖动啊,在你一直抖啊抖的过程,不在你抖动的时候进行操作,而是再你稳定之后进行函数的执行,也就是说,当你频繁的进行一个动作(下拉滚动条),不会一直执行所触发的函数而是在停下来之后多长时间进行触发。再来举个栗子,哎!每天举栗子也很沉的好嘛,咱们那种大厦的感应的门了解吧?比如现在有10个人一直进门(好比你一直在滚动页面),这个感应门不可能进一个人关一次门吧?这样门早就被砸了好么(浏览器奔溃了),感应门肯定是等10个人进去了,等几(比如10秒)秒,这10秒内没有人进了,就执行关门这个操作(触发的函数),10内有人进,就重新再记10秒重新计算。这就是防抖
-
实现思路 :主要有两点 1.事件发生后,清除旧的计时器 2.设置行的计时器
<div class="box"></div> <script> var box = document.querySelector('.box'); function debounce(handler,time){ var timer = null ; return function (){ clearTimeout(timer); // 触发就清0 触发就清0 ; 直到不触发之后,几秒钟 var args = arguments; var _this = this; timer = setTimeout(function(){ // 把box对象的这个this传给它 handler.apply(_this,args); },time); } } // 要执行的动作 function handle(e){ console.log("这里做点什么"); this.innerHTML = e.clientX; } var testDebounce = debounce(handle,2000); box.onmousemove = testDebounce; </script>
我觉得你肯定你开始的时候一定和我一样,为什么debounce函数要return 一个函数,那我们来写一下
var timer = null; box.onmousemove = reTime(); function reTime (){ if(timer){ clearTimeout(timer); } timer = setTimeout(handle,2000) } function handle(){ // todo somethings }
reTime函数需要操作来自父级作用域的变量timer,而debounce函数就是为了创建这样一个作用域,使得每次执行reTimer函数时timer变量都是存在的。但是后边这种相对于前边就不那么优雅了,第一个timer只在函数内部进行使用,不必在全局变量中,显然闭包更符合方案。
-
-
截流原理和实现
-
原理:知道了防抖,截流就是更简单了,在一个瀑布中,定时抽断一下,俗话讲抽刀断水水更流,不形容我们做程序哈。再来举一个吧,光举着也没人吃。比如我们正在做一个输入框,要求每输入一个字符都调用一个API来查询数据,从而实现联想、自动补全等功能,然而我们的输入速度是很快的,可能还没等第一个字符的查询结果出来,第二个字符就已经敲进去了,所以我们需要让查询频率小一点,具体做法就是在输入的过程中,每隔N秒才查询一次。
-
实现思路 :确保一个计时器停止时再重新计时
<div class="box"></div> <script> var box = document.querySelector(".box"); function throttle(fn,delay){ let timer = null ; return function throttler(){ if (timer===null) { // 只要时间不是null 就触发 。也就是说这个事件触发之后就从头算时间,到时间了也就再次触发 timer = setTimeout(function(){ fn(); timer = null; },delay) } } } function handle(){ console.log('--todoSomethings---') } box.onmousemove = throttle(handle,2000) </script>
-