防抖: 事件在n秒后执行,如果在n秒内被再次出发,会重新计算时间,直到n 秒后才执行。简单点就是一个事件,一个事件在n秒内被再次触发,事件不会执行,只有过了n秒才执行
- 防抖应用:scroll滚动事件的出发;
- 网络请求一些应用;
- 表单验证
- 按钮提交事件
- 浏览器窗口缩放
- 搜索框输入
还是看代码吧
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> .container { 100%; height: 200px; background-color: rgb(166, 187, 184); text-align: center; line-height: 200px; background-size: 30px; } </style> </head> <body> <div class="container"></div> <script> let dv1 = document.querySelector(".container"); let counter = 0; function doSome() { dv1.innerHTML = counter++; } dv1.addEventListener('mousemove', doSome) </script> </body> </html>
当鼠标在这个盒子移动会频繁出发这个事件,影响性能,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> .container { 100%; height: 200px; background-color: rgb(166, 187, 184); text-align: center; line-height: 200px; background-size: 30px; } </style> </head> <body> <div class="container"></div> <script> let dv1 = document.querySelector(".container"); let counter = 0; function doSome() { dv1.innerHTML = counter++; } // dv1.addEventListener('mousemove', doSome) dv1.addEventListener('mousemove', debounce(doSome,300)) function debounce(fun, wait) { let timer = null; return function () { clearTimeout(timer); timer = setTimeout(() => { fun.apply(this, arguments); }, wait); }; } </script> </body> </html>
2节流: 如果你持续触发事件,每隔一段时间,只执行一次事件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> .container { 100%; height: 200px; background-color: rgb(166, 187, 184); text-align: center; line-height: 200px; background-size: 30px; } </style> </head> <body> <div class="container"></div> <script> let dv1 = document.querySelector(".container"); let counter = 0; function doSome() { dv1.innerHTML = counter++; } // dv1.addEventListener('mousemove', doSome) // dv1.addEventListener("mousemove", debounce(doSome, 300)); dv1.addEventListener('mousemove',throttle(doSome, 1000)) // 2、节流函数体 function throttle(fn) { // 4、通过闭包保存一个标记 let canRun = true; return function () { // 5、在函数开头判断标志是否为 true,不为 true 则中断函数 if (!canRun) { return; } // 6、将 canRun 设置为 false,防止执行之前再被执行 canRun = false; // 7、定时器 setTimeout(() => { fn.call(this, arguments); // 8、执行完事件(比如调用完接口)之后,重新将这个标志设置为 true canRun = true; }, 1000); }; } </script> </body> </html>
// 2、防抖功能函数,接受传参 function debounce(fn) { // 4、创建一个标记用来存放定时器的返回值 let timeout = null; return function() { // 5、每次当用户点击/输入的时候,把前一个定时器清除 clearTimeout(timeout); // 6、然后创建一个新的 setTimeout, // 这样就能保证点击按钮后的 interval 间隔内 // 如果用户还点击了的话,就不会执行 fn 函数 timeout = setTimeout(() => { fn.call(this, arguments); }, 1000); }; }
引用:https://juejin.im/post/5c87b54ce51d455f7943dddb#heading-3