前端日常开发常用功能系列之节流

这是前端日常开发常用功能这个系列文章的第一篇,该系列是日常开发中一些常用的功能的再总结、再提炼,以防止遗忘,便于日后复习。该系列预计包含以下内容: 防抖、节流、去重、拷贝、最值、扁平、偏函数、柯里、惰性函数、递归、乱序、排序、注入、上传、下载、截图。。。

 什么是节流?

节流就是如果你持续触发事件,每隔一段时间,只执行一次事件。

为什么要进行节流?

在频繁触发事件的场景,有些情况可能执行的逻辑比较复杂或者耗时,此时浏览器的处理跟不上触发,就会发生卡顿、假死或者事件堆积,为了解决这个故障,节流是其中之一的策略,前文还有另一种策略的介绍: 防抖。

常见的需要防抖的场景: 搜索框keyup、keydown等触发后台请求; 频繁改变窗口大小resize;鼠标移动mousemove事件;类似以上频繁触发并且处理逻辑较为耗时或者触发时需要请求后台接口;

如何做到节流呢?

版本1,设定间隔,如果当前请求触发时间和上次触发间隔小于设定间隔,则不触发

<html>
<head>
<meta charset="UTF-8">
<style>
    div {
        width: 500px;
        height: 300px;
        background: orange;
    }
</style>
</head>
<body>
    <div id="div"></div>
</body>
<script>
    const div = document.getElementById(‘div‘);

    const throttle = (fn, wait) => {
        let pre = 0, context, args;

        return function() {
            context = this;
            args = arguments;
            const now = new Date().getTime();
            if(now -pre > wait) {
                fn.apply(context, args);
                pre = now;
            }
        }
    };

    const fn = throttle((e) => {
        console.log(‘move‘, e);
    }, 1000)

    div.addEventListener(‘mousemove‘, fn);
</script>
</html>

执行结果是: 当鼠标不断在橙色区域移动,则每隔1s才会打印‘move‘;(设定的间隔就是1000ms)但是在结尾处不会执行事件,比如4.5s结束则事件只在0s、1s、2s、3s、4s执行

版本2,使用定时器;首次触发设定新的定时器,如果间隔小于预设,则清除旧的定时器;

<html>
<head>
<meta charset="UTF-8">
<style>
    div {
        width: 500px;
        height: 300px;
        background: orange;
    }
</style>
</head>
<body>
    <div id="div"></div>
</body>
<script>
    const div = document.getElementById(‘div‘);

    const throttle = (fn, wait) => {
        let context, args, timer;

        const run = () => {
            timer = setTimeout(() => {
                fn.apply(context, args);
                clearTimeout(timer);
                timer = null
            }, wait);
        }

        return function() {
            context = this;
            args = arguments;
            if(!timer) {
                run();
            }
        }
    };

    const fn = throttle((e) => {
        console.log(‘move‘, e);
    }, 1000)

    div.addEventListener(‘mousemove‘, fn);
</script>
</html>

执行结果是:当鼠标不断在橙色区域移动,则每隔1s才会打印‘move‘,但是和非定时器版本的区别在于此版本第一次执行也是在1s之后,并非立即执行

如果我们想在首次触发事件时立即执行一次,在事件触发结束后再执行一次应该怎么办呢?

版本3

<html>
<head>
<meta charset="UTF-8">
<style>
    div {
        width: 500px;
        height: 300px;
        background: orange;
    }
</style>
</head>
<body>
    <div id="div"></div>
</body>
<script>
    const div = document.getElementById(‘div‘);

    const throttle = (fn, wait) => {
        let pre = 0, context, args, timer;

        const run = () => {
            pre = +new Date();
            fn.apply(context, args);
            clearTimeout(timer);
            timer = null;
        }

        return function() {
            context = this;
            args = arguments;
            const now = +new Date();
            const remain = wait - (now - pre);
               if(Math.abs(remain) > wait || remain < 0) {
                   pre = +new Date();
                   fn.apply(context, args);
               } else if(!timer){
                   timer = setTimeout(run, wait);
               }
        }
    };

    const fn = throttle((e) => {
        console.log(‘move‘, e);
    }, 1000)

    div.addEventListener(‘mousemove‘, fn);
</script>
</html>

原文地址:https://www.cnblogs.com/innooo/p/10419953.html

时间: 2024-10-10 09:32:53

前端日常开发常用功能系列之节流的相关文章

前端日常开发常用功能系列之数组去重

