• 简述防抖与节流,必懂(含完整模拟实例)


    • 文章看似很长,实则防抖与节流内容类似,理解其一便知其二
    • 代码不多,耐心跟着敲一遍,基本能理解防抖和节流思想

    防抖节流对

    防抖节流
    概念连续的事件,只最后一次触发回调 (如:停止滚动滑动条时,触发一次回调)连续的事件,间隔一段时间执行一次回调
    (如:滚动滚动条时,每隔一段事件触发一次回调)
    应用场景避免用户快速点击按钮,持续发送请求
    搜索框持续输入
    手机号、邮箱验证
    鼠标的mousemove、mouseover
    滚动加载,加载更多
    搜索框联想功能

    防抖

    一、原理

    事件触发n秒后才能再次发起请求

    二、需求场景实例

    例:用防抖模拟解决输入框多次发起请求问题
    在这里插入图片描述

    三、实现思路

    • 1、实现原始输入
    <input type="text"/>
    
    • 1
    //js
    var int = document.querySelector("input");
        int.oninput = function(){
            console.log(this.value)  //模拟业务逻辑
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 2、若触发事件,给定一个setTimeOut定时器做延迟触发
    • 3、初始化定时器为null
    • 4、每次点击,清除且重置定时器
    • 5、最后一次点击,即n秒后执行业务逻辑
    var int = document.querySelector("input");
    var time = null;  //初始化定时器
        int.oninput = function(){
            if(time != null){  //判断是否已存在定时器
                clearTimeout(time)  //清空定时器
            }
            time = setTimeout(() => {
                console.log(this.value);   //模拟业务逻辑
            }, 500);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    效果如下:
    在这里插入图片描述

    四、防抖进阶优化

    • 痛点:以上方法将防抖函数和业务逻辑放到一起,代码块不优雅,后期难以维护
    • 解决:将防抖函数与业务逻辑单独封装
    实现思路

    1、封装业务逻辑

    //业务逻辑
    function task(){
        console.log(this.value);  //模拟业务逻辑
    }
    
    • 1
    • 2
    • 3
    • 4

    2、封装防抖函数

    • 封装一个名为debounce,且返回值为函数的防抖函数,来替代oninput后承接的内容。
    • 因为返回值为函数,所以用闭包思想来实现封装
    function debounce(){
        return function(){}
     }
    
    • 1
    • 2
    • 3
    • 防抖函数里传入业务逻辑fn()和延迟时间delay
    • 优化全局变量time,把变量time作为私有变量放入debounce函数中
    function debounce(fn,delay){
          let time = null
          return function(){
            //此处是防抖逻辑
           }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、组装业务逻辑函数和防抖函数(完整代码)

    var int = document.querySelector("input");
    int.oninput = debounce(task,500)
    
    //业务逻辑
    function task(){
        console.log(this.value);
    }
    //防抖函数
    function debounce(fn, delay){
        var time = null;
        return function(){
            if(time != null){
                clearTimeout(time)
        }
    
        time = setTimeout(() => {
                fn.call(this) // 注:此处需改变this指针,否则业务逻辑中的this指向window
            }, delay);
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    节流

    一、原理

    控制执行次数,n秒内多次触发事件只有1次生效

    二、需求场景实例

    例:用节流模拟解决滑动浏览器多次请求的问题
    在这里插入图片描述

    三、实现思路

    • 1、实现原始输入
    <style>
        body{
            height: 10000px;
        }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    //js
    window.onscroll = function(){  
        console.log('触发')
    }
    
    • 1
    • 2
    • 3
    • 4

    2、设置标记变量,限制值为true时,进入计时器计时并执行业务逻辑
    3、设置setTimeOut,定时器在规定时间后才能再次触发

    var flag = true;
    var time = null;
    
    window.onscroll = function(){  
        if(flag){   //标记变量为true时开始计时
            time = setTimeout(() => {
                console.log('触发')
                flag = true;
            }, 500);
        }
        flag = false; //n秒内flag值为false,不触发计时器
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    效果如下:
    在这里插入图片描述

    四、节流进阶优化

    • 痛点:以上方法将节流函数和业务逻辑放到一起,代码块不优雅,后期难以维护
    • 解决:将节流函数与业务逻辑单独封装
    实现思路

    1、封装业务逻辑

    function task(){
        console.log('触发');
    }
    
    • 1
    • 2
    • 3

    2、封装防抖函数

    • 封装一个名为throttle,且返回值为函数的节流函数,来替代window.onscroll后承接的内容。
    • 因为返回值为函数,所以用闭包思想来实现封装
    function throttle(){
        return function(){
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 节流函数里传入业务逻辑fn()和延迟时间delay
    • 初始化标记变量flag,值为true
    • 优化全局变量flag,time,把变量time作为私有变量放入throttle函数中
    function throttle(fn,delay){
        var flag = true;
        var time = null;
        return function(){
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、组装业务逻辑函数和防抖函数(完整代码)

     window.onscroll = throttle(task, 500)
     
    //业务逻辑
    function task(){
        console.log('触发');
    }
    //节流函数
    function throttle(fn,delay){
        var flag = true;
        var time = null;
        return function(){
            if(flag){
                time = setTimeout(() => {
                    fn.call(this)// 注:此处需改变this指针,否则业务逻辑中的this指向window
                    flag = true;
                }, delay)
            }
            flag = false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    需求变化频繁的情况下,如何实施自动化测试
    Springboot基于web的游泳馆信息管理系统 毕业设计-附源码281444
    lotus MaxStorage 限制存储空间使用
    ESP32-C3入门教程 基础篇⑪——Non-Volatile Storage (NVS) 非易失性存储参数的读写
    Rust权威指南之认识所有权
    @SpringBootApplication配置了scanBasePackages导致请求一直404,分析下原因
    IT面试参考
    idea常用快捷键持续更新
    python快速保存微信公众号文章中的图片(可指定多个文章)
    天啦,从Mongo到ClickHouse我到底经历了什么?
  • 原文地址:https://blog.csdn.net/qq_40228736/article/details/126473250