优化 --- 节流

1. 什么是节流

单位时间内,再次触发同一个事件,不会再开启新的事件,只执行第一次

2. 使用场景

  1. 鼠标移动(mousemove)
  2. 页面尺寸缩放(resize)
  3. 滚动条滚动(scroll)等

3. 案例

3.1 鼠标划过盒子,数字+1

由于鼠标滑动1像素,就算是触发了鼠标移动事件,这样就会不断地执行这个事件的回调函数,如果里面存在大量消耗性能的代码,如DOM操作,数据处理等,可能造成卡顿,500ms内不停的触发事件也只会在500ms中触发一次

1. lodash.js 处理节流

在事件被最后一次被触发后,再执行回调函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: gray;
            margin: 200px auto;
        }

        .box p {
            text-align: center;
            line-height: 200px;
        }
    </style>

</head>
<body>
<div class="box"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script>
    let count = 0
    const box = document.querySelector(".box")

    function counter() {
        count++
        box.innerHTML = `<p>${count}</p>`
    }
	// 在事件被触发后,500ms内执行一次回调函数
    box.addEventListener("mousemove", _.throttle(counter, 500))
</script>
</body>
</html>

2. 手写节流

节流的核心就是利用 setTimeout 来实现

  1. 声明一个定时器变量
  2. 当鼠标每次滑动先判断是否有定时器,如果有定时器就不开启新的定时器了
  3. 如果没有定时器,就开启新的定时器,并将这个定时器存储在定时器变量中
    1. 调用执行的函数
    2. 清空定时器,必须使用 timer = null 的方式清空定时器
let count = 0
const box = document.querySelector(".box")

// 节流函数
function debounce(fn, t) {
    let timer
    // 由于 debounce(counter, 500) 会立刻调用debounce 函数,所以需要返回一个匿名函数的地址
    return function () {
        if (!timer) {
            timer = setTimeout(function () {
                fn()
                timer = null  // 在 setTimeout() 中是无法清除定时器的,必须使用 time = null 的方式清除定时器
            }, t)
        }
    }
}

function counter() {
    count++
    box.innerHTML = `<p>${count}</p>`
}

box.addEventListener("mousemove", debounce(counter, 1000))
posted @ 2024-05-23 17:26  河图s  阅读(10)  评论(0)    收藏  举报