这是前端日常开发常用功能这个系列文章的第一篇,该系列是日常开发中一些常用的功能的再总结.再提炼,以防止遗忘,便于日后复习.该系列预计包含以下内容: 防抖.节流.去重.拷贝.最值.扁平.偏函数.柯里.惰性函数.递归.乱序.排序.注入.上传.下载.截图... 本文所记录的数组去重方法只针对一维数组,且数组项都是基本数据类型值 方法一: 二重循环比较去重(因为使用的是‘===’比较,适合数组项为数值.字符串的数组) const unique1 = arr => { const tempArr = ar

PHP微信公众号开发常用功能

最近学习了关于微信公众号开发的相关知识,为了帮助自己更好的理解,在此重新再梳理一遍 更多关于微信公众号开发的功能可以参考微信公众平台的开发技术文档 完成开发者配置 第一步,需要在微信公众平台配置我们的服务器  在接口的文件需要写入以下代码以完成验证: class Wxapi { public function __construct() { $this->index(); } public function index() { $echostr = isset($_GET['echostr'])

【原创】日常开发常用操作(不定时更新)

1.服务端抓包 tcpdump tcp port 18888 -vv -x -i eth0 root执行,抓包后分析时注意每个包前20字节是ip首部,其中1-2字节是版本号首部长度服务号等一般是4500,其中第3-4字节是整个包大小(=40+包体数据),剩下由源目标地址,接着20字节是tcp首部,有端口等信息. 所以我们的真正数据时从第三行第五段开始的. 另外int的话 xxyy zzqq  显示的话实际是 zzqq xxyy 另外会有粘包 或者 半包的情况,所以要留意长度等 2.进制转换 ec

ios 日常开发常用宏定义

  #pragma mark - 字体.颜色相关 #define kFONT_SIZE(f) [UIFont systemFontOfSize:(f)] #define kFONT_BOLD_SIZE(f) [UIFont boldSystemFontOfSize:(f)] #define kFONT_ITALIC_SIZE(f) [UIFont italicSystemFontOfSize:(f)] #define kRGBCOLOR(r,g,b) [UIColor colorWithRed:

前端开发掌握nginx常用功能之rewrite

上一篇博文对nginx最常用功能的server及location的匹配规则进行了讲解,这也是nginx实现控制访问和反向代理的基础.掌握请求的匹配规则算是对nginx有了入门,但是这些往往还是不能满足实际的需求场景,例如请求url重写.重定向等等,这都需要对请求的path进行修改操作的,匹配规则是不能独自完成实际需求的,这就需要掌握nginx的另一个常用功能rewrite,下面就来说说这个常用功能. Rewrite规则 rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正

CDN公共库、前端开发常用插件一览表(VendorPluginLib)

=======================================================================================前端CDN公共库====================================================================================== 为什么使用前端CDN公共库: 使用前端CDN增加网页的并行载入速度,减少本地服务器的负担,节省流量.我们把静态资源放到自己的服务器上面固

Notepad++前端开发常用插件介绍

Notepad++前端开发常用插件介绍 Notepad++除了自身的功能强大之外,更是有许多非常的优秀的插件,下面就总结一下前端开发过程一些比较常用的插件. Emmet Emmet的前身是Zen Coding,一款使用仿CSS选择器的语法来快速开发HTML和CSS的插件,是前端开发神器.它无视了编辑器的自动提示和自动完成,秒杀了你自定义的各种快捷键或者 AHK 的热字符串,以智能简洁高效的缩短输入,带给你超快速地书写各种复杂而枯燥的 HTML 和 CSS 代码的体验.现在可以在Notepad++

推荐一些前端开发常用框架

1.动态加载js 1).sea.js Sea.js 追求简单.自然的代码书写和组织方式,具有以下核心特性: 简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码. 自然直观的代码组织方式:依赖的自动加载.配置的简洁清晰,可以让我们更多地享受编码的乐趣 一般对于单页面的网站比较适合是国内的以为大牛写的 地址:http://seajs.org/docs/ 网易的有道云笔记网页版用的就是这个 可以看看他的js代码 http://note.youdao.co

Sublime Text 前端开发常用扩展插件推荐

Sublime Text 前端开发常用扩展插件推荐 Sublime Text Sublime Text 是程序员们公认的编码神奇,拥有漂亮的用户界面和强大的功能 更重要的是,Sublime Text 易于扩展,众多开发人员为其贡献插件,而且通过包管理工具 —— Package Control 可以方便安装和管理. Package Control 安装方法 首先通过快捷键 ctrl+` 或者 View > Show Console 打开控制台,然后粘贴相应的 Python 安装代码. Sublim