防抖&节流


<!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>
</head>

<body>
    <input type="text" id="search">

    <script>
        //https://www.jianshu.com/p/c8b86b09daf0

        // 目的:尽量在用户输入完之后,才发送一次http请求,减少服务器压力
        // 1.每次输入使用定时器延迟发送请求
        // 2.使用闭包保存定时器id,每次输入,如果旧定时器没有执行就清除旧定时器,设置新的定时器
        // 3.那么当用户不输入一段delay时间时就可以只发送一次请求。

        function debounce(fn, delay) {
            let timer = null;

            //返回一个闭包函数 
            return function (e) {
                //e事件对象 之所可以接收e

                //判断当前输入是否有定时器
                if (timer) {

                    //有计时器,那么阻止之前的计时器执行
                    clearTimeout(timer);
                    console.log('清除之前的定时器', timer);

                }

                //保存settimeout
                //使用箭头函数,将this指向由window对象变为input节点对象

                timer = setTimeout(() => {
                    console.log();

                    //因为在settimeout的函数体内所以使用call可以立刻执行,当然也可以用bind,但是要手动执行
                    //call和apply的传参不一样 这里e是一个对象,且fn只结束欧一个参数使用call。当然也可以使用argument类数组对象
                    fn.call(this, e);
                    //首先fn是由window调用的,如果不使用箭头函数的this是无法指向input节点对象,
                    //这里的this由闭包函数给予,同时闭包函数被input节点的事件监听调用

                    //正常执行了,清除保存的定时器ID
                    timer = null;

                }, delay)


            }

        }

        let inputNode = document.querySelector('#search');

        inputNode.addEventListener('input', debounce(function (event) {
            // console.log(this === inputNode);//判断是否已经指向了节点 true
            console.log(`发送${this.value}到请求`);
            //访问element的构造函数的原型属性value

            console.log(`用户最后输入的字符为${event.data}`);
            // console.log(event);
        }, 1000))
    </script>
</body>

</html>

文章作者: iamfugui
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 iamfugui !
评论
  目录