修身养性,知行合一

  • 首页
  • 爱码
    • 系统
    • 数据库
    • JavaScript
    • CSharp
    • Python
  • 生活
    • 文化
    • 美食
  • 杂谈
  • 关于
修身养性,知行合一
码字,杂谈
  1. 首页
  2. 爱码
  3. 前端
  4. JavaScript
  5. 正文

手动实现JS防抖

2020年6月24日 4401点热度 0人点赞 0条评论

什么是防抖

事件响应函数在一段时间后才执行,如果在这段时间内再次调用,则重新计算执行时间;当预定的时间内没有再次调用该函数,则执行该函数。

防抖做什么

防止某些函数的频繁调用,保证页面的稳定流畅和数据准确性。

一个小的例子

使用 underscore 的防抖功能来测试一下效果。

中文网址

在页面中直接导入cdn即可。

https://cdn.bootcss.com/underscore.js/1.9.1/underscore.js

未防抖时的样子

将下面内容粘贴到一个HTML的body标签中。

<div id="container" style="width:100%;height:200px;line-height:200px;text-align:center;color:#fff;background-color:#444;font-size:30px;"></div>
<script>
    let count = 0;
    let container = document.querySelector("#container");

    // 此处为高频调用函数
    function doSomething() {
        container.innerHTML = count++;
    }

    container.onmousemove = doSomething;
</script>

这段代码会生成一个灰色框,只要鼠标在其内部移动,就会调用 doSomething 函数,导致数字不断增长。

使用防抖

同样地,将下面内容粘贴到一个新的HTML的body标签中。

<div id="container" style="width:100%;height:200px;line-height:200px;text-align:center;color:#fff;background-color:#444;font-size:30px;"></div>
<script src="https://cdn.bootcss.com/underscore.js/1.9.1/underscore.js"></script>
<script>
    let count = 0;
    let container = document.querySelector("#container");

    // 此处为高频调用函数
    function doSomething() {
        container.innerHTML = count++;
    }

    container.onmousemove = _.debounce(doSomething, 300);
</script>

这里导入了 underscore 库,这个库会导出一个 _ 的对象,它包含一个 debounce 方法,该方法的作用就是防抖。第一个参数是函数原型,第二个参数是响应时间,另外还可以设置是否立即执行,如果是,传入 true。这里我们设置300ms后响应。

这次运行后,可以发现当鼠标移动时,不再一味地增加,而是当鼠标静止或移出后一段时间(300ms)才会响应。

手动实现防抖函数

如果仅仅使用防抖函数,导入一个库是得不偿失的,因为防抖函数本身并不大,所以可以手写一个。

function debounce(func, wait, immediate) {
    let timeout, result;

    var debounced = function() {
        // 获取上下文,关联this的指向
        let context = this;
        // 获取所有参数
        const args = arguments;
        // 每次防抖都清除定时器,然后设置一个新的定时器。
        if (timeout) clearTimeout(timeout);

        // 区别是否立即执行
        if (immediate) {
            // 如果立即执行,需要一个变量控制重复执行。这里利用timeout取反,可以控制效果
            let callNow = !timeout;
            timeout = setTimeout(() => {
                timeout = null;
            }, wait);

            // 立即执行
            if (callNow) result = func.apply(context, args);
        } else {
            // 不立即执行,则正常定时器等待即可
            timeout = setTimeout(function() {
                result = func.apply(context, args);
            }, wait);
        }

        // 返回调用函数的结果
        return result;
    }

    // 设置一个清除函数,可以手动控制取消防抖函数的执行。
    debounced.cancel = function() {
        clearTimeout(timeout);
        timeout = null;
    }

    return debounced;
}
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: JavaScript
最后更新:2020年6月24日

jeremyjone

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

文章目录
  • 什么是防抖
  • 防抖做什么
  • 一个小的例子
    • 未防抖时的样子
    • 使用防抖
  • 手动实现防抖函数
最新 热点 随机
最新 热点 随机
node-sass 的安装 解决端口被占的问题 vue3 组件 Props 的声明方式 给 div 添加选中状态 请求的取消 rgb 颜色小数兼容问题
Windows Server 2019安装与配置(二) js 修改 stylus 变量 VS Code配置C&C++,亲测 美化PowerShell(含WindowsTerminal和VSCode终端) 迁移 wordpress 小记 Windows Server 2019安装与配置(三)

(っ•̀ω•́)っ✎⁾⁾ 开心每一天

COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

京ICP备19012859号-1

京公网安备 11010802028585号