高频率触发的业务: 抽奖 登录 动画 网络加载等等需要做防抖或者是节流操作
通过案例来讲解防抖与节流
防抖比如:有一个炸弹按一次开始键 就倒计时15分钟触发爆炸,再15分钟以内再次开始按键,从新计时15分钟后触发,这种思想就是防抖是思想
- <style>
- .box {
- width: 100px;
- height: 100px;
- background-color: brown;
- cursor: pointer;
- position: absolute;
- left: 100px;
- }
- style>
- <div class='box'>666div>
- document.onclick = fangdou(function(e) {
- console.log(6666)
- }, 1000)
- function fangdou(cb, delay) {
- var timer = null;
- return function() {
- clearTimeout(timer)
- timer = setTimeout(function() {
- cb()
- }, delay)
- }
- }
可以看到我们fangdou()传进去的是一个回调函数
思想就是在设置的时间内高频的点击,只会触发一次,就一定会涉及到计时器,先给变量一个null值,调用回调函数的时候清空,这样就防止了多次点击调用多次,然后给一个计时器给变量设置中间的间隔时间一直传给计时器
需要注意的一点是我们的一直调用的是这个函数
function() {
clearTimeout(timer)
timer = setTimeout(function() {
cb()
}, delay)
}
- document.onmousemove=jieliu(function(){console.log(666)},20)
- function jieliu(cb,daley){
- var timer=null;
- return function(){
- if(!timer){
- timer=setTimeout(()=>{
- cb();
- timer=null
- },daley)
- }
- }
- }
节流操作:高频触发的业务 需要让它的频率降下来
思想是类似的通过计时器来降频,设置一个变量为空,使用if做判断如果变量为空才执行,不为空就没有作用,在计时器之中重新把这个变量设置为空就行了
他的调用者也是这个函数
function(){
if(!timer){
timer=setTimeout(()=>{
cb();
timer=null
},daley)
}
}
以及他们的优化代码
- //防抖/节流的代码优化
- function jieliu2(cb,daley){
- var timer=null;
- return function(){
- // console.log(66666,timer)
- // this是事件函数的this
- let arg=arguments
- if(!timer){
- timer=setTimeout(()=>{
- cb.apply(this,arg);//本来是window但是希望
- timer=null
- },daley)
- }
- }
- }
-
- let shijianhanshu=jieliu2(function(e){
- // console.log(e.offsetX,e.pageX)
- box.style.left=e.pageX-box.offsetWidth/2+"px"
- box.style.top=e.pageY-box.offsetHeight/2+"px"
- console.log(11111)
- },17)
- document.addEventListener("mousemove",shijianhanshu)
-
- document.onclick = fangdou2(function(e) {
- console.log(6666,e,this)
- }, 1000)
-
- function fangdou2(cb, delay) {
- var timer = null;
- return function() {
- //return这个函数频率很高 想办法让cb()执行慢下来:防抖
- let arg=arguments
- clearTimeout(timer)
- timer = setTimeout(()=>{
- cb.apply(this,arg)
- }, delay)
- }
- }