首页 > 其他分享 > js之防抖与节流

js之防抖与节流

时间:2023-02-17 18:01:39浏览次数:35  
标签:function 触发 防抖 节流 之防抖 js 事件 func

一.本质

  本质上二者都是优化高频率执行代码的一种手段。

  一句话概括:防抖是碰到新调用就重置计时器;节流则是碰到新调用就无视。

   比如:浏览器的resize、mouseover 等事件在触发时,会不断的调用绑定在事件上的回调函数,浪费资源,降低性能。所以,为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以使用防抖和节流的方式来减少调用频率。

二.定义

  1.防抖:N秒后再执行该事件,若在N秒内被重复触发,则重新计时。即当持续触发事件时,一定时间段内没有再触发该事件,则事件处理函数才会执行一次,如果设定的时间到来之前,再次触发了时间,就重新开始延时。

    1.1.为什么要防抖:有的操作是高频触发的,但是其实触发一次就可以了,比如监听输入框的输入,不需要用户每次输入一个字符就去触发监听,应该是用户完成一段输入后再去触发监听事件;再比如如果短时间内多次缩放页面,我们也不应该每次都去触发操作,只触发一次就可以了。也就是等用户高频事件完了,再进行事件的操作。

   1.2.防抖怎么做:使用settimeout实现。触发事件,如果当前没有定时器,设定定时器。如果有定时器,重设定时器。

function debounce(func,wait){
let timeout=null;
return function(){
clearTimeout(timeout);
timeout=setTimeout(()=>{
func()
},wait)
}
}

   防抖如果要立即执行,可加入第三个参数用于判断,实现代码如下:

function(func,wait,immediate){
let timeout=null;
return function(){
if(timeout){
clearTime(timeout)
}
if(immediate){
let isCallNow=!timeout;
timeout=setTimeout(function(){
timeout=null;
},wait)
if(isCallNow){
func()
}
}else{
timeout=setTimeout(function(){
func()
},wait)
}
}
}

2.节流:N秒内只执行一次,如果再N秒内被重复触发,只有一次生效。即高频率触发的事件,在指定的单位时间内,只相应一次。

  2.1.为什么要节流:防抖存在一个问题,事件会一直等到用户完成操作后一段时间再触发,如果一直操作,则不会触发。节流就是减少流量,将频繁触发的事件减少,并且每隔一段事件执行,也就是控制事件触发的频率。

也就是某一个操作希望上一次的完成后再进行下一次,或者希望隔一段事件触发一次。

   2.2.节流怎么做:思路:我们可以设计一种类似开关一样的函数,即事件触发时让函数执行一次,然后关闭这个开关。过段时间再将这个开关打开,再次触发事件。

    完成节流可以使用时间戳与定时器的写法:使用时间戳的写法,事件会立即执行,停止触发后没有办法再次执行,代码如下:

function throttle(func,delay=1000){
let oldTime = Date.now()
return function(){
let newTime = Date.now();
if(newTime-oldTime >= delay){
func();
oldTime = Date.now()
}
}
}

   使用定时器的写法,delay毫秒后第一次执行,第二次事件停止触发后依然会再一次执行。

function throttle(func,delay=1000){
let timer = null;
return function(){
if(!timer){
timer = setTimeout(() => {
func();
timer = null;
},delay);
}
}
}

 将时间戳与定时器搭配使用,可以实现更精确的节流。

function throttle(func,delay){
let timer = null;
let starttime = Date.now();
return function(){
let curtime = Date.now();
let remaining = delay - (curtime - starttime) //从上一次到现在剩下的时间
clearTimeout(timer)
if(remaining <= 0){
func()
starttime = Date.now()
} else {
timer = setTimeout(fn,remaining);
}
}
}

三.区别

相同点:1.都可以通过setTimeout实现

             2.米的都是降低执行频率,节省资源

不同点:

  • 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout​​和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
  • 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次

例如,都设置时间频率为1000ms,在4秒时间内,频繁触发函数,节流,每隔 1000ms 就执行一次。防抖,则不管调动多少次方法,在4s后,只会执行一次。

四.应用场景

1.防抖在连续的事件中,只需触发一次回调的场景:

 1.1.搜索框搜索输入,只需用户最后一次输入完,再向后台发送请求

  1.2.窗口大小缩放,只需窗口调整结束,计算窗口大小,从而防止重复渲染

2.节流在间隔一段时间 执行一次回调的场景:

  2.1.滚动加载,加载更多

  2.2搜索框的搜索联想功能

标签:function,触发,防抖,节流,之防抖,js,事件,func
From: https://blog.51cto.com/u_15402941/6064467

相关文章

  • vue2 vue-router.esm.js:16 [vue-router] Failed to resolve async component default
    敢信,晚上加班找这个错误,TMD找了二小时,网上各种百度。。。。。。原因竟然是这个ProductCategory组件,没有import进来,而components中却引用了!!!!低级错误,粗心问题!!!这也再次证......
  • 测试公开课资料系列02--Postman之chai.js断言应用
    前言如果要挖井,就要挖到水出为止。明晚公开课给大家讲讲如何用chai.js断言,有用过postman只会右侧点来自动生成断言代码,或在公司应用postman的朋友们都来听听。一、c......
  • JS常用方法
    reduce方法循环的一种,其中有四个参数letlist=[{id:1,content:'张三',isdone:false},{id:2,content:'张三',isdone:true},{id:3,content:'张三',isdone:false}......
  • vue项目部署在nodejs+express
    一、安装node和打包vue项目就不用多说了二、安装expressExpress是一个保持最小规模的灵活的Node.jsweb应用程序开发框架,为web和移动应用程序提供一组强大的功能npmin......
  • js实现一二级域名共享cookie
    前言最近接手的项目中,有人反馈了一个问题,说是在访问网站并登录后,登录成功有登录信息,但是刷新页面后重定向到了登录页面,让从新登录。打开goole调试页面,查看cookie时......
  • nodejs 实现类似sleep延时执行的方法
    在Node.js中,没有类似于传统编程语言中的sleep()函数,因为Node.js是单线程的。但是可以使用setTimeout()函数实现暂停执行,从而实现类似于sleep()的效果。下面是......
  • js - 数字转中文
    js-数字转中文JavaScript中将阿拉伯数字转换为中文转换代码var_change={ary0:['零','一','二','三','四','五','六','七','八','九'],ary1:['',......
  • three.js 性能优化之模型转化与压缩
    模型转换obj转gltf 安装插件npmi-gobj2gltf执行转换命令obj2gltf-i11-6.obj-o11-6.gltf-u 模型压缩安装gltf-pipelinenpmi-gg......
  • 关于net core 开发服务时,使用Serilog根据appsettings.json输出日志错误的问题。
    使用Serilog输出日志时,配置内容如下,"Serilog":{"Using":["Serilog.Sinks.Console","Serilog.Sinks.File"],"MinimumLevel":"Debug","WriteTo":[......
  • js 对象命名
    JS标识符的命名规则,即变量的命名规则:标识符只能由字母、数字、下划线和‘$’组成数字不可以作为标识符的首字符对象属性的命名规则通过[]操作符为对象添加属性时,属......