js的抖动

208 阅读2分钟

在js中,为元素绑定事件,触发该事件并且事件会多次触发,但是只有一次有效,多余的触发称为js抖动

例如

  1. input事件
  2. scroll事件
  3. resize事件
  4. mousemove事件

解决方式

1. 防抖

  • 特点:当事件多次触发时,代码不执行;当事件的触发停止一段时间后再执行逻辑代码

2. 节流

  • 特点:当事件多次触发时,逻辑代码按照固定的时间间隔执行;当停止一段时间后,再执行最后一次逻辑代码

Demo

scroll事件为例

demo1--防抖

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 600px;
            height: 2500px;
            background-color: #f99;
            margin: 0 auto;
        }
    </style>
</head>

<body>
    <div class="box"></div>
</body>
<script>
    // 封装一个防抖的函数
    function shake (await, callback) {
        var timer = null
        return function () {
            clearTimeout(timer)
            timer = setTimeout(() => {
                callback()
            }, await);
        }
    }
    window.onscroll = shake(1000, () => console.log('事件结束执行'))
</script>

</html>

demo2--节流

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 600px;
            height: 2500px;
            background-color: #f99;
            margin: 0 auto;
        }
    </style>
</head>

<body>
    <div class="box"></div>
</body>
<script>
    // 封装一个节流函数
    function throttle (await, callback) {
        // 设置起始时间
        var beginTime = Date.now()
        // 定时器
        var timer = null
        return function () {
            // 触发事件的当前时间
            var currentTime = Date.now()
            // 清除开启的定时器
            clearTimeout(timer)
            if (currentTime - beginTime >= await) {
                // 当两次时间差大于等于设定的时间
                // 调用方法
                callback()
                // 重置起始时间
                beginTime = Date.now()
            } else {
                // 否则开启定时器
                timer = setTimeout(() => {
                    callback()
                }, await);
            }
        }
    }
    window.onscroll = throttle(1000, () => console.log('事件每隔1s执行,事件停止再触发一次'))
</script>

</html>