您现在的位置是:首页 > Javascript
当前栏目
如何理解JS事件的防抖与节流?
2023-03-07 09:49:05 时间
本文转载自微信公众号「新钛云服」,作者方章和。转载本文请联系新钛云服公众号。
在平时的编码过程中,当绐浏览器注册一个时间,经常会遇到一些执行次数非常频繁的事件,如scroll,resize等,事件频繁的执行会导致浏览器进行大量的计算而引发页面卡顿假死的情况,为些我们需要通过一些手段来解决这个问题,所以就有了防抖和节流这两个技术。
事件节流 throttle
是指在某段时间内,不管你触发了多少次回调事件,我都只认第一次,并在计时结束时给予响应,至于后面你再触发多少次回调我都不会予以回应。代码实现如下:
- // fn执行的函数, interval是时间间隔的阈值, 意为多久后执行,单位毫秒
- function throttle(fn, interval) {
- // 上一次触发回调的时间
- let last = 0
- return function () {
- let context = this
- let args = arguments
- let now = +new Date()
- // 判断上次触发的时间和本次触发的时间差是否小于设置的间隔时间
- if (now - last >= interval) {
- // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
- last = now;
- fn.apply(context, args);
- }
- }
- }
- // 绐scroll事件增加节流
- const newScroll = throttle(() => console.log('滚动了'), 1000)
- document.addEventListener('scroll', newScroll)
事件防抖Debounce
与事件节流怡好相反,事件防抖只认最后一次,不管你前面触发了多少次我都不管,我只执行你最后一次触发事件的回调,代码实现如下:
- // fn执行的函数, delay是延迟多久执行的时间, 意为多久后才触发事件,单位毫秒
- function debounce(fn, delay) {
- let timer = null
- return function () {
- let context = this
- let args = arguments
- // 每次事件被触发时,都去清除之前的旧定时器
- if(timer) {
- clearTimeout(timer)
- }
- timer = setTimeout(function () {
- fn.apply(context, args)
- }, delay)
- }
- }
- const newScroll = debounce(() => console.log('滚动了'), 1000)
- document.addEventListener('scroll', newScroll)
函数防抖的应用场景
连续的事件,只需触发一次回调的场景有:
搜索框搜索输入。只需用户最后一次输入完,再发送请求
手机号、邮箱验证输入检测
窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
函数节流的应用场景
间隔一段时间执行一次回调的场景有:
- 滚动加载,加载更多或滚到底部监听
- 百度搜索框,搜索联想功能
- 高频点击提交,表单重复提交
相关文章
- 鲜为人知但很有用的 HTML 属性
- 翻转再翻转!有意思的水平横向溢出滚动
- 自定义计数器小技巧!CSS 实现长按点赞累加动画
- 过五关!React高频面试题指南
- 软件开发中的十个认知偏差
- 不需要 JS!仅用 CSS 也能达到监听页面滚动的效果!
- 一文读懂TypeScript类型兼容性
- Vue 的响应式原则与双向数据绑定
- 快速掌握 TypeScript 新语法:Infer Extends
- JWT教你如何证明你是我的人!
- 一篇带给你 V8 GC 的实现
- 面试官:请使用JS完成一个LRU缓存?
- 通过可视化来学习JavaScript事件循环
- 新的跨域策略:使用 COOP、COEP 为浏览器创建更安全的环境
- 为什么有人说 vite 快,有人却说 vite 慢?
- 种草 Vue3 中几个好玩的插件和配置
- 超全面的前端工程化配置指南
- Vue 状态管理未来样子
- Volatile关键字能保证原子性么?
- 面试突击:SpringBoot 有几种读取配置文件的方法?