浅谈防抖和节流

519 阅读2分钟

在前端学习当中我们需要使用很多需要触发的事件,但是不断触发事件,导致不断的调用函数,将会导致浏览器进行卡顿。这样会给用户带来很不好的体验,此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时又不影响实际效果。

滚动条监听

这是一个很常见的功能,大多数网站都有一键返回顶部的功能。它的代码也很简单。
这个按钮出现在据顶部一定距离时将会出现,当我们想返回顶部时只需轻轻点击一下,就可以返回到页面顶部。
监听浏览器滚动事件,返回当前滚条与顶部的距离

        function showTop() {
            var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
            console.log('滚动条位置:' + scrollTop);
        }
        window.onscroll = showTop0000000001

so_easy.jpg 是不是感觉很简单,只需要简简单单的几行代码就可以监听滚动条的位置。

监听滚动条.png

但是你看:只是轻轻的滑动一下竟然打印出这么多数据,我们其实并不需要让它这么频繁的进行执行。这样频繁的调用函数将会占用浏览器资源,浏览器的总资源是有上限的,我们不应该浪费在这里。

防抖(debounce)

防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

function debounce(fn, delay) {
  let timer = null;
  return function () {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  }
}

我们只需要增加防抖函数,设置1s内多次触发事件不会执行。

        function debounce(fn, delay) {
            let timer = null 
            return function () {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(fn, delay) 
            }
        }
        function showTop() {
            var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
            console.log('滚动条位置:' + scrollTop);
        }
        window.onscroll = debounce(showTop, 1000)

防抖滚动条.png 此时会发现,必须在停止滚动1秒以后,才会打印出滚动条位置。 但是如果有大哥 “我就是玩,就不停的滑” 这个触发事件将永远也不会触发,为了大哥的良好体验,我们要就行给出反馈,即使用户不断拖动滚动条,我们也能在某个时间间隔之后给出反馈。
我们只要设计节流就可以解决问题!!

节流(throttle)

当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流通俗解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。

function throttle(fn, cycle) {
  let start = Date.now();
  let now;
  let timer;
  return function () {
    now = Date.now();
    clearTimeout(timer);
    if (now - start >= cycle) {
      fn.apply(this, arguments);
      start = now;
    } else {
      timer = setTimeout(() => {
        fn.apply(this, arguments);
      }, cycle);
    }
  }
}