在js中函数的防抖和节流

博客介绍了函数防抖和节流产生的原因,一些浏览器事件会在短时间内快速触发多次,导致性能问题,而防抖和节流可解决此问题。还分别阐述了函数防抖和节流的概念,防抖是将一系列连续事件只处理一次,节流是按固定频率处理一段时间内的事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、函数的防抖和节流产生的原因

  1. 有一些浏览器事件可以在很短的事件内快速触发多次,例如 调整窗口大小 或 向下滚动 页面。例如,如果将事件监听器绑定到窗口滚动事件上,并且用户继续非常快速地向下滚动页面,你的事件可能会在3秒的范围内被触发数千次。这可能会导致一些严重的性能问题
  2. 在一些事件中,如滚动、窗口调整大小,或键盘按下的事件时,一定要提及函数防抖动和函数节流来提升页面速度和性能
  3. 直接绑定函数到scroll事件是非常错误的决定,当用户滚动页面时,页面可能会变得非常慢甚至未响应。而函数防抖和函数节流是解决这个问题的一种方式,通过限制需要经过的事件,直至再次调用函数,在处理一些高频率触发的 DOM 事件的时候,它们都能极大提高用户体验
  4. 为了提高页面性能,有时需要对高频率触发的事件(scrllo, resize, mousemove, touchmove)进行防抖(Debounce)或者节流(Throttle)处理

二、函数的防抖

  1. 如果一个事件被频繁触发多次,并且触发的时间间隔过短,则防抖函数可以使得对应的事件处理函数只执行一次
  2. 把一系列连续的事件,只处理一次,即只调用一次事件处理程序,强调一系列连续触发的事件
  3. 一系列事件:
    1)在指定时间间隔(距离上次触发的时间)内触发的相同类型事件视为一个系列的事件
    2)举例:假如scroll事件分别在0,1,3,7,8时间触发了事件A,B,C,D,E。假如规定时间间隔为2,则A,B,C属于一个系列(D,C之间间隔为3);D,E属于一个系列。防抖的目的就是把A,B,C构成的系列(或者D,E构成的系列)事件合并成一个,即只执行A或者C(D或者E)
  4. 代码如下:
// debounce函数用来包裹我们的事件处理方法
function debounce(fn, delay){
    // 持久化一个定时器
    let timer = null
    
    // 闭包函数可以访问timer
    return function(){
        // 通过 this 和 arguments 获得函数的作用域和参数
        let context = this
        let args = arguments
        // 如果事件被触发,清除timer并重新开始计时
        clearTimeout(timer)
        timer = setTimeout(function() {
            fn.apply(context, args)
        }, delay)
    }
}

function foo(){
    console.log('You are scrolling!')
}

document.addEventListener('scroll', debounce(foo, 50));
  1. 防抖的简单实现:
    1)代码如下:
var debounce = function(func, delay){
        var timeHandle = null;
        return function(){
            var context = this, 
                args = arguments, 
                later = function(){
                    func.apply(context, arguments);
                };
            if(timeHandle) {
                clearTimeout(timeHandle); // 覆盖上次事件回调:清除上次未执行的回调,新建个回调执行定时器
            }
            timeHandle = setTimeout(later, delay);
        }
    }

2)图示说明:事件处理程序在一系列事件触发后delay时间后执行
在这里插入图片描述

三、函数的节流

  1. throttle 的概念理解稍微容易一些,如果一个事件被频繁触发多次,节流函数可以按照固定频率去执行对应的事件处理方法
  2. 一段时间内的事件,只处理一次,即只调用一次事件处理程序。强调一段时间内
  3. 代码如下:
function throttle(fn, threshold){
    var last
    
    var timer
    
    threshold || (threshold = 250)
    
    return function(){
        let context = this
        let args = arguments
        
        var now = +new Date()
        
        if(last&&now<last+threshold){
            clearTimeout(timer)
            
            timer = setTimeout(function(){
                last = now
                fn.apply(context, args)
            },threshold)
        }else {
            last = now
            fn.apply(context, args)
        }
    }
}
  1. 节流的简单实现:
    代码如下:
var throttle = function(func, delay){
        var previous = 0;
        return function(){
            var context = this,
                args = arguments,
                curr = Date.now();
            // 如果时间间隔超过delay时间,则执行回调
            if(curr - previous >= delay){
                previous = curr; // 更新previous
                func.apply(context, args);
            }
            console.log(curr)
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值