JS防抖是什么?干嘛用的?

你好同学,我是沐爸,欢迎点赞、收藏和关注!个人知乎

防抖在前端开发中可以说经常用到,有诸多使用场景。接下来我们一起看下防抖的定义、防抖函数的实现、应用场景、lodash防抖函数以及防抖在框架中的使用。Let's go

一、什么是防抖?

什么是防抖?防抖技术确保函数在指定的时间间隔结束后才执行,如果在该间隔内有多次调用,则只会执行最后一次调用。

通俗点讲,以按钮点击为例,设置频率为1s,那么如果相邻两次的点击事件的时间间隔小于1s,理论上你可以一直点下去,点击要执行的函数永远不会触发;如果你只点了一次,或者两次点击的时间间隔大于等于1s,那么函数就会执行。

二、函数实现

javascript 复制代码
function debounce(fn, wait) {
  let timeout = null;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
}

// 使用示例:方式一
window.addEventListener('resize', debounce(function() {
  console.log('窗口大小改变');
}, 200));

// 使用示例:方式二
function onWindowResize() {
  console.log('窗口大小改变');
}
window.addEventListener('resize', debounce(onWindowResize, 200));

三、应用场景

1.搜索框输入

当用户在搜索框中键入时,通常希望在用户停止输入一定时间后再去请求搜索结果,以减少请求次数。

javascript 复制代码
function onSearchInput() {
  console.log('搜索词:', this.value);
}

const searchInput = document.querySelector('.search-input');
searchInput.addEventListener('input', debounce(onSearchInput, 300));

2.窗口调整大小

在用户调整浏览器窗口大小时,可能需要根据最终的尺寸执行一些操作,如重新计算布局或重新加载资源。

javascript 复制代码
// 假设 myChart 是一个 ECharts 实例
const myChart = echarts.init(document.getElementById('myChart'));

// 对图表进行初始化操作,如设置选项等
myChart.setOption(/* ... */);

// 定义一个函数用于响应窗口大小变化
function onWindowResize() {
  myChart.resize(); // 调整图表尺寸以适应窗口大小
}

// 使用防抖处理窗口调整大小事件
const debouncedResize = debounce(onWindowResize, 200);

// 监听窗口调整大小事件
window.addEventListener('resize', debouncedResize);

3.表单验证

在用户填写表单时,可能希望在用户完成输入后进行验证,而不是每输入一个字符都进行验证。

javascript 复制代码
function onFormInput() {
  // 执行表单验证逻辑
  console.log('输入内容验证');
}

const formInput = document.querySelector('.form-input');
formInput.addEventListener('input', debounce(onFormInput, 500));

4.表单提交

防抖也经常会用于表单提交,用以限制用户手误导致的重复提交。

javascript 复制代码
// 搜索函数
function handleSubmit() {
  console.log('执行搜索操作');
  // 执行搜索的逻辑
}

// 将防抖应用于点击事件
const debouncedSubmit = debounce(handleSubmit, 300);

// 给搜索按钮添加点击事件监听器
searchButton.addEventListener('click', debouncedSubmit);

5.键盘事件处理

在处理键盘事件,如连续按键时,防抖可以确保在用户停止按键后执行操作,如提交搜索查询。

javascript 复制代码
function onKeyPress() {
  console.log('按键事件');
}

document.addEventListener('keydown', debounce(onKeyPress, 100));

6.文件预览

在选择文件后,可能需要在用户停止选择文件一段时间后才加载预览,以避免在文件选择过程中占用过多资源。

javascript 复制代码
function onFileSelected() {
  console.log('文件选择完成');
  // 加载文件预览或处理文件
}

const fileInput = document.querySelector('.file-input');
fileInput.addEventListener('change', debounce(onFileSelected, 300));

四、lodash防抖函数

Lodash 是一个流行的 JavaScript 实用工具库,它提供了很多现成的函数式编程工具,包括防抖(debounce)功能。Lodash 的 debounce 方法可以非常方便地实现函数的防抖。

