JavaScript-防抖和节流

简介: JavaScript-防抖和节流

0前言:


节流和防抖是前段优化的手段之一。他的作用是减少频繁触发,例如用户搜索智能提示中,如果输入每一个字都要发起后台请求对服务器端的压力太大。

本文介绍了防抖和节流的基本原理,实现方式,他是高阶函数的一个应用。

1 防抖:debounce。


在介绍前,先看一下事件监听addEventListener()方法

语法:   element.addEventListener(event,function,useCapture)

第一个参数是事件类型,不要加on

第二个参数是事件触发后调用的函数

第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的默认值为false

定义input输入框:
<input type="text" id='input' value="输入:">
    // 定义一个函数e  监听他的输入,当输入时打印输入的值
    function f(e) {
        console.log(Date.now(),e.target.value)
    }
    document.getElementById('input').addEventListener('input',function(e){
        f(e)  //监听input输入,触发调用f函数
    })

image.png

1.1 那么,如何让他打印的频率慢一点?


防抖-立即执行版本 :例:你从8点一直输入,到12点松手,那么只会打印一次。

实测不好的地方是,当我停止输入,他1秒打印一次了。(最后一个定时器没清除,一直执行)

代码:加入定时器,设置延时,这样就不会频繁的触发了。

    function f(e) {
        this.clearInterval(this.timer) //代码进入函数体,先结束之前的定时器
        this.timer = setInterval(()=>{
        // 要执行的函数                 一秒执行一次,
        console.log(Date.now(),e.target.value)  //因此同一时间下,只有最后一个定时器执行
        },1000)
    }
   document.getElementById('input').addEventListener('input',function(e){
        f(e)
    })

防抖-非立即执行版本 :例:假如你设置点击后3秒后打印,3秒内又点击了按钮,则重新计时。直到你点了然后过了3秒,才执行(算是上面的优化版)

---我继续用上面的例子效果:当我停止输入3秒后才打印,如果我输入一直不停,就一直不打印。

    function f() {
        this.clearInterval(this.timer) //结束之前的定时器
        let a = document.getElementById('input').value //拿input中value的值
        let oop  = setInterval(()=>{
        // 要执行的函数          //设置最后一个定时器的id叫oop
        console.log(Date.now(),a)
        return 
        },2000)
        setInterval(()=>{
        // 要执行的函数
        this.clearInterval(oop) //2秒后清除掉最后一个定时器
        },2000)
       }       
document.getElementById('btn').addEventListener('click',function(){
        f()
    })

这个的效果是点击按钮后2秒,打印一下,然后2秒后结束最后一个定时器,后台不会继续打印了,当我再点的时候2秒后继续打印,再2秒后停止定时器。

防抖-混合版本:我想点击按钮的时候,先发一次,然后再点的话2秒后才打印,这个步骤比起上面的就多了一个第一次点要打印一次。

解决:设置一个变量,对他判断,如果变量是true就执行打印内容,然后定时器里面把它设置成null(布尔值是false),就可实现

    function f(t) {
         let a = document.getElementById('input').value
        if(t){
            console.log(Date.now(),a)
        } 
        let oop  = setInterval(()=>{
        // 要执行的函数
        console.log(Date.now(),a)
        // console.log(a)
        t=null
        return
        },2000)
        setInterval(()=>{
        // 要执行的函数
        this.clearInterval(oop)
        },2000)
       }       
document.getElementById('btn').addEventListener('click',function(t=1){
        f(t)
    })

2节流:throttle


通俗理解:函数节流就是fps游戏的射速:就算一直按着鼠标射击,也只会按规定射速射出子弹(不会无限速度发子弹的)。单位时间内最高的发送频率,控制频率

由于代码及其相似就不写了,其实这个更简单,只需点击之后设置定时器,2秒,他就会每隔2秒打印一次。

3总结


如果事件触发是高频但是有停顿时,可以选择debounce; 在事件连续不断高频触发时,只能选择throttling,因为debounce可能会导致动作只被执行一次,界面出现跳跃。

•相同点:函数防抖和函数节流都是防止某一时间高频调用某函数f,而使用高阶函数的技巧对函数f进行包装以得到新函数f1,f1的功能与f相同,只是在有效调用上做了限制;

•不同点:函数防抖是某一段时间内只有效执行一次(或者两次吧),而函数节流是间隔一段时间有效执行一次。•  本文只是基本实现其原理,对参数和上下文并没有处理。建议使用underscore库中的工具方法:节流[1] ,防抖[2]

推荐记忆方案:记住一个好理解的,另一个对比。

