JavaScript函数防抖动debounce

 更新时间:2022年06月07日 10:19:50   作者:​ 灵扁扁  
这篇文章主要介绍了JavaScript函数防抖动debounce,防抖动作用防止在短时间内过于频繁的执行相同的任务,更多相关内容需要的小伙伴可以参考一下

防抖动简述

函数防抖动(debounce):防止在短时间内过于频繁的执行相同的任务。 当短时间内的频繁是不必要的时候,就可以考虑去抖动,避免资源浪费,或造成不好体验。

函数防抖动的原理,主要是利用一次性定时器,延迟任务的执行,在延迟这段时间内, 如果任务再次被触发,则通过 clearTimeout 销毁上一次产生的定时器, 因为定时器的被销毁,之前被延迟执行的任务也会随之被取消执行。 这样就实现了在一定时间内,只执行一次任务。这一次的执行通常是最后一次的触发, 因为此前的触发因为定时器的销毁而被取消了。

多次触发只执行最后一次或许就是和“节流”概念的区别?它两在作用上挺像的,在具体实现上略有不同。 函数防抖(debounce)是短时间内连续多次触发,但只执行最后一次,即是说将多次执行变成了只执行最后一次,执行次数减少。 而节流(throttle)是将短时间的多次执行,变成每隔一段时间执行一次。

防抖应用示例

1.防抖前后示例效果截图

2.防抖示例完整 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>防抖动 Demo</title>
</head>
<body>
<h1>防抖动 Demo</h1>

<label>
    <span>输入昵称:</span>
    <input oninput="inputChange(event.data)"></input>
</label>

<script>

  let timer = null

  function inputChange (data) {
    // 不做防抖动会频繁触发校验,例如连续的输入两个字可能会触发6-7次,
    // 这种频繁程度可能不是必要的,当频繁不是必要的,那么就是资源的浪费。
    // validatePhone(data)

    // 防抖处理,连续正常的输入同样的两个字,只会触发一次校验任务。
    clearTimeout(timer)
    timer = setTimeout(() => {
      validatePhone(data)
    }, 1000)
  }

  function validatePhone (data) {
    let flag = true
    const regPhone = /^1\d{10}$/
    if (!regPhone.test(data)) {
      flag = false
      console.log('校验内容:' + data + '。手机号不正确,请输入1开头的11位手机号')
    }
    return flag
  }
</script>
</body>
</html>

防抖动的应用场景

当任务在短时间内被频繁执行,而这种频繁不是必要的,或不是想要的,就可以考虑使用防抖。 下面是一些场景例子:

①监听滚动条实现左侧内容和右侧导航关联,滚动条的频繁程度很高, 而这种频繁程度可能不是我们想要的,此时就可以考虑使用防抖。

例如我在 JavaScript实现内容滚动与导航标签互动关联方案中就使用了防抖。

// 监听滚动条
window.addEventListener("scroll", function (e) {
  // 防抖动处理
  clearTimeout(that.timeout)
  this.timeout = setTimeout(() => {
    that.activeNavNode(e)
  }, 100)
});

②表单输入的一些监听事件,例如 oninput 等。

③一些组件库的内容变化监听,例如 el-tree 的 @check-change 事件, 当选择祖先级的选项时,因为包含了选中其子孙项,@check-change 会被频繁触发, 如果这个选项变化关联接口,那么这种频繁可能不是必要的。

下面是一个示例:

    <el-tree
      ref="tree"
      :data="treeData"
      show-checkbox
      @check-change="handleCheckChange">
    </el-tree>
handleCheckChange (data, checked, indeterminate) {
  // 简单的防抖动处理
  clearTimeout(this.timeout)
  this.timeout = setTimeout(() => {
    let checkedKeys = this.$refs.tree.getCheckedKeys()
    // 处理相关业务,例如根据选中的条件,触发接口查询
    // this.$emit('checkChange', checkedKeys.join(';'))
  }, 300)
},

④监听浏览器窗口变化 window.onresize,例如在 echarts 的应用中, 默认浏览器窗口大小改变 echarts 视图布局是不会做响应式改变的, 那么就需要通过监听浏览器窗口大小改变然后去重置 echarts 实现布局的改变。 实践发现,调整一下浏览器窗口大小,会非常多次触发 onresize, 但如果我们也跟着去多次重置 echarts.resize(),这不仅不是必要的, 而且还会造成闪烁频繁,卡顿等不好的体验,以及性能浪费。此时适合用防抖动处理。

下面是一个示例:

// 设备视口大小改变时,重置 echarts
let timer = null
window.onresize = function () {
  // 简单的防抖动处理
  clearTimeout(timer)
  timer = setTimeout(() => {
    console.log(timer)
    chart.resize()
  }, 500)
}

也可以考虑使用闭包的方式,而不必在外面声明 timer,例如这样

// 也可以考虑用闭包的方式
window.onresize = this.debounce(() => {
  chart.resize()
}, 500)

function debounce (fn, delay = 1000) {
  let timer = null
  return () => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(fn, delay)
  }
}

⑤鼠标事件,例如拖拽等的监听等,出于准确性和及时性, 他们的监听响应十分细密,而当这种频繁在业务上可能不是必要的,那么也可以考虑使用防抖动技术。

到此这篇关于JavaScript函数防抖动debounce的文章就介绍到这了,更多相关JS防抖动内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于js实现二级下拉联动

    基于js实现二级下拉联动

    这篇文章主要为大家详细介绍了基于js实现二级下拉联动,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • js实现鼠标左右移动,图片也跟着移动效果

    js实现鼠标左右移动,图片也跟着移动效果

    本文主要介绍了js实现鼠标左右移动,图片也跟着移动效果的方法与思路。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • Javascript之深入浅出prototype

    Javascript之深入浅出prototype

    本文将深入浅出的对Javascript中的prototype进行详细介绍。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 使用mini-define实现前端代码的模块化管理

    使用mini-define实现前端代码的模块化管理

    这篇文章主要介绍了使用mini-define实现前端代码的模块化管理,十分不错的一篇文章,这里推荐给有需要的小伙伴。
    2014-12-12
  • Javascript执行流程细节原理解析

    Javascript执行流程细节原理解析

    这篇文章主要介绍了Javascript执行流程细节解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • JS组件封装之监听localStorage的变化

    JS组件封装之监听localStorage的变化

    这篇文章主要介绍了JS组件封装之监听localStorage的变化,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • JS中准确判断变量类型的方法

    JS中准确判断变量类型的方法

    这篇文章主要介绍了在js中如何准确的判断一个变量的类型,文中代码非常详细,帮助大家更好的学习,有兴趣的朋友可以了解下
    2020-06-06
  • js几个不错的函数 $$()

    js几个不错的函数 $$()

    js几个不错的函数 $$()...
    2006-10-10
  • 通过实例解析javascript Date对象属性及方法

    通过实例解析javascript Date对象属性及方法

    这篇文章主要介绍了通过实例解析javascript Date对象属性及方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • JavaScript中Webpack的使用教程

    JavaScript中Webpack的使用教程

    Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源,这篇文章主要介绍了JavaScript中Webpack的使用,需要的朋友可以参考下
    2021-10-10

最新评论