• 防抖(debounce)和节流(throttle)区别详细讲解及案例练习


    一、防抖

    1、概念

    防抖策略(debounce):当事件被触发后,延迟 n 秒后再执行回调,;若在n秒内又被触发,则重新计时。

    2、理解

    多次触发只执行一次,比如王者荣耀回城,只有经过8秒才能触发回城,8秒途中再次触发回城或中断,都需要重新等待8秒才能回城

    3、应用场景

    登录、发短信等按钮避免用户点击太快,导致发送了多次请求,需要防抖。

    4、封装防抖函数

    let debounce = function (handler,delay) {
        let timer=null;
        return function () {
            if(timer) clearTimeout(timer);
            timer = setTimeout(()=>{
                fn.apply(this,arguments)
            },delay)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    二、节流

    1、概念

    在规定的时间范围内不会重复触发回调,只有大于这个时间间隔才会触发,把频繁触发变为少量触发。

    2、理解

    一个周期只执行一次,比如王者荣耀技能,只有经过技能冷却时间,,才能再次使用

    3、应用场景

    ① 鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;

    ② 懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源;

    ③ 浏览器input搜索框展示下拉列表,需要节流,也可以使用防抖

    4、封装节流函数

    let throttle = function(handler,delay) {
    	let timer = null;   
      	return function () {
           if(timer) return;
           timer = setTimeout(() => {
             fn.apply(this,arguments)
             timer = null
           })
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    三、防抖与节流区别

    名称区别举例
    防抖最后一次执行的是防抖王者荣耀回城技能
    节流控制次数的是节流英雄cd技能

    通过对比防抖和节流函数,可以发现两者一个是return,一个是clearTimeout,为什么?
    答:
    防抖是触发间隔大于timer才会触发,所以每次在小于间隔time要清除定时器;

    节流是不管time内触发多少次,只会每间隔time时间才会触发一次,所以用return

    总结:防抖是限制操作,节流是减少操作

    四、防抖与节流案例

    1、正常页面

    如果你在1秒内输入123,那它就会在1秒内分别执行输入1、2、3时的事件。

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>正常案例title>
    head>
    
    <body>
        <input type="text" id="input">
        <script>
            let input = document.getElementById("input");
            let span = document.createElement('span');
            let num = 0;
            input.addEventListener("input", inputEvent)
            //输入事件
            function inputEvent(e) {
                console.log(e, this)
                num++;//记录请求次数
                span.innerHTML = `

    ${num}次请求了接口

    `
    ; document.body.appendChild(span); }
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2、防抖案例

    如果在200ms内输入123,那它只会执行输入3时的事件。

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>防抖title>
    head>
    
    <body>
        <input type="text" id="input">
        <script>
            let input = document.getElementById("input");
            let span = document.createElement('span');
            let num = 0;
            input.addEventListener("input", debounce(inputEvent, 200))
            //输入事件
            function inputEvent(e) {
                console.log(e, this)
                num++;//记录请求次数
                span.innerHTML = `

    ${num}次请求了接口

    `
    ; document.body.appendChild(span); } //防抖 function debounce(fn, delay) { //这里相当于定义了一个全局的timer let timer = null; return function () { //如果定时器存在,那就清掉,开启新的计时器 if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments); }, delay); } }
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3、节流案例

    如果你在一秒内输入123,那它只会执行输入1时的方法。

    DOCTYPE html>
    <html lang="en">
     
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>节流title>
    head>
     
    <body>
        <input type="text" id="input">
        <script>
            let input = document.getElementById("input");
            let span = document.createElement('span');
            let num = 0;
            input.addEventListener("input", throttle(inputEvent, 1000))
            //输入事件
            function inputEvent(e) {
                console.log(e, this)
                num++;//记录请求次数
                span.innerHTML = `

    ${num}次请求了接口

    `
    ; document.body.appendChild(span); } //节流 function throttle(fn, delay) { //相当于在全局定义了一个timer let timer = null; return function () { //如果timer存在,直接结束函数 if (timer) { return } timer = setTimeout(() => { fn.apply(this, arguments); //指定时间结束后,将timer变成null,否则这个函数将一直不执行 timer = null }, delay); } }
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    五、插件

    第三方插件库:lodash
    地址:https://www.lodashjs.com/

  • 相关阅读:
    【金融项目】尚融宝项目(十一)
    yum使用
    【VUE】ArcoDesign之自定义主题样式和命名空间
    innovus: 如何只place不优化?
    随便记记第二周
    智能导览与实时监测:数字孪生助力景区管理
    21款奔驰EQC350升级原厂360全景影像 感受上帝视野
    电子学会2023年6月青少年软件编程(图形化)等级考试试卷(三级)真题,含答案解析
    彻底搞懂MySql的B+Tree
    网络IO概述
  • 原文地址:https://blog.csdn.net/Vest_er/article/details/127451507