JS-防抖和节流详解

防抖

概念: 指的是延迟规定的动作,若在延迟时间内,再次触发了,就会重新计时

这一般应用于输入框搜索的时候,进行搜索优化,不能在用户输入未结束时就请求后台,会使服务器压力过大

代码演示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div>
        <input type="text" id="inputD">
    </div>
</body>
<script>
    //防抖,指的是在事件执行n秒之后执行回调,当在n秒内又被触发,则重新计时
    //辅助方式 setTimeout
    let inputD = document.getElementById('inputD');
    //添加事件
    inputD.addEventListener('keyup', function() {
            //获取输入值    
            let value = inputD.value;
            mockAjax(value);//没加防抖之前
        })
        //模拟请求
    function mockAjax(params) {
        console.log('发送请求', params);
    }
</script>

</html>

这是没加防抖操作之前的,此时会发现每次键入字符都会输出:

发送请求 w
发送请求 ww
发送请求 www

此时加入防抖:
1.加入定时器,此时只是延迟发生了,还是会触发三次

inputD.addEventListener('keyup', function() {
            //获取输入值    
            let value = inputD.value;
            // mockAjax(value);//没加防抖之前
            setTimeout(() => {
                mockAjax(value)
            }, 500);
        })

2.因为它多次触发,那就需要clearTimeout方法来清除定时器
这时候想到了防抖的含义,不就是每次触发的时候,重新计时吗,那么,我定义一个全局的定时器id,是做防抖的定时器,在触发的方法内部清除掉id,那么不就是又重新计时了.而且clearTimeout方法兼容性很好,当我传一个null参数,也不会报错.所以最后的代码如下

let inputD = document.getElementById('inputD');
    //添加事件
    let id = null;
    inputD.addEventListener('keyup', function() {
            //获取输入值    
            let value = inputD.value;
            // mockAjax(value);//没加防抖之前
            clearTimeout(id);//删除计时器,重新计时
            id = setTimeout(() => {
                mockAjax(value)
            }, 500);
        })
        //模拟请求
    function mockAjax(params) {
        console.log('发送请求', params);
    }

这时候去页面上请求,会发现,不会每个字符都打印,除非你键入一个字符停留的时间超过500ms

发送请求 ww
发送请求 wwwww
发送请求 wwwwwas

节流

概念: 设定一个时间段,在这个时间段内,让函数只执行一次

一般在实际开发中使用的比较少,但是面试会作为一个防抖连带的问题提出.
这里使用一个滚轮事件做说明

需求:当滚轮滚动的时候,每2s输出一次

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    body {
        height: 2000px;
    }
</style>

<body>

</body>
<script>
    //函数节流:设定一个时间,让函数在特定的时间内只执行一次,不会频繁执行
    //辅助:setTimeout flag

    let body = document.getElementsByTagName('body')[0];

    body.onscroll = () => {
        //未节流之前
        console.log('触发打印');
    }
</script>

</html>

此时控制台输出n次的’触发打印’
下面进行节流操作

1.加定时器,定时2秒钟触发打印一次,但是会发现它只是延迟输出了,2s内滑动鼠标还是会打印很多次

let body = document.getElementsByTagName('body')[0];

    body.onscroll = () => {
        //未节流之前
        setTimeout(() => {
            console.log('触发打印');
        }, 2000);
    }

2.加标识,flag定义为是否到2s
考虑一下,setTimout执行的时候,刚好是2s,这时候将flag改变状态,这时候又重新开始计时了,等到2s之后触发打印函数

  let body = document.getElementsByTagName('body')[0];
    let flag = true; //节流标识,是否到两秒 默认是true,第一次要进入到if里面
    body.onscroll = () => {
        if (flag) {
            flag = false;
            //如果到2s 触发函数
            setTimeout(() => {
                flag = true; //改变状态
                console.log('触发打印');
            }, 2000);

        }

这个时候回到页面上滑动测试,会发现是定时输出的

两者的区别

  1. 防抖是为了使高频函数减少执行的次数的
  2. 节流是时间段内只执行一次,让高频函数只执行一次

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值