原生JS实现防抖和节流
2.1 防抖和节流解决什么问题
降低高频触发次数,提升交互【与后台数据交互,页面交互】性能
2.2 防抖和节流应用场景
应用场景:搜索,鼠标移动,鼠标拖拽,窗口尺寸的改变,窗口的滚动等等
2.3 防抖和节流具体如何实现?
-
防抖实现
-
防抖定义
-
在固定时间【通常300毫秒】内如果有事件触发,则重新计算再延长这个固定时间,如果在固定的时间内没有事件触发,则调用函数
-
-
实现原理:主要通过定时器实现
-
代码:
<!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>Document</title> <style> .box { width:60%; height: 400px; border: 1px solid #f00; margin:10px auto; display: flex; justify-content: center; align-items: center; font-size: 100px; } </style> </head> <body> <h2>防抖</h2> <div class="box"> 1 </div> </body> <script> //获取box const box=document.querySelector('.box') let i=0; box.addEventListener('mousemove',debounce(moveFn,2000),false) function moveFn() { box.textContent=++i; } //写一个防抖函数,降低触发次数 function debounce(fn,wait) { let timer=null return function() { const _this=this const args=arguments //清除定时器 clearTimeout(timer) //启动定时器 timer=setTimeout(function() { fn.apply(_this,args) //call,apply,bind },wait) } } </script> </html>
节流实现
-
节流定义:无论在固定时间内是否有事件触发,节流都会按照固定的时间节点频率触发
-
实现原理:
-
定时器实现
-
代码:
<!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>Document</title> <style> .box { width:60%; height: 400px; border: 1px solid #f00; margin:10px auto; display: flex; justify-content: center; align-items: center; font-size: 100px; } </style> </head> <body> <h2>节流</h2> <div class="box"> 1 </div> </body> <script> //获取box const box=document.querySelector('.box') let i=0; box.addEventListener('mousemove',throttle(moveFn,5000),false) function moveFn(e) { box.textContent=++i; } //节流函数 function throttle(fn,wait) { let timer=null return function() { //保存当前this const _this=this //保存事件 const args=arguments if(!timer) { timer=setTimeout(function() { timer=null fn.apply(_this,args) },2000) } } } </script> </html>
时间戳实现
-
思路:用当前时间减去上一次的时间如果大于指定的时间间隔,就触发,否则不触发
-
代码:
<!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>Document</title> <style> .box { width:60%; height: 400px; border: 1px solid #f00; margin:10px auto; display: flex; justify-content: center; align-items: center; font-size: 100px; } </style> </head> <body> <h2>节流-时间戳</h2> <div class="box"> 1 </div> </body> <script> //获取box const box=document.querySelector('.box') let i=0; box.addEventListener('mousemove',throttle(moveFn,5000),false) function moveFn(e) { box.textContent=++i; } //节流函数 function throttle(fn,wait) { //定义过去时间-上一次 let previous=0 return function() { //保存当前this const _this=this //保存事件 const args=arguments //获取当前时间戳 let nowTime=+new Date() if(nowTime-previous>wait) { //执行fn fn.apply(_this,args) //将本次的时间戳赋值给上一次 previous=nowTime } } } </script> </html>
总结防抖和节流的区别
-
防抖固定时间内如果有事件触发,则会重新计时
-
节流无论固定内是否有事件触发,都会按照固定时间频率执行
-
-