zoukankan      html  css  js  c++  java
  • 浅谈JS函数防抖及应用场景

    【前言】

    在工作中,我们可能碰到这样的问题:

    • 用户在搜索的时候,在不停敲字,如果每敲一个字我们就要调一次接口,接口调用太频繁,给卡住了。
    • 用户在阅读文章的时候,我们需要监听用户滚动到了哪个标题,但是每滚动一下就监听,那样会太过频繁从而占内存,如果再加上其他的业务代码,就卡住了。

    所以,这时候,我们就要用到 防抖与节流 了。

    那么,讲到 防抖与节流,我们可以顺带探秘下 重绘与回流

    说起 重绘与回流,我们就顺带把 浏览器输入 URL 后发生的事情 也关注一下,从而引出 DNSTCP 等知识点,最终串起来构成本文的轮廓,方便 jsliang 和小伙伴们对这块知识的整理与记忆。

    【主体】

    本节主要介绍函数防抖debounce

    下面我们有段防抖小案例代码。

    如果小伙伴们手头有电脑,并感兴趣想先自己思考下什么是防抖。可以将代码复制到浏览器,尝试点击按钮,并关注下控制台,看看 Console 是如何打印的。

    如果小伙伴们手头没有电脑,那么咱一起先瞅瞅代码实现,再看看下面 GIF 演示。(这样效果没有自己敲的直白有效)

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>防抖</title>
    </head>
    <body>
      <button id="debounce">点我防抖!</button>
    
      <script>
        window.onload = function() {
          // 1、获取这个按钮,并绑定事件
          var myDebounce = document.getElementById("debounce");
          myDebounce.addEventListener("click", debounce(sayDebounce));
        }
    
        // 2、防抖功能函数,接受传参
        function debounce(fn) {
          // 4、创建一个标记用来存放定时器的返回值
          let timeout = null;
          return function() {
            // 5、每次当用户点击/输入的时候,把前一个定时器清除
            clearTimeout(timeout);
            // 6、然后创建一个新的 setTimeout,
            // 这样就能保证点击按钮后的 interval 间隔内
            // 如果用户还点击了的话,就不会执行 fn 函数
            timeout = setTimeout(() => {
              fn.call(this, arguments);
            }, 1000);
          };
        }
    
        // 3、需要进行防抖的事件处理
        function sayDebounce() {
          // ... 有些需要防抖的工作,在这里执行
          console.log("防抖成功!");
        }
    
      </script>
    </body>
    </html>

    很好,相信小伙伴们已经看完了代码,下面我们看看它的演示:

    这时候,我们可以抛出防抖的概念了:

    • 防抖任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。

    结合上面的代码,我们可以了解到,在触发点击事件后,如果用户再次点击了,我们会清空之前的定时器,重新生成一个定时器。意思就是:这件事儿需要等待,如果你反复催促,我就重新计时!

    空讲无益,show you 场景:

    • 有个输入框,输入之后会调用接口,获取联想词。但是,因为频繁调用接口不太好,所以我们在代码中使用防抖功能,只有在用户输入完毕的一段时间后,才会调用接口,出现联想词。

    小伙伴们可以尝试看着上面的案例,先自己实现一遍这个场景的解决,如果感觉不行,那就看:《防抖和节流的应用场景和实现》

    知识点补充:何为 arguments
    首先,后端转前端的同学,可以将 arguments 理解为能实现重载函数功能的工具。
    然后,我们举个例子:在 function test() 这个方法中,由于我们不确定变量有多少,比如 test("jsliang", 24),又或者 test("LiangJunrong", "jsliang", "24"),这时候只需要在函数 test 中用 arguments 接收就行了。
    最后,在 function test() { let arr1 = argument[0] } 中,arr1 就可以获取到传进来的第一个变量。
    所以fn.call(this, arguments) 其实是将不确定变量替换到函数中了。

    参考资料 1:《闲聊 JS 中的 apply 和 call》
    参考资料 2:《js 中 arguments 的用法》

     
    案例2:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>demo</title>
    </head>
    <body>
        <input type="text" name="search">
    
        <script type="text/javascript">
            var searchInput = document.querySelector('input[name="search"]');
            /*绑定事件*/
            searchInput.addEventListener('keyup',debounce(getInputValue),false);
            /* 防抖函数 */
            function debounce(fn){
                var timer = null;
                return function(){
                    if(timer){
                        clearTimeout(timer)
                    }
                    timer = setTimeout(()=>{
                        fn.call(this,arguments)
                    },500)
                }
            }
            /* 调用获取输入值 */
            function getInputValue(){
                console.dir(this.value)
            }
        </script>
    </body>
    </html>

    .

  • 相关阅读:
    [SUCTF 2019]Pythonginx
    [极客大挑战 2019]BuyFlag
    [GXYCTF2019]Ping Ping Ping
    git 常用命令记录
    webpack4.X + react-router 路由跳转
    webpack4.X + react搭建
    windows 下 node 安装 react
    valueOf()、toString()
    isFinite()
    Javascript 闭包
  • 原文地址:https://www.cnblogs.com/fightjianxian/p/12077451.html
Copyright © 2011-2022 走看看