javascript 复制代码
import _ from 'lodash';

function performSearch(query) {
  console.log('搜索:', query);
  // 执行搜索逻辑
}
const debouncedSearch = _.debounce(performSearch, 300);

const searchInput = document.getElementById('search-input');
searchInput.addEventListener('input', (event) => {
  debouncedSearch(event.target.value);
});

五、防抖在框架中的使用

Vue 2 中的防抖使用

在Vue 2中,你可以使用debounce函数结合watch属性来实现防抖:

javascript 复制代码
import _ from 'lodash';

export default {
  data() {
    return {
      searchQuery: ''
    }
  },
  watch: {
    // 使用防抖函数包装 watch 属性
    searchQuery: _.debounce(function (newValue) {
      console.log('搜索查询更新:', newValue);
      // 执行搜索逻辑
    }, 300)
  },
  methods: {
    // 其他方法...
  }
}

Vue 3 中的防抖使用

Vue 3 引入了Composition API,提供了更多的灵活性。对Vu2的例子进行改写:

javascript 复制代码
import _ from 'lodash';
import { reactive, watch } from 'vue';

const state = reactive({
  searchQuery: ''
});

const debouncedSearch = debounce((newValue) => {
  console.log('搜索查询更新:', newValue);
  // 执行搜索逻辑
}, 300);

watch(() => state.searchQuery, (newValue, oldValue) => {
  debouncedSearch(newValue);
});

React 中防抖的使用

1.函数组件使用防抖函数

假设我们有一个搜索框,我们想要在用户停止输入300毫秒后才执行搜索操作:

javascript 复制代码
import React, { useState, useCallback } from 'react';
import _ from 'lodash'; // 引入Lodash库

const SearchComponent = () => {
  const [searchTerm, setSearchTerm] = useState('');

  // 使用 useCallback 钩子来记忆化防抖函数
  const debouncedSearch = useCallback(
    _.debounce((term) => {
      console.log('搜索:', term);
      // 执行搜索逻辑
    }, 300),
    []
  );

  const handleInputChange = (event) => {
    // 当输入改变时,更新状态并触发防抖函数
    setSearchTerm(event.target.value);
    debouncedSearch(event.target.value);
  };

  return (
    <input
      type="text"
      value={searchTerm}
      onChange={handleInputChange}
      placeholder="输入搜索内容"
    />
  );
};

export default SearchComponent;

2.类组件使用防抖函数

在类组件中,你可以在componentDidMount生命周期方法中设置事件监听器,并在componentWillUnmount中清除它们:

javascript 复制代码
import React, { Component } from 'react';
import _ from 'lodash';

class SearchComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      searchTerm: '',
    };
    this.debouncedSearch = _.debounce(this.handleSearch, 300);
  }

  handleSearch = (term) => {
    console.log('搜索:', term);
    // 执行搜索逻辑
  };

  handleInputChange = (event) => {
    const term = event.target.value;
    this.setState({ searchTerm: term }, () => {
      this.debouncedSearch(term);
    });
  };

  componentDidMount() {
    // 如果需要绑定事件,可以在此处进行
  }

  componentWillUnmount() {
    // 清除防抖函数的定时器
    this.debouncedSearch.cancel();
  }

  render() {
    const { searchTerm } = this.state;
    return (
      <input
        type="text"
        value={searchTerm}
        onChange={this.handleInputChange}
        placeholder="输入搜索内容"
      />
    );
  }
}

export default SearchComponent;

希望今天的分享对你有所帮助,下期再见!

相关推荐
new出一个对象2 小时前
uniapp接入BMapGL百度地图
javascript·百度·uni-app
你挚爱的强哥3 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
y先森4 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy4 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189114 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿5 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡6 小时前
commitlint校验git提交信息
前端
天天进步20156 小时前
Vue+Springboot用Websocket实现协同编辑
vue.js·spring boot·websocket
虾球xz6 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇6 小时前
HTML常用表格与标签
前端·html