首页 > 其他分享 >js实现防抖节流

js实现防抖节流

时间:2022-08-28 18:01:22浏览次数:66  
标签:触发 防抖 节流 param js timeout fn

前端项目开发过程中,对一个dom元素动作绑定了事件,但触发dom函数的动作过于频繁从而影响页面性能甚至出现bug的情况,比如:

页面滚动scroll事件、浏览器窗口resize事件、输入框搜索input事件等等,这些事件如果在一段时间内不加限制频繁触发必定会导致页面性能变差,尤其是绑定的事件内包含触发页面重绘重排、ajax请求这类操作时,甚至可能出现卡顿、假死、数值错误之类的bug。。。

所以为了防止绑定事件多次触发,就需要考虑使用防抖和节流的方案了

防抖:事件在指定时间间隔后触发,在时间间隔内如果重复触发事件就重新计时,多用于取多次操作的最后一次操作为有效操作的场景如:搜索框输入搜索、点击切换状态按钮、表单数据提交

节流:事件在指定事件间隔内只触发一次,时间间隔内重复触发则只有第一次生效,超出时间间隔直接执行,多用于多次操作会取得相同结果从而避免多次触发的情况如:滚动加载、新增列表项、拖拽元素

防抖和节流在代码中如何实现:

防抖

 1 /**
 2  * @param {*} fn 要进行防抖的函数
 3  * @param {*} delay 延迟几秒执行
 4  * @param {*} immediate 是否立即执行一次防抖函数(fn)
 5  */
 6 function debounce(fn, delay, immediate) {
 7   let timeout = null
 8   return function(...args) {
 9     // 清除已存在定时任务
10     if(timeout) {
11       clearTimeout(timeout)
12       timeout = null
13     } else {
14       if(immediate) fn.apply(this, args)
15     }
16     // 重新设置定时任务
17     timeout = setTimeout(() => {
18       fn.apply(this, ...args)
19     }, delay)
20   }
21 }

节流

 1 /**
 2  * 立即执行版本
 3  * @param {*} fn 要执行节流的函数
 4  * @param {*} wait 节流函数执行周期
 5  */
 6 function throttle(fn, wait) {
 7   let pre = Date.now()
 8   return function(...args) {
 9     let now = Date.now()
10     if(now - pre > wait) {
11       fn.apply(this, args)
12       pre = now
13     }
14   }
15 }
16 
17 /**
18  * 延迟指定时间执行版本
19  * @param {*} fn 要执行节流的函数
20  * @param {*} wait 节流函数执行周期 
21  */
22 function throttle(fn, wait) {
23   let timeout = null
24   return function(...args) {
25     if(!timeout) {
26       setTimeout(() => {
27         fn.apply(this, args)
28         timeout = null
29       }, wait)
30     }
31   }
32 }

 最后我们来看一下使用了防抖和节流后的效果:

防抖:

这里通过在控制台输出input框内容模拟实际应用场景中用户手动输入搜索,可以看到没有使用防抖函数,用户每次输入都会触发搜索操作,非常损耗性能

使用防抖后(这里的防抖延迟我设定的是1s),可以看到只有当用户输入间隔超过1s后才会真正执行搜索逻辑,大大节省了性能

节流:

通过页面滚动条滚动到指定高度时触发控制台输出不同内容模拟滚动加载,可以看到在不使用节流的情况下,滚动条滚动到指定高度后继续滚动还会触发加载函数

 

而使用了节流后,即使多次滚动也只会触发一次加载函数,大大节省了性能

 

标签:触发,防抖,节流,param,js,timeout,fn
From: https://www.cnblogs.com/dsyblog/p/16631290.html

相关文章

  • js事件,jQuery类库的介绍
    目录JSJS获取用户输入JS类属性操作JS样式操作事件1.事件的含义2.触发方式3.添加事件的两种方式4.关键字this5.window.onloadJS事件案例jQueryjQuery类库1.介绍2.jQuery导......
  • Spring Boot集成Jsp
    1、创建webapp目录,并在ProjectStructure中设置为资源文件夹2、导入依赖<!--内嵌Tomcat对jsp的解析依赖--><dependency><groupId>org.apache.tomcat.embed</grou......
  • threejs 实现3d柱状图
    import{useEffect,useRef}from'react';import{BoxGeometry,Mesh,AmbientLight,MeshPhongMaterial,MeshLambertMaterial,PerspectiveCamera,Scene,WebGLRe......
  • JS基础学习(二)操作BOM和DOM
    浏览器对象JavaScript可以获取浏览器提供的很多对象,并进行操作。windowwindow对象不但充当全局作用域,而且表示浏览器窗口。window对象有innerWidth和innerHeight属......
  • 关于vue的css样式对js动态添加的dom节点不生效问题的解决方法
    一、问题描述开发的时候免不了有时候需要向某个节点appendchild,添加子节点,但是如果是在vue中,就会发现通过操作dom的appendchild方式添加节点会出现样式对这些新增的节点......
  • Vue3+vite+js 配置别名@报错
    Vue3+vite+js配置别名@报错vue3项目中配置vite.config.js时使用path模块报错,一直警告找不大到path模块原因:path模块是node.js内置的功能,但是node.js本身并不支持ts解决......
  • JS基础学习(一)函数和对象
    函数定义方式1.第一种functionabs(x){if(x>=0){returnx;}else{return-x;}}2.第二种变量赋值的形式,注意最后有一个分号";......
  • NC20185 [JSOI2010]缓存交换
    题目原题地址:[JSOI2010]缓存交换题目编号:NC20185题目类型:堆、贪心时间限制:C/C++1秒,其他语言2秒空间限制:C/C++262144K,其他语言524288K1.题目大意Cache容量以及......
  • js无限debugger学习总结
    静态js代码debugger1.几千个含有debugger的script标签<script>debugger;</script><script>debugger;</script><script>debugger;</script>.........
  • Python 报错:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char
    报错内容:json.decoder.JSONDecodeError:Expectingvalue:line1column1(char0) 报错代码:print(res.json()) 报错原因:打印请求返回值报错该接口返回值......