什么是防抖和节流?怎么实现?

1.怎么理解防抖和节流

防抖:一定时间内(定时器延时间)用户频繁的去触发一个事件,只执行最后一次得触发

比如输入框的input事件,每输一个文字就会触发一次,这样频繁的触发会消耗性能。使用防抖后只会在你输入完成后才会触发

节流:控制触发事件的次数,控制多久能触发一次,分为首节流和尾节流

节流可理解为游戏中的技能,释放一个技能后会有技能CD,等CD事件结束才可以再次释放技能

首节流:使用时间戳实现,触发事件后能立即执行

尾节流:使用定时器实现,触发事件后,要经过延时才会执行

2.实现防抖

先说一下实现思路

首先要定义一个变量(timer)用来存放定时器id,触发事件后判断timer是否为空,为空就清除定时器,重新开始,定时器内执行业务代码并将timer改为空

代码:

<!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">
</body>
<script>
    let input = document.querySelector('input')
    // 绑定input事件
    input.oninput = debounce(inputValue, 1000)
    // 封装防抖函数
    function debounce (fn, delay) {
        let timer = null
        return function () {
            // 当有定时器执行是timer不为null,清除定时器重新开始
            if (timer !== null) {
                clearTimeout(timer)
            }
            // 将定时器的返回值id赋值给timer
            timer = setTimeout(() => {
                fn.apply(this, arguments)
                // 执行完业务代码后将timer赋值为null,防止进入上面的if判断
                timer = null
            }, delay)
        }
    }
    // 业务代码
    function inputValue (event) {
        let value = event.target.value
        if (value) {
            console.log(value)
        }
    }
</script>
</html>

3.实现节流

首节流实现思路(时间戳):

1.定义一个变量用来存放旧的(lastTime)时间戳

2.获取最新的时间戳(newTime)

3.使用最新的时间戳(newTime)减去旧的时间戳(lastTime)如果大于设定的时间(delay)就可以再次执行,并将最新时间赋值给旧时间

<!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>
<style>
    .box {
        height: 2000px;
    }
</style>
<body>
    <div class="box"></div>
</body>
<script>
    window.onscroll = throttle(throttleHandle, 2000)
    // 封装首节流
    function throttle (fn, delay) {
        let lastTime = 0
        return function () {
            let newTime = new Date()
            if (delay <= newTime - lastTime) {
                fn.apply(this, arguments)
                lastTime = newTime
            }
        }
    }
    // 业务逻辑代码
    function throttleHandle () {
        console.log('首节流');
    }
</script>
</html>

尾节流实现方法 (定时器):

1.定义一个变量用来存放定时器ID(timer)

2.如果 !timer 为真就进入定时器并将定时器返回值赋值给 timer

3.定时器执行业务代码并将timer赋值为null

<!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>
<style>
    .box {
        height: 2000px;
    }
</style>
<body>
    <div class="box"></div>
</body>
<script>
    window.onscroll = throttle(throttleHandle, 2000)
    // 封装尾节流
    function throttle (fn, delay) {
        let timer = null
        return function () {
            if (!timer) {
                timer = setTimeout(() => {
                    fn.apply(this, arguments)
                    timer = null
                }, delay)
            }
        }
    }
    // 业务逻辑代码
    function throttleHandle () {
        console.log('尾节流');
    }
</script>
</html>

首节流+尾节流实现

<!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>
<style>
    .box {
        height: 2000px;
    }
</style>
<body>
    <div class="box"></div>
</body>
<script>
    window.onscroll = throttle(throttleHandle, 2000)
    function throttle (fn, delay) {
        let lastTime = 0
        let timer = null
        return function () {
            let newTime = Date.now()
            let remaining = delay - (newTime - lastTime)
            clearTimeout(timer)
            if (remaining <= 0) {
                // 触发时间间隔大于设定时间(delay)
                fn.apply(this, arguments)
                lastTime = newTime
            } else {
                // 触发时间间隔小于设定时间(delay)
                timer =setTimeout(() => {
                    fn.apply(this, arguments)
                    lastTime = newTime
                }, remaining)
            }
        }
    }
    // 业务逻辑代码
    function throttleHandle () {
        console.log('首节流+尾节流');
    }
</script>
</html>

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值