JS节流基础版
<style>.artBox { margin: 20px auto; font: normal 18px/26px sans-serif; max-width: 1000px; }
.artBox mark { padding: 2px 6px; background: #ccc; }
.artBox p { margin: 10px 0; }
.artBox blockquote { padding: 14px; border: solid gray; border-width: 0 4px; border-radius: 10px; background: #ddd; }
</style>
<div class="artBox">
<p>什么是节流?</p>
<blockquote>节流(Throttle)是一种限制高频事件触发频率的性能优化技术,确保函数在固定时间间隔内最多执行一次,相当于给函数加了“冷却时间”。常用于 scroll、resize、mousemove、keydown 等高频事件,避免页面卡顿和性能浪费。</blockquote>
<p>先来体会高频事件的例子。下例,鼠标指针在方框内移动时会实时触发计数器函数的累加运算,计数结果高频率呈现在方框内,预览过程中请尝试将鼠标指针不停地在方框内绕圈移动,这时可以看到数字的变化速度非常之快:</p>
<div class="hEdiv" data-prev="1"><pre class="hEpre">
<style>
#mdiv { margin: auto; padding: 12px; width: 400px; height: 200px; display: grid; place-items: center; font-size: 36px; border: 1px solid gray; }
.tMid { text-align: center; }
</style>
<h1 class="tMid">请在方框内移动鼠标指针</h1>
<div id="mdiv">0</div>
<script>
let num = 0;
const add = () => ++num; // 累加器
const showRes = () => mdiv.innerText = add(); // 显示计数器结果
mdiv.addEventListener('mousemove', showRes, 500);
</script>
</pre></div>
<p>mousemove 是鼠标指针移动事件,当它移动于特定元素之上,待运行的机制会被高频率触,不加以节流可能产生非预期的效果甚至造成一些负面影响。要改变上例计数变化过快的效果,实现方法之一是给其降频,通过“节流”的机制让目标函数在一定时间间隔内只能运行一次。节流好比特定线路的公交车,在规定的事件间隔必定有一辆车子开出;或者也可以比喻为给花圃自动浇水的设备,令设备每隔一段时间自动喷水一次。</p>
<p>以下例子采用了通用的节流函数,该函数在 mouseover 监听事件中调用,作用于调用计数器并呈现计数结果的 showRes 函数,即每隔指定时间(wait毫秒)运行一次 showRes 函数(而 showRes 函数调用的时累加器函数):</p>
<div class="hEdiv" data-prev="1"><pre class="hEpre">
<style>
#mdiv { margin: auto; padding: 12px; width: 400px; height: 200px; display: grid; place-items: center; font-size: 36px; border: 1px solid gray; }
.tMid { text-align: center; }
</style>
<h1 class="tMid">请在方框内移动鼠标指针</h1>
<div id="mdiv">0</div>
<script>
let num = 0;
// 函数 :累加器
const add = () => ++num;
// 函数 :显示累加器当前运算结果
const showRes = () => mdiv.innerText = add();
// 函数 :节流(时间戳版)
const throttle = (func, wait) => {
let last = 0; // 上一次的时间戳
return (...args) => {
let now = Date.now(); // 当下的时间戳
if (now - last >= wait) {
func.apply(this, ...args); // 执行传入的目标函数
last = now; // 重置时间戳
}
};
};
mdiv.addEventListener('mousemove', throttle(showRes, 500));
</script>
</pre></div>
<p>节流函数还有另一个版本,计时器版,通用函数如下:</p>
<div class="hEdiv"><pre class="hEpre">
// 节流 :定时器版
const throttle = (func, wait) => {
let timeout;
return (...args) => {
if (timeout) return; // 冷却机制(如果计时器存在不执行下面的代码)
// 启动计时器
timeout = setTimeout(() => {
timeout = null; // 注销计时器以便后续重置
func.apply(this, ...args); // 应用函数
}, wait);
};
};
</pre></div>
<p>定时器版(setTimeout)节流函数完全可以替代前例的时间戳版(Date.now)函数,效果一样。</p>
<p>节流与防抖都是降频处理高频事件,二者的核心区别在于:节流是在匀速执行目标函数,防抖则是延时执行目标函数——好比电梯的自动关门机制那样,只要还有人进电梯,所指定的间隔时间马上重置,即重新开始倒计时。</p>
<p>【说明】本文所讨论的节流函数属于基础班、简化版、通用版,它们还有多种演进版本,感兴趣的朋友可以网查。</p>
</div>
<script type="module">
import hl from 'https://638183.freep.cn/638183/web/js/hl.js';
const divs = document.querySelectorAll('.hEdiv');
const pres = document.querySelectorAll('.hEpre');
divs.forEach((div,idx) => hl.hl(div, pres));
</script> 报告黑黑老师,预览都试过了,一快一慢,这种现象就是老师说的“节流”? 谢谢黑黑老师辛苦,学习了。{:4_187:} 长知识了,谢谢马老师直观讲解两个重要方法——节流与防抖技术{:4_190:} 代码里有这么多各种功能的设计呢,跟着黑黑学习新知识{:4_187:} 马老师晚上好!这里说的道理我不懂,我联想到一些破解软件版本不好的就出现闪退,画面不稳喝醉了似的。遇到这样状态有的作者会给个补丁文件安装一下,有的就只好放弃使用,再傻丫头的诸多版本中很突出。{:4_204:}{:4_190:}
霜染枫丹 发表于 2026-6-25 20:53
马老师晚上好!这里说的道理我不懂,我联想到一些破解软件版本不好的就出现闪退,画面不稳喝醉了似的。遇到 ...
酱紫
这个跟那些没有关系。这个说的是节流,让太快的东东减速、匀速或等待 红影 发表于 2026-6-25 19:37
代码里有这么多各种功能的设计呢,跟着黑黑学习新知识
这里出现了世界上最短的函数 杨帆 发表于 2026-6-25 18:35
长知识了,谢谢马老师直观讲解两个重要方法——节流与防抖技术
这些会经常用到 梦江南 发表于 2026-6-25 12:19
报告黑黑老师,预览都试过了,一快一慢,这种现象就是老师说的“节流”?
快是我们所追求的,但是,太快了不见得都是好事。比方说翻书,10秒钟就能把一部红楼梦翻完,你说这书翻的有意思吗?所以要节流,让翻页适合阅读。 梦江南 发表于 2026-6-25 12:19
谢谢黑黑老师辛苦,学习了。
{:4_190:} 马黑黑 发表于 2026-6-26 20:42
这些会经常用到
是的,经常遇到,还不能自主运用呢 杨帆 发表于 2026-6-26 21:22
是的,经常遇到,还不能自主运用呢
这需要探索、尝试,敢做,才可能有出产 马黑黑 发表于 2026-6-28 11:42
这需要探索、尝试,敢做,才可能有出产
非常赞同~谢谢马老师指导,祝夏安{:4_190:} 马黑黑 发表于 2026-6-26 20:42
这里出现了世界上最短的函数
而且很有用{:4_187:} 红影 发表于 2026-6-28 17:32
而且很有用
用得上就有用 杨帆 发表于 2026-6-28 15:01
非常赞同~谢谢马老师指导,祝夏安
晚上好 马黑黑 发表于 2026-6-28 22:18
用得上就有用
那是当然{:4_204:} 马黑黑 发表于 2026-6-28 22:23
晚上好
马老师,晚上好{:4_180:} 杨帆 发表于 2026-6-28 22:57
马老师,晚上好
下午好
页:
[1]
2