最近写了一些前端代码,感觉前端也挺有趣的,因此以后会不定时更新前端的博文。
因为前端这块我也是现学现卖,因此依然重复着需求-学习-实现-发现问题-解决问题-探求原理的过程。
问题描述
需求中有一部分是一个滑块控制,用户可以滑动滑块向后台接口传入数值,后台根据传入数值实现某些功能。类似下面这样。
滑块部分实现就不详细说了,就是使用 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·斯科特·派克
评论
888267 851258I came to the exact conclusion as properly some time ago. Excellent write-up and I will likely be confident to appear back later for much more news. 298975
997832 476439Chaga mushroom tea leaf is thought-about any adverse health elixir at Spain, Siberia and a lot of n . Countries in europe sadly contains before you go ahead significantly avoidable the main limelight under western culture. Mushroom 804326
163559 686805You produced some decent points there. I looked on the internet for that issue and located most people will go in addition to with the internet web site. 406924
563072 482855Woh Every person loves you , bookmarked ! My partner and i take problem in your last point. 863702
832796 222553You produced some decent points there. I looked on the internet for that issue and discovered many people is going together with with the internet internet site. 457903
712239 97467excellent day, your internet web site is low-cost. I do many thanks for succeed 143357
91567 411274Absolutely pent subject matter, appreciate it for selective information . 202513
715416 21954I gotta bookmark this web site it seems extremely beneficial . 500886
740434 779015If you happen to significant fortunate people forms, referring by natural indicates, additionally you catch the attention of some sort of envy in consideration of those types the other campers surrounding you which have tough times about this subject. awnings 786282