快速应对面试中的防抖和节流函数!

定义

1、防抖函数定义

  • 防抖(debounce):触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间

举例说明:

举例:就好像在百度搜索时,每次输入之后都有联想词弹出,这个控制联想词的方法就不可能是输入框内容一改变就触发的,他一定是当你结束输入一段时间之后才会触发。

2、防抖函数的封装

需求:
  • 持续触发不执行
  • 不触发的一段时间之后再执行
思路:
  1. 那么怎么实现上述的目标呢?我们先看这一点:在不触发的一段时间之后再执行,那就需要个定时器呀,定时器里面调用我们要执行的函数,将arguments传入。
  2. 封装一个函数,让持续触发的事件监听是我们封装的这个函数,将目标函数作为回调(func)传进去,等待一段时间过后执行目标函数
  3. 第二点实现了,再看第一点:持续触发不执行。我们先思考一下,是什么让我们的函数执行了呢?是上边的setTimeout。OK,那现在的问题就变成了持续触发,不能有setTimeout。这样直接在事件持续触发的时候,清掉定时器就好了。
封装:
function debounce(fn, delay) {
            let timer = null
            return function () {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    //模拟触发change事件
                    fn.apply(this, arguments)
                    // 清空计时器
                    timer = null
                }, delay);
            }
        }

3、利用防抖函数的实例

<!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>
    <!-- DOM元素 -->
    <input id="input1" type="text">
    <script>
        //防抖函数
        const input1 = document.getElementById('input1')

        function debounce(fn, delay) {
            let timer = null
            return function () {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    //模拟触发change事件
                    fn.apply(this, arguments)
                    // 清空计时器
                    timer = null
                }, delay);
            }
        }
        input1.addEventListener('keyup', debounce(() => {
            console.log(input1.value)
        }, 500))
        // input1.οnkeyup=function(){
        //     console.log(input1.value);
        // }
    </script>
</body>

</html>

展示结果:
在这里插入图片描述
小结:

如上图所示,我们需要监听输入框里面的value值将其传递给后台,用户输入的每一次都将发送给后台,那么就会造成网络的堵塞,浪费资源,我们封装一个防抖函数,在规定的时间内,获取输入框的值,若期间多次重复输入的话,每一次输入,我们就会重新计算时间,知道最后一次触发该事件,那么防抖函数就有效的解决了这个问题!

4、节流函数定义

  • 节流(thorttle):高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率

举例说明:

举例:预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。就好像你在淘宝抢购某一件限量热卖商品时,你不断点刷新点购买,可是总有一段时间你点上是没有效果,这里就用到了节流,就是怕点的太快导致系统出现bug。

5、节流函数的封装

需求
  • 持续触发并不会执行多次
  • 到一定时间再去执行
思路
  1. 思考一下,持续触发,并不会执行,但是到时间了就会执行。抓取一个关键的点:就是执行的时机。要做到控制执行的时机,我们可以通过一个开关,与定时器setTimeout结合完成。
  2. 函数执行的前提条件是开关打开,持续触发时,持续关闭开关,等到setTimeout到时间了,再把开关打开,函数就会执行了。
  3. 这样,就实现了节流,节流还可以用时间间隔去控制,就是记录上一次函数的执行时间,与当前时间作比较,如果当前时间与上次执行时间的时间差大于一个值,就执行。
封装
function throttle(fn, delay = 100) {
            let timer = null
            return function () {
                if (timer) {
                    return
                }
                timer = setTimeout(() => {
                    fn.apply(this, arguments)
                    timer = null
                }, delay);
            }
        }

6、利用节流函数的实例

<!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>
    <!-- //DOM元素 -->
    <div id="div1" draggable="true" style="width:100px;height:100px;background:pink">可拖拽</div>

    <script>
        //节流函数
        const div1 = document.getElementById('div1')

        function throttle(fn, delay = 100) {
            let timer = null
            return function () {
                if (timer) {
                    return
                }
                timer = setTimeout(() => {
                    fn.apply(this, arguments)
                    timer = null
                }, delay);
            }
        }
        div1.addEventListener('drag', throttle(function (e) {
            console.log(e.offsetX, e.offsetY)
        }, 200))
    </script>

</body>

</html>

展示结果:
在这里插入图片描述
小结:

如上图所示,鼠标拖动物块儿,我们打印出它的位置坐标,我们监听鼠标移动事件,若没有节流函数的辅助,那么只要鼠标一拖动,那么控制台就会持续输出他的位置坐标,为了防止控制台监听打印我们不需要的数据,节流函数,有效的结局了控制台持续输出的问题,让其在规定的时间内输出一次该坐标,每次移动控制台有规律的输出当前的坐标!

7、防抖函数和节流函数有什么区别呢(一句话概括)?

区别:防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值