美文网首页
javascript函数防抖和函数节流

javascript函数防抖和函数节流

作者: solfKwolf | 来源:发表于2020-03-10 22:44 被阅读0次
  • throttle-函数节流:一个水龙头在滴水,可能一次性会滴很多滴,但是我们只希望它每隔 500ms 滴一滴水,保持这个频率。即我们希望函数在以一个可以接受的频率重复调用。
  • debounce-函数防抖:将一个弹簧按下,继续加压,继续按下,只会在最后放手的一瞬反弹。即我们希望函数只会调用一次,即使在这之前反复调用它,最终也只会调用一次而已。

解决什么问题

在开发的过程中,有很多场景(onmousemove, resize, onscroll)会频繁触发事件。函数节流和函数防抖就是为了实现防止事件频繁触发。

做一个计算窗口示例

很明显,监听浏览器窗口的 resize 事件,并基于该事件改变页面布局。首先,计算 offsetWidth 属性,如果该元素或者页面上其他元素有非常复杂的 CSS 样式,那么这个过程将会很复杂。其次,设置某个元素的高度需要对页面进行回流来令改动生效。如果页面有很多元素同时应用了相当数量的 CSS 的话,这又需要很多运算,可以通过'resize'输出的次数来观察函数调用的次数。

window.onresize = function() {  
var div = document.getElementById('mydiv')
  div.style.height = div.offsetWidth + 'px'
  console.log('resize')
}

函数防抖实现

// 非立即执行版
function debounce(func, wait) {
    let timer;
    return function() {
      let context = this; // 注意 this 指向
      let args = arguments; // arguments中存着e
         
      if (timer) clearTimeout(timer);
 
      timer = setTimeout(() => {
        func.apply(this, args)
      }, wait)
    }
}
// 立即执行版
function debounce(func, wait) {
    let timer;
    return function() {
      let context = this; // 这边的 this 指向谁?
      let args = arguments; // arguments中存着e
 
      if (timer) clearTimeout(timer);
 
      let callNow = !timer;
 
      timer = setTimeout(() => {
        timer = null;
      }, wait)
 
      if (callNow) func.apply(context, args);
    }
}

函数节流实现

// 时间戳版本
function throttle(func, wait) {
  var previous = 0;
  return function() {
    let now = Date.now();
    if(now-previous>wait) {
      func.apply(this, arguments)
      previous = now;
    }
  }

}

// 定时器版
function throttle(func, wait) {
    let timeout;
    return function() {
      let context = this;
      let args = arguments;
      if (!timeout) {
        timeout = setTimeout(() => {
          timeout = null;
          func.apply(context, args)
        }, wait)
      }
    }

我们应该可以很容易的发现,其实时间戳版和定时器版的节流函数的区别就是,时间戳版的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候。

区别

  • 函数节流是每隔n秒,函数只执行一次
  • 函数防抖是执行函数后隔n秒后再次执行才有效。

原理

某些代码不可以在没有间断的情况下连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作(清除定时器)就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。

还是很简单的...

相关文章

网友评论

      本文标题:javascript函数防抖和函数节流

      本文链接:https://www.haomeiwen.com/subject/ghxpsctx.html