【大厂手写系列】 · 手写一个防抖和节流

前言

这是手写系列的第一篇文章,如有错误/好的写法欢迎大家在评论区交流~

防抖

应用场景

  • 适合大量事件一次响应
  • 适用于需要限制函数执行频率的场景,特别是在处理用户输入、页面滚动、窗口调整等频繁触发事件的情况下。

具体案例

  • 如音乐平台在线搜索功能,在用户输入搜索关键字时会实时向服务器发送请求并展示搜索结果。为了减少不必要的请求和提升搜索体验,可以使用防抖技术。

思路

  • 延迟函数执行并重新计时以确保在一段时间内只执行一次函数。

手写代码

html 复制代码
<!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>
        <span>正常情况:</span>
        <input type="text" id="nondebounce">
    </div>
    <div>
        <span>实现防抖时:</span>
        <input type="text" id="debounce">
    </div>

    <script>
        const nondebounceDom = document.getElementById('nondebounce')
        // 正常情况下,每次键盘抬起都会触发 ajax 函数
        nondebounceDom.addEventListener('keyup', function () {
            ajax()
        })

        const debounceDom = document.getElementById('debounce')
        // 使用防抖函数,确保在连续触发 keyup 事件时只触发一次 ajax 函数
        debounceDom.addEventListener('keyup', debounce(ajax, 500))

        // 模拟一个 ajax 请求
        function ajax() {
            console.log('这是一个请求');
        }

        // 实现防抖的函数
        function debounce(fn, time) {
            let timer = null
            return function () {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    // 使用 apply 将函数 fn 的执行上下文设置为当前函数的执行上下文,并传入当前函数的参数
                    fn.apply(this, arguments)
                }, time)
            }
        }
    </script>
</body>

</html>

节流

应用场景

  • 适合大量事件按固定时间平均触发
  • 适用于需要控制事件触发频率的场景,特别是在处理高频率事件,如页面滚动、鼠标移动、键盘按键事件等情况下。

具体案例

  • 假设有一个在线地图应用,在用户拖动地图时会触发地图移动事件,需要根据地图移动的位置实时更新附近的地点信息。为了减少地点信息更新的频率,可以使用节流技术。

思路

  • 延迟函数执行,并确保在一定时间内只执行一次,以控制事件触发频率,提高性能和响应速度。

手写代码

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>

<body>
    <div>
        <span>正常情况:</span>
        <input type="text" id="unThrottle">
    </div>
    <br>
    <div>
        <span>实现节流时:</span>
        <input type="text" id="throttle">
    </div>
</body>

<script>
    // 获取未节流的输入框元素
    const unDebounceDom = document.getElementById('unThrottle')
    // 为未节流的输入框添加 keyup 事件监听器
    unDebounceDom.addEventListener('keyup', function (e) {
        // 模拟发送请求的函数,并传入输入框的值
        ajax(e.target.value)
    })

    // 获取节流后的输入框元素
    const debounceDom = document.getElementById('throttle')
    // 使用节流函数包装发送请求的函数
    debounceDom.addEventListener('keyup', function (e) {
        throttleAjax(e.target.value)
    })

    // 模拟发送请求的函数
    function ajax() {
        console.log('这是一个请求');
    }

    // 使用节流函数节流发送请求的函数
    let throttleAjax = throttle(ajax, 3000)

    // 节流函数
    function throttle(fn, time) {
        let canRun = true
        return function () {
            if (!canRun) return
            canRun = false
            setTimeout(() => {
                fn.apply(this, arguments)
                canRun = true
            }, time)
        }
    }

</script>

</html>
相关推荐
菜鸟una36 分钟前
【瀑布流大全】分析原理及实现方式(微信小程序和网页都适用)
前端·css·vue.js·微信小程序·小程序·typescript
木易 士心40 分钟前
Android 开发核心知识体系与面试指南精简版
android·面试·职场和发展
专注前端30年1 小时前
2025 最新 Vue2/Vue3 高频面试题(10月最新版)
前端·javascript·vue.js·面试
Highcharts.js1 小时前
选择合适的组合:如何打造数据可视化的“黄金组合”
javascript·信息可视化·highcharts·交互式图表开发
文火冰糖的硅基工坊2 小时前
[嵌入式系统-146]:五次工业革命对应的机器人形态的演进、主要功能的演进以及操作系统的演进
前端·网络·人工智能·嵌入式硬件·机器人
2401_837088502 小时前
ResponseEntity - Spring框架的“标准回复模板“
java·前端·spring
yaoganjili2 小时前
用 Tinymce 打造智能写作
前端
angelQ2 小时前
Vue 3 中 ref 获取 scrollHeight 属性为 undefined 问题定位
前端·javascript
Dontla2 小时前
(临时解决)Chrome调试避免跳入第三方源码(设置Blackbox Scripts、将目录添加到忽略列表、向忽略列表添加脚本)
前端·chrome
我的div丢了肿么办2 小时前
js函数声明和函数表达式的理解
前端·javascript·vue.js