博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

防抖、节流

Posted on 2021-05-25 15:17  米粒3  阅读(41)  评论(0编辑  收藏  举报

1.防抖:简单来说就是持续触发不执行,不触发了后等一段时间执行

 

鼠标在一个层中滑动,显示鼠标的坐标
<style>
        .box {
            width: 500px;
            height: 400px;
            border-radius: 8px;
            border: 1px solid #e6e6e6;
            color: #000;
            display: flex;
            justify-content: center;
            align-items: center;
        }
</style>

<div class="box" id="box">


function debounce(func,delay){
    let timeout;
    return function(){
         clearTimeout(timeout);
         timeout=setTimeout(()=>{
             func.apply(this,arguments)
         })
    }
}

let box=document.getElementById("box");
box.onmousemove=debounce(function(e){
       box.innerHTML=`${e.clientX} ${e.clientY}`
},1000)

 

2.节流:开关打开,持续触发时,持续关闭开关,等到时间到了后打开开关,函数就会执行了

 

function throttle(func,delay){
     let run=true 
     return function(){
          if(!run){
               return;
          }
          run=false
          setTimeout(()=>{
               func.apply(this,arguments)
               run=true
          },delay)
     }
}

let box=document.getElementById("box");
box.onmousemove=throttle(function(e){
    box.innerHTML=`${e.clientX} ${e.clientY}`
},delay)

  

更新一下:

说明一下节流时,后面操作中应该是因为run=false 所以才直接return,但是不是在return之前let run=ture直接覆盖掉之前的false

这里可以看一下throttle函数内部,和函数调用的时候。首先看函数内部,分解一下结构:

function throttle(func, delay) {
    return function () {
      // 执行func
    }
}

那调用时候呢?也分解一下:

throttle(function () { // 目标函数内容 }, 1000)

这里throttle函数执行的结果是其内部return的function的调用。也就是说鼠标经过的事件监听实际上是这个被return的function,不断持续触发的是它,而throttle函数只是提供了一个作用域,内部用闭包声明了一个run的开关变量,由于闭包的存在,run这个变量会一直存在不被销毁,而let run = true只在这个闭包(可以理解为作用域)内只声明了一次,但它不会被持续执行,所以return的函数内部的判断不会被它覆盖掉。根据打印结果可以看出,事实确实是如此: