节流 防抖

函数节流:

英文 throttle 有节流阀的意思。大致意思也是 节约触发的频率

真正的含义是:单位时间n秒内,第一次触发函数并执行,以后 n秒内不管触发多少次,都不执行。直到下一个单位时间n秒,第一次触发函数并执行,这个n秒内不管函数多少次都不执行。

用处:多用于页面scroll滚动,或者窗口resize,或者防止按钮重复点击等情况

函数防抖:

英文 debounce 有防反跳的意思,大致就是指防止重复触发。

真正的含义是:延迟函数执行。即不管debounce函数触发了多久,只在最后一次触发debounce函数时,才定义setTimeout,到达间隔时间再执行 需要防抖的函数。

用处:多用于 input 框 输入时,显示匹配的输入内容的情况。

使用方式

封装在公用 util.js中:

javascript 复制代码
// 函数节流
function throttle(fn, interval = 2000) {
  var enterTime = 0; //触发的时间
  var gapTime = interval; //间隔时间,如果interval不传,则默认2000ms
  return function (e) {
    var that = this;
    var backTime = new Date(); //第一次函数return即触发的时间
    if (backTime - enterTime > gapTime) {
      fn.call(that, e, arguments);
      enterTime = backTime; //赋值给第一次触发的时间,这样就保存了第二次触发的时间
    }
  };
}
// 函数防抖
function debounce(fn, interval = 2000) {
  var timer;
  var gapTime = interval; //间隔时间,如果interval不传,则默认2000ms
  return function (e) {
    clearTimeout(timer);
    var that = this;
    var args = arguments; //保存此处的arguments,因为setTimeout是全局的,arguments不是防抖函数需要的。
    timer = setTimeout(function () {
      fn.call(that, e, args);
    }, gapTime);
  };
}

调用

javascript 复制代码
var uril = require('../../utils/util')
 
Page({
  onPageScroll: uril.throttle(function () {
    console.log(111)
  }),
  gotoUnlock: uril.debounce(function () {
    console.log(222)
  }),
 
})

简单说,多次点击时,规定时间内 函数节流只触发第一次,函数防抖只触发最后一次
原文


防抖与节流

用户行为过快会导致浏览器反应不过来,如果当前回调函数中有一些大量的业务,有可能会出现卡顿现象,因此需要防抖和节流

效果
防抖:前面所有的触发事件都被取消,最后一次执行在规定时间之后才会触发,也就是说快速连续触发时只会执行一次

节流:在规定的时间间隔范围内不会重复触发回调,只要大于这个时间间隔才会触发回调,把频繁触发转变为少量触发

原理
防抖是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,都会清除当前的 timer 然后重新设置超时调用,即重新计时。这样一来,只有最后一次操作能被触发。

节流是通过判断是否到达一定时间来触发函数,若没到规定时间则使用计时器延后,而下一次事件则会重新设定计时器。

防抖的应用场景

( 1 ) 用户在输入框中连续输入一串字符,只会在输入完成后取最终输入的内容。然后发送ajax请求,这样可以有效地减少请求次数,节约请求资源。

( 2 ) window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖函数让其只触发一次。

节流的应用场景

( 1 ) 鼠标连续不断地触发某事件(如点击),在单位时间内只触发一次。

( 2 ) 在页面的无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。

( 3 ) 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

实现:

方法一、使用lodash插件,其中包含防抖与节流业务

防抖:_.debounce(function(){},1000);其中function(){}为要防抖的函数,1s后执行,用户操作频繁但是只执行一次

节流:_.throttle(function(){},1000) 用户操作频繁,把频繁操作变为少量操作

Vue2框架自带lodash直接引入就可以

方法二、自己写防抖节流函数

防抖:分为立即执行版本和非立即执行版本

防抖函数中获得argument并使用apply改变this是为了让 debounce 函数最终返回的函数 this 指向不变(否则this会指向window)以及依旧能接受到 event 参数(这里接收的arguments其实就是event参数)。

非立即执行:触发事件后不会立即执行而是在n秒后执行

javascript 复制代码
 <input type="text">
javascript 复制代码
let input = document.querySelector('input')
    let a = 'a';
    input.oninput = debounce(function(a) {
        console.log(1)
    }, 1000)
 
    function debounce(fn, delay) {
        let time = null;
        function _debounce() {
            let args = [...arguments];
            clearTimeout(time);
            time = setTimeout(() => {
                fn.apply(this, args)
            }, delay)
        }
        return _debounce
    }

立即执行,触发后会先立即执行一次

javascript 复制代码
  let input = document.querySelector('input')
    let a = 'a';
    input.oninput = debounce(function(a) {
        console.log(1)
    }, 1000, true)
function debounce(fn, delay, isImmediate = true) {
        let time = null;
        let isFirst = true
 
        function _debounce() {
            let args = [...arguments]
            if (time) {
                clearTimeout(time)
            }
            if (isFirst && isImmediate) {
                fn.apply(this, args);
                isFirst = false;
            }
            time = setTimeout(() => {
                fn.apply(this, args)
                isFirst = true;
            }, delay)
        }
        return _debounce
    }

节流:有两个版本,时间戳和定时器

时间戳版本

javascript 复制代码
function throttle(fn, wait) {
        let lastTime = 0;
        function _throttle() {
            let nowTime = Date.now();
            let args = [...arguments]
            if (nowTime - lastTime > wait) {
                fn.apply(this, args);
                lastTime = nowTime;
            }
        }
        return _throttle
    }

定时器

javascript 复制代码
function throttle(fn, wait) {
        let lastTime = 0;
 
        function _throttle() {
            let nowTime = Date.now();
            let args = [...arguments]
            if (nowTime - lastTime > wait) {
                fn.apply(this, args);
                lastTime = nowTime;
            }
        }
        return _throttle
    }

时间戳版本是在触发时立马就执行,而定时器版本是在触发一段时间后再执行


原文链接:https://blog.csdn.net/bumengbuzhangfu/article/details/130219314

未整理

相关推荐
jingling5554 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
油丶酸萝卜别吃4 小时前
Vue3 中如何在 setup 语法糖下,通过 Layer 弹窗组件弹出自定义 Vue 组件?
前端·vue.js·arcgis
同学小张8 小时前
【端侧AI 与 C++】1. llama.cpp源码编译与本地运行
开发语言·c++·aigc·llama·agi·ai-native
踢球的打工仔8 小时前
PHP面向对象(7)
android·开发语言·php
J***Q29210 小时前
Vue数据可视化
前端·vue.js·信息可视化
汤姆yu11 小时前
基于python的外卖配送及数据分析系统
开发语言·python·外卖分析
Yue丶越11 小时前
【C语言】字符函数和字符串函数
c语言·开发语言·算法
翔云 OCR API11 小时前
人脸识别API开发者对接代码示例
开发语言·人工智能·python·计算机视觉·ocr
V***u45311 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言
ttod_qzstudio12 小时前
深入理解 Vue 3 的 h 函数:构建动态 UI 的利器
前端·vue.js