最近写了一些前端代码,感觉前端也挺有趣的,因此以后会不定时更新前端的博文。
因为前端这块我也是现学现卖,因此依然重复着需求-学习-实现-发现问题-解决问题-探求原理的过程。
问题描述
需求中有一部分是一个滑块控制,用户可以滑动滑块向后台接口传入数值,后台根据传入数值实现某些功能。类似下面这样。
滑块部分实现就不详细说了,就是使用 input type="range"
元素再加上CSS样式美化而已,滑块跟数值的同步则是通过js代码。
在拖动滑块时,触发的oninput事件会通过js调用后台接口,这里的问题是,在滑动滑块时,触发频率太高,例如从10滑到20的过程中,会向后台连续调用10次接口,传入11~20这10个参数。
这显然是有问题的,用户只是想得到20的效果,其他数值是不应该传入的,这些多余的输入会让后台浪费大量性能。
因此这里引入了函数防抖和函数节流的概念,用来控制函数在一定时间内的执行次数,下面分别介绍。
函数防抖
函数防抖的概念是创建一个计时器,函数将在计时完毕后再执行(延时执行),如果在计时完毕之前传入新的同一请求,则计时器清零重新等待,最后执行的函数传入的参数是最后一次传入的参数。
函数防抖主要用来防止连续调用,例如输入框内的验证功能、滑块等参数连续修改功能、防止表单多次提交等等。
代码如下
function debounce(fn,wait) { var timer = null; return function () { var context = this; var args = arguments; if (timer) { clearTimeout(timer); timer = null; } timer = setTimeout(function () { fn.apply(context,args) },wait) } } var fn = function () { console.log('boom') } setInterval(debounce(fn,500),1000) //第一次在1500ms后触发,之后每1000ms触发一次 setInterval(debounce(fn,2000),1000) //不会触发,因为一直在重置计时器
其中对timer
变量做了一次闭包。
函数节流
函数节流的概念是规定一个单位时间,在单位时间内只能触发一次函数执行,其他执行会被忽略。
函数节流主要用于锁定调用频率,例如游戏刷新率、DOM元素拖拽、Canvas画笔功能等。
代码如下
function throttle(fn,gapTime) { let _lastTime = null; return function () { let _nowTime = + new Date(); if (_nowTime - _lastTime > gapTime || !_lastTime) { fn(); _lastTime = _nowTime; } } } let fn = ()=>{ console.log('boom') } setInterval(throttle(fn,1000),10) //每秒触发一次
其中对_lastTime
变量做了一次闭包。
不过这么写有一个问题,即最后一次触发很可能无法执行。
因此可以结合函数防抖实现如下
function throttle2(method,delay,time) { var timeout,startTime = new Date(); return function() { var context = this; var args = arguments; var curTime = new Date(); clearTimeout(timeout); //达到触发间隔则立即触发 if (curTime - startTime >= time) { method.apply(context,args); startTime = curTime; //最后一次延时触发 } else { timeout = setTimeout(method,delay); } } }
或者
var lastTime = null; var timeout = null; function throttle(fn,delay) { let nowTime = new Date(); clearTimeout(timeout); if (nowTime - lastTime > delay || !lastTime) { fn(); lastTime = nowTime; }else{ timeout = setTimeout(fn,delay); } }
总结
在遇到函数触发次数太频繁的问题后,通过查资料找到了这两种方法,这里明显应该使用函数防抖,成功解决了该问题。
当然,在这个案例里也可以使用onchange事件,在松开鼠标的时候才会触发,数值显示则使用oninput实时显示当前数值。
本文代码部分转载自轻松理解JS函数节流和函数防抖。
所谓自律,是以积极而主动的态度,
去解决人生痛苦的重要原则,
主要包括四个方面:
推迟满足感、承担责任、尊重事实、保持平衡。
《少有人走的路》
——M·斯科特·派克
评论
920356 220084I like this web site very considerably so much superb information . 402212