JavaScript防抖与节流,深入浅出,一本正经讲透彻

简介: JavaScript防抖与节流,深入浅出,一本正经讲透彻

目录


一、函数防抖(debounce)


1. 什么是防抖?


二.、函数节流


2.1 定时器实现


2.2 时间戳实现


2.3 时间戳+定时器


最后


一、函数防抖(debounce)

1. 什么是防抖?

函数防抖:在频繁触发某一个事件时,一段时间内不再触发该事件后才会去调用对应的回调函数,在设定间隔时间内如果下一次事件被触发, 那么就重新开始定时器,直到事件触发结束。


规定时间内没有继续触发事件的前提下,再去调用事件处理函数;


具体如下面的例子所示:

/*定义防抖函数
  * func:传入一个函数,事件不再持续触发时会调用该函数
  * delay:定义持续多久后执行传入的回调函数
  * */
  function debounce(func,delay) {
    let timer = null  // 用于保存定时器
    return function (...args) {
      // 如果定时器存在,清除定时器,随后重新设置timer
      if(timer !== null) clearTimeout(timer)
      timer = setTimeout(func, delay)  // 超过delay为接收到事件会调用这里的func   必要的额时候可以修改func的this指向  由于timer对外部存在引用,因此不会被销毁
    }
  }
  /*事件处理函数*/
  function testDeBounce(){
    console.log('你看我执行了几次??')
  }
  // 接收debounce返回的函数
  const temp = debounce(testDeBounce(),1000)
  /*绑定事件,测试防抖函数*/
  window.addEventListener('scroll',()=>{
    temp()
  }); // 这样写最少调用一次事件处理函数,最多也不会多余下面的写法执行的次数
  window.addEventListener('scroll', testDeBounce); // 如果这样写的话,每当页面滚动就会调用事件处理函数

总结一下思路:


1.定义一个节流函数


2.函数内部使用一个变量保存定时器


3.返回一个函数,函数内部定义:如果定时器已经存在就清除定时器,重新设置定时器


4.定义一个变量来接收debounce返回的函数


5.在事件的回调函数中直接调用上一步的变量接收的方法


二.、函数节流

函数节流:在事件持续触发的前提下,保证一定时间段内只调用一次事件处理函数,就是函数节流;


函数节流实现的方式:定时器、时间戳、定时器+时间戳;


2.1 定时器实现

思路:


1.定义节流函数throttle


2.定义timer保存定时器


3.返回一个函数。函数内部定义:如果定时器不存在,设置定时器,间隔某一时间后将timer设置为null,如果在这之前事件再次触发,则定时器中的回调无效


<button>这是一个孤独的按钮</button>

/*
  * 定义定时器节流函数
  * func:传入事件处理函数
  * delay:在delay指定的时间内定时器回调无效
  * */
  function throttle(func,delay) {
    let timer = null
    const context = this
    return function(...args){
      // 如果定时器不存在
      if(!timer){
        timer = setTimeout(()=>{
          func.apply(context,args) // 考虑返回的函数调用的环境,因此这里不直接使用this
          timer = null // delay之后清除定时器
        },delay)
      }
    }
  }
  function test() {
    console.log('啊啊啊!')
  }
  const temp = throttle(test,1000)
  document.querySelector('button').addEventListener('click',()=>{
    temp()
  })

2.2 时间戳实现

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(Math.random());        
}        
window.addEventListener('scroll', throttle(handle, 1000));

2.3 时间戳+定时器

// 节流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(Math.random());
} 
window.addEventListener('scroll', throttle(handle, 1000));1.// 节流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(Math.random());
} 
window.addEventListener('scroll', throttle(handle, 1000));

最后

想跟博主交朋友的可以查找,公_号❤:前端老实人,跟博主一起探讨学习哦❤

如果对您有帮助,希望能给个👍评论收藏三连!

博主为人老实,无偿解答问题哦❤


相关文章
|
7月前
|
前端开发 JavaScript Java
【JavaScript】JavaScript 防抖与节流:以游戏智慧解锁实战奥秘
【JavaScript】JavaScript 防抖与节流:以游戏智慧解锁实战奥秘
76 3
|
4月前
|
前端开发 JavaScript UED
JavaScript防抖和节流的使用及区别
JavaScript防抖和节流的使用及区别
119 57
|
7月前
|
JavaScript 前端开发 UED
深入理解JavaScript中的节流与防抖技术
理解并合理运用节流与防抖技术,可以帮助我们优化事件处理函数的执行频率,从而提升应用的性能和用户体验。这两种技术通过减少不必要的计算和DOM操作,使得Web应用程序能够更加流畅地运行。 通过掌握防抖和节流的实现原理及应用场景,开发者可以更加灵活地编写高效且性能优化的代码,对于面对高频事件处理时尤其重要。在开发中合理选择使用防抖或节流,将直接影响到应用的响应性和效率。
69 1
|
3月前
|
前端开发 JavaScript UED
JavaScript 中的函数防抖与节流详解及实用场景
在前端开发中,处理用户频繁触发的事件,如输入框的输入、按钮点击、窗口调整大小等,常常需要优化性能以减少无效操作。为此,函数防抖(debounce)和函数节流(throttle)是两种常见的性能优化手段。本文将详细介绍两者的区别与实现,并探讨它们的应用场景。
60 1
|
4月前
|
JavaScript 前端开发
js防抖函数返回值问题解决方案
本文介绍了如何在JavaScript中创建一个带有返回值的防抖函数,通过结合Promise来实现。这种防抖函数可以在事件触发一定时间后再执行函数,并能处理异步操作的返回值。文章提供了防抖函数的实现代码和如何在实际项目中使用该防抖函数的示例。
47 1
|
5月前
|
JavaScript 前端开发 UED
JS 防抖与节流
防抖和节流是优化高频事件处理的技术。针对如`scroll`、`resize`等频繁触发的事件,它们能有效减少不必要的回调执行,节省资源。防抖确保在一段时间内仅执行最后一次操作,适用于输入框自动补全等场景;而节流则按固定间隔执行函数,适合拖拽、滚动事件。通过简单的JavaScript实现,可以显著提升应用性能和用户体验。
47 1
JS 防抖与节流
|
8月前
|
JavaScript 前端开发 UED
js的防抖节流
js的防抖节流
44 1
|
8月前
|
JavaScript 前端开发 UED
js的节流
js的节流
44 0
|
8月前
|
测试技术
js_防抖与节流(闭包的使用)
js_防抖与节流(闭包的使用)
55 0
|
2月前
|
JavaScript 前端开发
JavaScript中的原型 保姆级文章一文搞懂
本文详细解析了JavaScript中的原型概念,从构造函数、原型对象、`__proto__`属性、`constructor`属性到原型链,层层递进地解释了JavaScript如何通过原型实现继承机制。适合初学者深入理解JS面向对象编程的核心原理。
36 1
JavaScript中的原型 保姆级文章一文搞懂