马黑黑 发表于 2026-6-25 12:11

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">
&lt;style&gt;
    #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; }
&lt;/style&gt;

&lt;h1 class="tMid"&gt;请在方框内移动鼠标指针&lt;/h1&gt;
&lt;div id="mdiv"&gt;0&lt;/div&gt;

&lt;script&gt;
    let num = 0;
    const add = () =&gt; ++num; // 累加器
    const showRes = () =&gt; mdiv.innerText = add(); // 显示计数器结果
    mdiv.addEventListener('mousemove', showRes, 500);
&lt;/script&gt;
    </pre></div>
    <p>mousemove 是鼠标指针移动事件,当它移动于特定元素之上,待运行的机制会被高频率触,不加以节流可能产生非预期的效果甚至造成一些负面影响。要改变上例计数变化过快的效果,实现方法之一是给其降频,通过“节流”的机制让目标函数在一定时间间隔内只能运行一次。节流好比特定线路的公交车,在规定的事件间隔必定有一辆车子开出;或者也可以比喻为给花圃自动浇水的设备,令设备每隔一段时间自动喷水一次。</p>
    <p>以下例子采用了通用的节流函数,该函数在 mouseover 监听事件中调用,作用于调用计数器并呈现计数结果的 showRes 函数,即每隔指定时间(wait毫秒)运行一次 showRes 函数(而 showRes 函数调用的时累加器函数):</p>
    <div class="hEdiv" data-prev="1"><pre class="hEpre">
&lt;style&gt;
    #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; }
&lt;/style&gt;

&lt;h1 class="tMid"&gt;请在方框内移动鼠标指针&lt;/h1&gt;
&lt;div id="mdiv"&gt;0&lt;/div&gt;

&lt;script&gt;
    let num = 0;

    // 函数 :累加器
    const add = () =&gt; ++num;

    // 函数 :显示累加器当前运算结果
    const showRes = () =&gt; mdiv.innerText = add();
   
    // 函数 :节流(时间戳版)
    const throttle = (func, wait) =&gt; {
      let last = 0; // 上一次的时间戳
      return (...args) =&gt; {
            let now = Date.now(); // 当下的时间戳
            if (now - last &gt;= wait) {
                func.apply(this, ...args); // 执行传入的目标函数
                last = now; // 重置时间戳
            }
      };
    };

    mdiv.addEventListener('mousemove', throttle(showRes, 500));
&lt;/script&gt;
    </pre></div>
    <p>节流函数还有另一个版本,计时器版,通用函数如下:</p>
    <div class="hEdiv"><pre class="hEpre">
// 节流 :定时器版
const throttle = (func, wait) =&gt; {
    let timeout;
    return (...args) =&gt; {
      if (timeout) return; // 冷却机制(如果计时器存在不执行下面的代码)
      // 启动计时器
      timeout = setTimeout(() =&gt; {
            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>

梦江南 发表于 2026-6-25 12:19

报告黑黑老师,预览都试过了,一快一慢,这种现象就是老师说的“节流”?

梦江南 发表于 2026-6-25 12:19

谢谢黑黑老师辛苦,学习了。{:4_187:}

杨帆 发表于 2026-6-25 18:35

长知识了,谢谢马老师直观讲解两个重要方法——节流与防抖技术{:4_190:}

红影 发表于 2026-6-25 19:37

代码里有这么多各种功能的设计呢,跟着黑黑学习新知识{:4_187:}

霜染枫丹 发表于 2026-6-25 20:53

马老师晚上好!这里说的道理我不懂,我联想到一些破解软件版本不好的就出现闪退,画面不稳喝醉了似的。遇到这样状态有的作者会给个补丁文件安装一下,有的就只好放弃使用,再傻丫头的诸多版本中很突出。{:4_204:}{:4_190:}

马黑黑 发表于 2026-6-26 20:41

霜染枫丹 发表于 2026-6-25 20:53
马老师晚上好!这里说的道理我不懂,我联想到一些破解软件版本不好的就出现闪退,画面不稳喝醉了似的。遇到 ...

酱紫

这个跟那些没有关系。这个说的是节流,让太快的东东减速、匀速或等待

马黑黑 发表于 2026-6-26 20:42

红影 发表于 2026-6-25 19:37
代码里有这么多各种功能的设计呢,跟着黑黑学习新知识

这里出现了世界上最短的函数

马黑黑 发表于 2026-6-26 20:42

杨帆 发表于 2026-6-25 18:35
长知识了,谢谢马老师直观讲解两个重要方法——节流与防抖技术

这些会经常用到

马黑黑 发表于 2026-6-26 20:44

梦江南 发表于 2026-6-25 12:19
报告黑黑老师,预览都试过了,一快一慢,这种现象就是老师说的“节流”?

快是我们所追求的,但是,太快了不见得都是好事。比方说翻书,10秒钟就能把一部红楼梦翻完,你说这书翻的有意思吗?所以要节流,让翻页适合阅读。

马黑黑 发表于 2026-6-26 20:44

梦江南 发表于 2026-6-25 12:19
谢谢黑黑老师辛苦,学习了。

{:4_190:}

杨帆 发表于 2026-6-26 21:22

马黑黑 发表于 2026-6-26 20:42
这些会经常用到

是的,经常遇到,还不能自主运用呢

马黑黑 发表于 2026-6-28 11:42

杨帆 发表于 2026-6-26 21:22
是的,经常遇到,还不能自主运用呢

这需要探索、尝试,敢做,才可能有出产

杨帆 发表于 2026-6-28 15:01

马黑黑 发表于 2026-6-28 11:42
这需要探索、尝试,敢做,才可能有出产

非常赞同~谢谢马老师指导,祝夏安{:4_190:}

红影 发表于 2026-6-28 17:32

马黑黑 发表于 2026-6-26 20:42
这里出现了世界上最短的函数

而且很有用{:4_187:}

马黑黑 发表于 2026-6-28 22:18

红影 发表于 2026-6-28 17:32
而且很有用

用得上就有用

马黑黑 发表于 2026-6-28 22:23

杨帆 发表于 2026-6-28 15:01
非常赞同~谢谢马老师指导,祝夏安

晚上好

红影 发表于 2026-6-28 22:52

马黑黑 发表于 2026-6-28 22:18
用得上就有用

那是当然{:4_204:}

杨帆 发表于 2026-6-28 22:57

马黑黑 发表于 2026-6-28 22:23
晚上好

马老师,晚上好{:4_180:}

马黑黑 发表于 2026-6-29 12:39

杨帆 发表于 2026-6-28 22:57
马老师,晚上好

下午好
页: [1] 2
查看完整版本: JS节流基础版