LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

那些年我们忽略的高频事件,正在拖垮你的页面

freeflydom
2025年7月11日 10:28 本文热度 70

在前端开发中,我们经常需要处理一些高频触发的事件,比如:

  • 输入框搜索建议(input 或 keyup
  • 窗口调整大小(resize
  • 滚动事件(scroll
  • 鼠标移动(mousemove

这些事件如果每次都执行某些代价较高的操作(如发起网络请求、重排重绘页面等),会对性能造成严重影响。为了解决这个问题,我们可以使用 防抖(debounce) 和 节流(throttle) 技术。


🧠 一、什么是防抖(Debounce)?

定义:

防抖 是指,在一段时间内多次触发同一个函数,只有最后一次触发后经过指定时间没有再次触发,才会真正执行该函数。

类比:

就像你在打字时,搜索引擎不会每次按键都去请求服务器,而是等你停下来后再请求。 就像你打游戏的回城,自己移动了或被打断了就只能重新回城,直到停下来等了指定时间才会真正回城成功。

应用场景:

  • 搜索框输入实时建议
  • 表单验证
  • 窗口调整尺寸
  • 多次点击按钮(避免重复提交)

✅ 示例代码:

function debounce(fn, delay) {
    return function (args) {
        const that = this;
        clearTimeout(fn.id);
        fn.id = setTimeout(() => {
            fn.call(that, args); // 保留 this 上下文
        }, delay);
    };
}

📌 使用示例:

const inputA = document.getElementById('inputA');
inputA.addEventListener('keyup', debounce(function(e) {
    console.log('发送请求:', e.target.value);
}, 300));

🧠 二、什么是节流(Throttle)?

定义:

节流 是指,在一定时间间隔内只允许执行一次函数。无论在这段时间内触发多少次,函数只会执行一次。

类比:

就像游戏中的技能冷却,每 5 秒只能释放一次技能。

应用场景:

  • 页面滚动加载更多内容(如瀑布流)
  • 窗口调整大小(避免频繁布局计算)
  • 实时位置更新(如地图定位)

✅ 示例代码:

function throttle(fn, delay) {
    let last = 0;
    return function (...args) {
        const now = +new Date();
        if (!last || now - last >= delay) {
            fn.apply(this, args);
            last = now;
        }
    };
}

📌 使用示例:

window.addEventListener('resize', throttle(function() {
    console.log('窗口大小变化');
}, 200));

🔁 三、防抖 vs 节流:对比总结

特性防抖(Debounce)节流(Throttle)
原理在规定时间内未被再次触发才执行固定时间只执行一次
触发频率多次触发 → 只执行最后一次多次触发 → 每隔一段时间执行一次
典型用途搜索建议、表单校验滚动监听、窗口调整、动画帧控制


💡 四、进阶技巧与常见问题

1. 如何保证 this 不丢失?

在对象方法或事件回调中,this 很容易指向全局对象(如 window)。解决方案有:

✅ 方法一:用变量保存 this

obj.inc = debounce(function(val) {
    const that = this;
    setTimeout(function () {
        that.count += val;
    }, 500);
});

✅ 方法二:使用 .bind()

fn.bind(that)(args);

✅ 方法三:使用箭头函数(推荐)

setTimeout(() => {
    fn(args);
}, delay);

箭头函数不绑定自己的 this,继承外层函数的 this,非常适用于事件处理和定时器。


2. 如何兼容箭头函数和普通函数?

如果你传入的是一个箭头函数作为 fn,也要注意它的 this 绑定行为。通常我们会优先使用箭头函数来简化上下文管理。


3. 如何封装成可复用的工具函数?

你可以将防抖和节流函数封装到一个通用工具库中,例如:

// utils.js
export function debounce(fn, delay) {
    let timer;
    return function (...args) {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, args);
        }, delay);
    };
}
export function throttle(fn, delay) {
    let last = 0;
    return function (...args) {
        const now = +new Date();
        if (now - last > delay) {
            fn.apply(this, args);
            last = now;
        }
    };
}

然后在组件中导入使用:

import { debounce } from './utils';
input.addEventListener('input', debounce(fetchSuggestions, 300));

📈 五、实际应用案例分析

1. 输入框搜索建议(防抖)

<input type="text" id="searchInput">
<script>
    const input = document.getElementById('searchInput');
    function fetchSuggestions(query) {
        console.log('发送请求:', query);
    }
    input.addEventListener('input', debounce((e) => {
        fetchSuggestions(e.target.value);
    }, 300));
</script>

2. 图片懒加载 + 滚动监听(节流)

<img data-src="image1.jpg" class="lazy-img">
<script>
    function lazyLoadImages() {
        const images = document.querySelectorAll('.lazy-img');
        images.forEach(img => {
            if (isInViewport(img)) {
                img.src = img.dataset.src;
            }
        });
    }
    window.addEventListener('scroll', throttle(lazyLoadImages, 200));
</script>

关于图片懒加载,想详细了解可看前端性能优化实战:一文搞懂图片懒加载(Lazy Load),从原理到代码全解析在图片泛滥的网页时代,加载速度决定用户体验 - 掘金


🧩 六、拓展知识:高阶函数 & 闭包的应用

1. 高阶函数(Higher-order Function)

防抖和节流函数都是典型的高阶函数,它们:

  • 接收一个函数作为参数
  • 返回一个新的函数(包装后的函数)

这种设计模式广泛应用于现代 JS 开发中,尤其在 React、Vue 等框架中。

2. 闭包(Closure)

在防抖和节流函数中,我们利用了闭包来保存状态(如 timerlastfn.id 等),这使得函数可以在多次调用之间共享状态,而不污染全局作用域。


🎯 七、结语:何时用防抖?何时用节流?

场景推荐技术
用户输入搜索建议✅ 防抖
窗口调整大小✅ 节流
滚动加载更多内容✅ 节流
频繁点击按钮✅ 防抖
实时数据同步(如聊天输入)✅ 防抖
动画帧控制✅ 节流

转自https://juejin.cn/post/7525277602245574691


该文章在 2025/7/11 10:28:05 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved