js 防抖 节流 JavaScript

js 防抖 节流 JavaScript

实际工作中,通过监听某些事件,如scroll事件检测滚动位置,根据滚动位置显示返回顶部按钮;如resize事件,对某些自适应页面调整DOM的渲染;如keyup事件,监听文字输入并调用接口进行模糊匹配等等,这些事件处理函数调用的频率如果太高,会加重浏览器的负担,减弱性能,造成用户体验不好。此时需要采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时不影响原来效果。

函数防抖(debounce)

当持续触发事件时,一段时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前就触发了事件,延时重新开始。
函数防抖的应用场景,最常见的就是用户注册时候的手机号码验证和邮箱验证了。只有等用户输入完毕后,前端才需要检查格式是否正确,如果不正确,再弹出提示语。

clipboard.png

上图中,持续触发scroll事件时,并不执行handle函数,当1000毫秒内没有触发scroll事件时,才会延时触发scroll事件;
上面原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
代码如下:

// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
    clearTimeout(timer); // 清除未执行的代码,重置回初始化状态

    timer = setTimeout(function(){
        console.log("函数防抖");
    }, 1000);
};

防抖函数的封装使用

/**
 * 防抖函数
 * @param method 事件触发的操作
 * @param delay 多少毫秒内连续触发事件,不会执行
 * @returns {Function}
 */
function debounce(method,delay) {
    let timer = null;
    return function () {
        let self = this,
            args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function () {
            method.apply(self,args);
        },delay);
    }
}
window.onscroll = debounce(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滚动条位置:' + scrollTop);
},1000)

另一种写法

// 防抖
function debounce(fn, wait) {    
    var timeout = null;    
    return function() {        
        if(timeout !== null)   clearTimeout(timeout);        
        timeout = setTimeout(fn, wait);    
    }
}
// 处理函数
function handle() {    
    console.log("函数防抖"); 
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));
函数节流(throttlo)

当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
函数节流应用的实际场景,多数在监听页面元素滚动事件的时候会用到。

clipboard.png

上图中,持续触发scroll事件时,并不立即执行handle函数,每隔1000毫秒才会执行一次handle函数;
函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。如果空闲,则可以正常触发方法执行。
代码如下:

// 函数节流 定时器
var canRun = true;
document.getElementById("throttle").onscroll = function(){
    if(!canRun){
        // 判断是否已空闲,如果在执行中,则直接return
        return;
    }

    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);
};

节流函数的封装使用

//节流throttle代码(时间戳)
var throttle = function(func, delay) {            
  var prev = Date.now();            
  return function() {                
    var context = this;                
    var args = arguments;                
    var now = Date.now();                
    if (now - prev >= delay) {                    
      func.apply(context, args);                    
      prev = Date.now();                
    }            
  }        
}        
function handle() {            
  console.log("函数节流");        
}        
window.addEventListener('scroll', throttle(handle, 1000));


//节流throttle代码(定时器)
var throttle = function(func, delay) {            
    var timer = null;            
    return function() {                
        var context = this;               
        var args = arguments;                
        if (!timer) {                    
            timer = setTimeout(function() {                        
                func.apply(context, args);                        
                timer = null;                    
            }, delay);                
        }            
    }        
}        
function handle() {            
    console.log("函数节流");        
}        
window.addEventListener('scroll', throttle(handle, 1000));


// 节流throttle代码(时间戳+定时器):
var throttle = function(func, delay) {     
    var timer = null;     
    var startTime = Date.now();     
    return function() {             
        var curTime = Date.now();             
        var remaining = delay - (curTime - startTime);             
        var context = this;             
        var args = arguments;             
        clearTimeout(timer);              
        if (remaining <= 0) {                    
            func.apply(context, args);                    
            startTime = Date.now();              
        } else {                    
            timer = setTimeout(func, remaining);              
        }      
    }
}
function handle() {      
    console.log("函数节流");
} 
window.addEventListener('scroll', throttle(handle, 1000));

用时间戳+定时器,当第一次触发事件时马上执行事件处理函数,最后一次触发事件后也还会执行一次事件处理函数

欢迎关注

JavaScript中的防抖节流是为了控制函数的执行频率,以提高性能和优化用户体验。 防抖(debounce)是指在一定的时间间隔内,只执行最后一次操作。引用提供了一个自定义的防抖函数示例。该函数接受两个参数:待执行的函数和延迟时间。在函数调用时,如果在延迟时间内再次触发了函数调用,则会清除之前的定时器,重新设置一个新的定时器,以延迟函数的执行。 节流(throttle)是指在一定的时间间隔内,限制函数的执行频率。引用和提供了两个不同的节流函数示例。这些节流函数都可以指定一个时间间隔,只有在这个时间间隔内函数没有被执行过才能继续执行。其中,引用实现了一个基于定时器的节流函数,而引用则是一个基础版的节流函数,使用了时间戳来判断是否达到执行条件。 需要注意的是,防抖节流可以根据具体的需求和场景来选择使用,以达到更好的效果。防抖适用于需要等待用户停止操作后才执行的场景,而节流适用于需要限制函数执行频率的场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [JavaScript 防抖节流的实现](https://blog.csdn.net/weixin_43853746/article/details/122654312)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【JavaScript防抖(debounce)、节流(throttling)](https://blog.csdn.net/qq_46658751/article/details/123386755)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值