0


前端基础:防抖与节流

一、一种现象

有一个input框,每次输入都要触发一次change事件,其实这大可不必,比如我输入 “上海” 两个字,竟然触发了9次。

<body>
  <input type="text" />
  <script src="./t.js"></script>
</body>
const input = document.querySelector('input')
input.oninput = function() {
  console.log(this.value)
}

假如每次change都会和后端发生一次交互,这个性能就会很惨。

怎么才能让这个次数变的少?

二、防抖

用户触发事件过于频繁,只要最后一次事件的操作。比如我们可以设置500ms,只要在500ms内你一直还在输入,也就是说你的停顿是少于500ms的,那么就不触发change事件里的复杂逻辑。在执行复杂逻辑之前就把定时器清理掉。

const input = document.querySelector('input')
let t = null
input.oninput = function() {
  if (t !== null) {
    clearTimeout(t)
  }
  t = setTimeout(() => {
    // 用一句打印代替复杂的业务逻辑
    console.log(this.value)
  }, 500)
}

三、代码改进

上面的代码有2个大毛病:

  1. let t是个全局变量;
  2. 防抖的逻辑 if (t !== null) 和 业务逻辑都混在一起了。

用闭包来改进这段代码

上面,在调用debounce的时候,第一个参数是传递一个函数,

我们传的是一个() => {console.log(this.value)} ,这里的this是window,但是我们想要的是input。

所以,可以用call的方式来

const input = document.querySelector('input')
input.oninput = debounce(function() { // 这里如果用箭头函数,还是指向window,不能用箭头函数
  // 业务逻辑,用一个打印代替
  console.log(this.value)
}, 500)

function debounce(fn, delay) {
  let t = null
  return function() {
    if (t !== null) {
      clearTimeout(t)
    }
    t = setTimeout(() => {
      // 执行业务逻辑,这里的this就是input 事件对象
      console.log('this: ', this)
      fn.call(this)
    }, delay)
  }
}

四、节流

有一种情形,滚动事件,会执行很多次。

window.onscroll = function() {
  console.log('---------')
}

你看,不到一秒钟随便滚动一下就是100多次。

防抖:只执行最后一次;

节流:控制执行次数;让耗性能的方法减少执行次数;

和防抖是一样的写法

window.onscroll = throttle(() => {
  // 这里是业务逻辑,this:window
  console.log('..........')
}, 500)

function throttle(fn, delay) {
  let flag = true
  return function() {
    if (flag) {
      setTimeout(() => {
        fn.call(this)
        flag = true
      }, delay)
    }
    flag = false
  }
}

标签: 大数据

本文转载自: https://blog.csdn.net/GY_U_YG/article/details/125492220
版权归原作者 GY_U_YG 所有, 如有侵权,请联系我们删除。

“前端基础:防抖与节流”的评论:

还没有评论