•节流是节约用水:把一直连续放水的水龙头关小,直到让水是一点一点向下滴(函数还是可以被调用多次,只不过是频率变慢了)。其实你只要记住这一个,就能区别于防抖啦。

4.区别


相同点:降低处理程序的频率

不同

防抖:某个时间内不能再次触发,一旦触发,就要重新计时(例如:等电梯)

节流:限制相邻两次调用的时间间隔。(例如:调小水龙头)

4题目

前提,在网页中,从顶部向底部匀速,连续不断地滚动滚动,给添加scroll事件监听时,并对回调函数进行节流处理和防抖处理,如果时间都给1s,

补充知识点:不同浏览器获取页面滚动距离的方法不一样

(window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop)

document.documentElement.scrollTop这个案例中使用这个获取成功了。

function f(){
   console.log(Date.now()
}
var f1 = 防抖(f,1000)
var f2 = 节流(f,1000)
window.onscroll = f2;// 或者f1

它们展现的效果会有什么区别?

答案:

先说节流:1.如果初始的滚动条不在0,那么他会一秒输出一次初始位置的距离。

                 2.如果初始位置在0,拖动后,每隔一秒输出很多次位置。一直匀速拖动的话,位置输出次数不固定,但稍微停顿便会输出很多次

防抖:1.如果初始的滚动条不在0,那么他只会输出一次位置。

          2.如果初始位置在0,拖动后,每隔一秒输出很多次位置。一直匀速拖动的话,位置输出次数不固定,但稍微停顿便会输出很多次(几乎无区别)

什么时候使用防抖,什么时候使用节流?

① 当我们只需要处理最后一次触发事件时,用函数防抖。

② 当事件触发过于频繁,我们需要限制事件处理程序的调用频率时,用函数节流

相关文章
|
2月前
|
前端开发 JavaScript UED
JavaScript防抖和节流的使用及区别
JavaScript防抖和节流的使用及区别
104 57
|
5月前
|
前端开发 JavaScript Java
【JavaScript】JavaScript 防抖与节流:以游戏智慧解锁实战奥秘
【JavaScript】JavaScript 防抖与节流:以游戏智慧解锁实战奥秘
61 3
|
21天前
|
前端开发 JavaScript UED
JavaScript 中的函数防抖与节流详解及实用场景
在前端开发中,处理用户频繁触发的事件,如输入框的输入、按钮点击、窗口调整大小等,常常需要优化性能以减少无效操作。为此,函数防抖(debounce)和函数节流(throttle)是两种常见的性能优化手段。本文将详细介绍两者的区别与实现,并探讨它们的应用场景。
25 1
|
5月前
|
JavaScript 前端开发 UED
深入理解JavaScript中的节流与防抖技术
理解并合理运用节流与防抖技术,可以帮助我们优化事件处理函数的执行频率,从而提升应用的性能和用户体验。这两种技术通过减少不必要的计算和DOM操作,使得Web应用程序能够更加流畅地运行。 通过掌握防抖和节流的实现原理及应用场景,开发者可以更加灵活地编写高效且性能优化的代码,对于面对高频事件处理时尤其重要。在开发中合理选择使用防抖或节流,将直接影响到应用的响应性和效率。
53 1
|
2月前
|
JavaScript 前端开发
js防抖函数返回值问题解决方案
本文介绍了如何在JavaScript中创建一个带有返回值的防抖函数,通过结合Promise来实现。这种防抖函数可以在事件触发一定时间后再执行函数,并能处理异步操作的返回值。文章提供了防抖函数的实现代码和如何在实际项目中使用该防抖函数的示例。
25 1
|
3月前
|
JavaScript 前端开发 UED
JS 防抖与节流
防抖和节流是优化高频事件处理的技术。针对如`scroll`、`resize`等频繁触发的事件,它们能有效减少不必要的回调执行,节省资源。防抖确保在一段时间内仅执行最后一次操作,适用于输入框自动补全等场景;而节流则按固定间隔执行函数,适合拖拽、滚动事件。通过简单的JavaScript实现,可以显著提升应用性能和用户体验。
33 1
JS 防抖与节流
|
6月前
|
JavaScript 前端开发 UED
js的防抖节流
js的防抖节流
35 1
|
6月前
|
JavaScript 前端开发 UED
js的节流
js的节流
32 0
|
6月前
|
测试技术
js_防抖与节流(闭包的使用)
js_防抖与节流(闭包的使用)
42 0
|
6月前
|
JavaScript
JS中防抖和节流的区别是什么
JS中防抖和节流的区别是什么
45 0