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,拖动后,每隔一秒输出很多次位置。一直匀速拖动的话,位置输出次数不固定,但稍微停顿便会输出很多次(几乎无区别)

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

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

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

相关文章
|
6天前
|
JavaScript
JS封装节流函数
JS封装节流函数
23 0
|
6天前
|
JavaScript
JS中防抖和节流的区别是什么
JS中防抖和节流的区别是什么
25 0
|
6天前
|
JavaScript 前端开发 UED
js的防抖节流
js的防抖节流
11 1
|
6天前
|
JavaScript 前端开发 UED
js的节流
js的节流
15 0
|
6天前
|
测试技术
js_防抖与节流(闭包的使用)
js_防抖与节流(闭包的使用)
18 0
|
6天前
|
JavaScript
|
6天前
|
JavaScript 前端开发
【JavaScript】面试手撕节流
上篇我们讲了防抖,这篇我们就谈谈防抖的好兄弟 -- 节流。这里在老生常谈般的提一下他们两者之间的区别,顺带给读者巩固下。
54 3
|
6天前
|
前端开发 JavaScript UED
【JavaScript】面试手撕防抖
防抖: 首先它是常见的性能优化技术,主要用于处理频繁触发的浏览器事件,如窗口大小变化、滚动事件、输入框内容改变等。在用户连续快速地触发同一事件时,防抖机制会确保相关回调函数在一个时间间隔内只会被执行一次。
41 0
|
6天前
|
JavaScript 前端开发
js的节流和防抖
js的节流和防抖
19 0
|
6天前
|
JavaScript 前端开发 UED