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的函数内部的判断不会被它覆盖掉。根据打印结果可以看出,事实确实是如此: