一、函数防抖

定义:事件在n秒后触发,不管在这个时间节点中执行多少次事件,只有最后一次事件是触发

对比场景:游戏中的回城 DNF中的抬枪

使用场景:

  1. - 上拉刷新,下来加载--scroll事件
  2. - resize
  3. - 文本的输入验证(连续输入文字后发送Ajax请求进行验证,验证一次就够了)

1-1 原生JavaScript-button实现防抖

  1. <body>
  2. <!-- 什么叫函数防抖:事件n秒后触发,不管在这个时间段中执行多少次事件,该事件只针对
  3. 最后一次触发 -->
  4. <button id="btn">函数防抖</button>
  5. <script>
  6. var btn = document.getElementById("btn");
  7. var timer;
  8. btn.onclick = function(){
  9. if(timer){
  10. clearTimeout(timer);
  11. }
  12. timer = setTimeout(()=>{
  13. console.log("loading");
  14. timer = null
  15. },500)
  16. }
  17. /*
  18. 3s
  19. */
  20. </script>
  21. </body>

1-2 input实现防抖

  1. <body>
  2. <input type="text" id="input">
  3. <script>
  4. var input = document.getElementById("input");
  5. var timer;
  6. input.addEventListener("keyup",()=>{
  7. if(timer){
  8. clearTimeout(timer);
  9. }
  10. timer = setTimeout(()=>{
  11. console.log(input.value)
  12. timer = null;
  13. },1000)
  14. })
  15. </script>
  16. </body>

1-3 封装防抖

  1. <body>
  2. <input type="text" id="input">
  3. <script>
  4. var input = document.getElementById("input");
  5. var timer
  6. /* 封装防抖函数 */
  7. function debounce(fn,delay=500){
  8. if(timer){
  9. clearTimeout(timer);
  10. }
  11. timer = setTimeout(fn,delay)
  12. }
  13. input.addEventListener("keyup",()=>{
  14. debounce(()=>{
  15. console.log(input.value);
  16. })
  17. })
  18. </script>
  19. </body>

1-4 闭包封装防抖

  1. <body>
  2. <input type="text" id="input">
  3. <script>
  4. var input = document.getElementById("input");
  5. input.addEventListener("keyup",debounce(()=>{
  6. console.log(input.value);
  7. }))
  8. /* 闭包 1、返回值是一个函数 2、返回函数使用返回函数外面定义的局部变量
  9. 闭包好处:不会造成全局的污染
  10. */
  11. function debounce(fn,delay=500){
  12. let timer = null;
  13. return function(){
  14. if(timer){
  15. clearTimeout(timer);
  16. }
  17. timer = setTimeout(fn,delay);
  18. }
  19. }
  20. </script>
  21. </body>

.1-5 apply改变this

  1. <body>
  2. <input type="text" id="input">
  3. <script>
  4. var input = document.getElementById("input");
  5. input.addEventListener("keyup",debounce(function(){
  6. console.log(this.value)
  7. }))
  8. /* 闭包 1、返回值是一个函数 2、返回函数使用返回函数外面定义的局部变量
  9. 闭包好处:不会造成全局的污染
  10. */
  11. function debounce(fn,delay=500){
  12. let timer = null;
  13. return function(){
  14. console.log(this)
  15. if(timer){
  16. clearTimeout(timer);
  17. }
  18. timer = setTimeout(()=>{
  19. console.log(this)
  20. fn.call(this);
  21. },delay);
  22. }
  23. }
  24. /* function才能使用call,apply */
  25. </script>
  26. </body>

二、函数节流

2-1 原生JavaScript-button实现节流

单位时间之内,只触发一次,如果在这个单位时间之内多次触发,最终也只会执行一次

使用场景

  1. 1、射击游戏中的鼠标事件
  2. 2input输入框搜索联想
  1. <style>
  2. #app{
  3. width: 100px;
  4. height: 100px;
  5. border: 1px solid #333;
  6. }
  7. </style>
  8. </head>
  9. <body>
  10. <div id="app" draggable="true">
  11. 可拖拽
  12. </div>
  13. <script>
  14. /* 单位时间之内,只触发一次,如果在这个单位时间之内多次触发,最终也只会执行一次 */
  15. /*
  16. 1、射击游戏中的鼠标事件
  17. 2、input输入框搜索联想
  18. */
  19. let timer = null;
  20. const app = document.getElementById("app");
  21. app.addEventListener("drag",function(e){
  22. if(timer){
  23. return
  24. }
  25. timer = setTimeout(()=>{
  26. console.log(e.offsetX,e.offsetY);
  27. timer = null
  28. },1000)
  29. })
  30. </script>
  31. </body>

2-2 封装节流函数

  1. <style>
  2. #app{
  3. width: 100px;
  4. height: 100px;
  5. border: 1px solid #333;
  6. }
  7. </style>
  8. </head>
  9. <body>
  10. <div id="app" draggable="true">
  11. 可拖拽
  12. </div>
  13. <script>
  14. const app = document.getElementById("app");
  15. app.addEventListener("drag",throttle(function(e){
  16. console.log(e.offsetX,e.offsetY);
  17. }))
  18. function throttle(fn,delay=500){
  19. let timer = null;
  20. return function(){
  21. if(timer){
  22. return
  23. }
  24. timer = setTimeout(()=>{
  25. /* arguments是函数内部的一个对象,接收函数传递过来的参数 */
  26. console.log(arguments);
  27. fn.apply(this,arguments)
  28. timer = null
  29. },delay)
  30. }
  31. }
  32. </script>