防抖和节流

防抖:

定义:

用户操作页面时,距离最近一次触发事件的时间超过设定的时间间隔才会执行一次回调函数。
(在设定的时间间隔内重复触发多次事件,只会在设定的时间间隔之后执行一次回调函数)

应用场景:
1.input输入内容时。

精简版代码:

//debounce
function debounce(fn,delay=500){
    let timer = null //timer是闭包中的
    return function(){
        if(timer) clearTimeout(timer)
        timer = setTimeout(()=>{
            fn.apply(this,arguments)
            timer = null
        },delay)
    }
}

节流:

定义:

用户操作页面时,在持续触发事件的时间段内,每过一段设定的时间间隔,就会执行一次回调函数。

应用场景:
1.拉动滚动条时。
2.滑动验证码滑块时。
3.拖拽元素时。
4.表单提交时

精简版代码:

//throttle
function throttle(fn,delay=100){
    let timer = null
    return function(){
        if(timer) return 
        timer = setTimeout(()=>{
            fn.apply(this,arguments)
            timer = null
        },delay)
    }
}

2023年2月3日补充:
  今天有个需求让我有了些感悟,也不知道对不对,先记下来,以后再勘误。
现有一个需求,div内信息更新通过update周期函数触发其余函数调用。默认信息更新时自动滚动到最底部,点击信息或者鼠标滚轮上滑则取消滚动到底部,有按钮可以点击恢复自动滚动到底部,也可能通过鼠标滑动到底部来恢复。

<template>
  <div
      ref="logCtn"
      v-html="logMsgs"
      @click="msgClick"
      @mousewheel="throttleChangeSelect"
      @scroll="getScroll"
    >
  </div>
</template>
<script>
  import {throttle, debounce} from 'throttle-debounce';
  data() {
      return {
         throttleChangeSelect: () => {},
         getScroll: () => {},
         isSelected: true,
         logMsgs: ""
      }
  },
  updated() {
    if (this.logMsgs !== "" && this.isSelected) {
      this.scrollBottom();
    }
  },
  mounted() {
    let self = this;
    this.throttleChangeSelect = throttle(2000, true, function(e){
      if( e.deltaY < 0 ){
        self.isSelected = false;
      }
    })
    this.getScroll = debounce(500, function(e){
      let target = e.target;
      if(target.scrollHeight === target.clientHeight + target.scrollTop){
        self.isSelected = true;
      }
    })
  },
  methods: {
    //另外有函数去更新logMsgs
    msgClick(event){
      let consoleDiv = this.$refs.logCtn;
      if(consoleDiv.scrollHeight !== consoleDiv.scrollTop + consoleDiv.clientHeight || consoleDiv.clientHeight - event.layerY > 21)//21为每行行高px
      {
        this.isSelected = false;
      }
    },
  },
    scrollBottom() {
      let consoleDiv = this.$refs.logCtn;
      if (consoleDiv && consoleDiv.scrollHeight >= consoleDiv.offsetHeight) {
        consoleDiv.scrollTop = consoleDiv.scrollHeight;
      }
 }
</script>

所以,以上关于滚动条的问题,一个用到了节流,一个用到了防抖。防抖用于动作结束后的判断,所以进度条滚动到底部时触发操作可以使用防抖,使用节流则触发操作时不一定是在底部。节流用于在一个动作的时间内周期性触发操作,首次动作便会触发,所以使用于向上或者向下滚动进度条的操作,第一时间通知滚动到底部,使用防抖则触发操作时消息可能又已滚动到底部导致无法滚动进度条。因此,滚动条使用节流还是防抖,要看具体情况来定。


爱吃鸡蛋饼
58 声望8 粉丝