js原生

函数防抖:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。

区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。

函数防抖

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。如下面这段代码,持续触发scroll事件时,并不执行handle函数,当1000毫秒内没有触发scroll事件时,才会延时触发scroll事件。

一个防抖的例子

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
      body{
        height: 5000px;
      }
    </style>
  </head>
  <body>
    <script>
      //防抖函数、fn(处理函数),wait(自定义定时器时间)
      function debounce(fn, wait) { 
        var timeout = ""; //声明变量timeout复制为空字符串
        return function() {//返回匿名函数
          if(timeout !== ""){//如果timeout不为空
            clearTimeout(timeout);//清除timeout定时器
          }
          timeout = setTimeout(fn, wait);//重新给timeout赋值为fn我处理函数,wait为定时周期的一次性定时器
        }
      }
      // 处理函数
      function handle() {
        console.log(Math.random());
      }
      // 滚动事件
      window.addEventListener('scroll', debounce(handle, 1000));//为window的scroll滑动事件绑定防抖函数
    </script>
  </body>
</html>

代码执行路线是:

  • 1、页面初始化,渲染页面,执行代码
  • 2、调用debounce函数,声明一个变量timeout,并赋值为空字符串。返回一个匿名函数,通过addEventListener绑定给window的scroll(滑动事件)
  • 3、触发window的scroll(滑动事件)
  • 4、进入window的scroll的处理函数(调用debounce函数返回的那个匿名函数)。
  • 5.1、如果timeout不为空,清除timeout定时器,重新给timeout赋值为fn我处理函数,wait为定时周期的一次性定时器。
  • 5.2、如果timeout为空,重新给timeout赋值为fn我处理函数,wait为定时周期的一次性定时器。
  • 6、再次触发window的scroll(滑动事件),重复步骤4和步骤5
  • 7、停止触发,执行一遍步骤4和步骤5
  • 8、执行timeout一次性定时器,调用handle函数进行处理

函数节流------》时间戳

var throttle = function(func, delay) {

  var prev = Date.now(); //生成初始时间

  return function() {

    var context = this; //存储当前this指向---可删除

    var args = arguments; //存储当前局部变量---可删除

    var now = Date.now(); //存储当前执行时间

    if (now - prev >= delay) { //使用当前执行时间减去初始时间

      func.apply(context, args); //通过apply使用当前对象调用func函数------如果想删除var context = this;var args = arguments;需要把当前代码改成func()

      prev = Date.now(); //再次刷新初始时间

    }

  }

}

function handle() {

  console.log(Math.random());

}

window.addEventListener('scroll', throttle(handle, 1000));

时间戳的一个优点:在页面初始化的时候就生成了“初始时间”(不明白初始时间上面有提示),而此时还没有触发scroll时间,等触发时远远超过了时间间隔(假设时间间隔为1秒),所以处理函数会立即执行

时间戳的一个缺点:假设触发事件的间隔是一秒,在距离上一次触发事件的时间还差0.5秒停止触发事件,那一秒过后事件函数也不会执行;

函数节流------》定时器

var throttle = function(func, delay) {
  var timer = "";
  return function() {
    var context = this;
    var args = arguments;
    if (!timer) {
      timer = setTimeout(function() {
        func.apply(context, args);
        timer = "";
      }, delay);
    }
  }
}
function handle() {
  console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));
 
定时器的优缺点与时间戳相反,当时发事件后1秒钟,执行处理函数,在事件间隔内出发时间,等超过时间间隔会再次执行处理函数
 

函数节流------》定时器+时间戳

 
所以我们就把事件戳的有点和定时器的有点结合起来,变成下面的方案
var throttle = function(func, delay) {
  var timer = "";
  var startTime = Date.now();
  return function() {
    var curTime = Date.now();
    var remaining = delay - (curTime - startTime);
    var context = this;
    var args = arguments;
    clearTimeout(timer);
    if (remaining <= 0) {
      func.apply(context, args);
      startTime = Date.now();
    } else {
      timer = setTimeout(func, remaining);
    }
  }
}
function handle() {
  console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));
 

----------------------VUE-----------------------------

// 防抖
export function _debounce(fn, delay) {

  var delay = delay || 200;

  var timer = "";
  return function () {
    var th = this;
    var args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function () {
      timer ="" ;
      fn.apply(th, args);
    }, delay);
  };
}
// 节流
export function _throttle(fn, interval) {
  var last = new Date().getTime();
  var timer;
  var interval = interval || 200;
  return function () {
    var th = this;
    var args = arguments;
    var now = new Date().getTime();
    if (last && now - last < interval) {
      clearTimeout(timer);
      timer = setTimeout(function () {
        last = new Date().getTime();
        fn.apply(th, args);
      }, interval);
    } else {
      last = new Date().getTime();
      fn.apply(th, args);
    }
  }
}

在需要使用的组件引用

import { _debounce } from "@/utils/public";

在 methods 中使用

methods: {
  // 改变场数
  changefield: _debounce(function(_type, index, item) {
    // do something ...
  }, 200)
}

VUE防抖节流:https://blog.csdn.net/qq_39759115/article/details/82287517
JS防抖节流参考文章:https://blog.csdn.net/qq_41000891/article/details/82733532

 
希望能看懂。。。。。。嘿嘿

Javascript的防抖和节流、VUE的防抖和节流的更多相关文章

  1. 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖

    前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...

  2. vue函数防抖和节流

    Vue函数防抖和节流https://zhuanlan.zhihu.com/p/72363385 <template> <div> <input type='text' v ...

  3. JavaScript函数节流和函数防抖之间的区别

    一.概念解释  函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.  大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...

  4. 【javascript】js中的函数节流和函数防抖

    一.概念解释  函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.  大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...

  5. JavaScript 高级系列之节流 [throttle] 与防抖 [debounce]

    一.概念 这两个东西都是为了项目优化而出现的,官方是没有具体定义的,他们的出现主要是为了解决一些短时间内连续执行的事件带来性能上的不佳和内存的消耗巨大等问题:像这类事件一般像 scroll keyup ...

  6. js函数节流和函数防抖

    概念解释 函数节流: 频繁触发,但只在特定的时间内才执行一次代码 函数防抖: 频繁触发,但只在特定的时间内没有触发执行条件才执行一次代码 函数节流 函数节流应用的实际场景,多数在监听页面元素滚动事件的 ...

  7. 函数节流throttle和防抖debounce

    throttle 函数节流 不论触发函数多少次,函数只在设定条件到达时调用第一次函数设定,函数节流 1234567891011 let throttle = function(fn,intervalT ...

  8. javaScript函数节流与函数防抖

    javaScript函数节流与防抖之区别 函数防抖(debounce)与函数节流(throttle)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟.假死或卡顿 ...

  9. 函数节流和函数防抖JavaScript实现

    函数节流 function throttle(fn, delay = 1000) { let Running = false; return function () { if (Running) { ...

随机推荐

  1. redis常用的命令总结

    redis常用的命令大全 1.基于内存的key-value数据库 2.基于c语言编写的,可以支持多种语言的api //set每秒11万次,取get 81000次 3.支持数据持久化 4.value可以 ...

  2. stm32f407以太网及USB OTG快速开发

    stm32f407以太网及USB OTG快速开发 引言 想要快速完成网络协议栈和USB OTG功能,使用ST自家的工具STM32CubMx再好不过的了.如果你还不会使用,别着急下面我会一步一步的用图片 ...

  3. selenium 对浏览器标签页进行关闭和切换

    关闭标签页 # 1.关闭浏览器全部标签页 driver.quit() # 2.关闭当前标签页(从标签页A打开新的标签页B,关闭标签页A) driver.close() 切换标签页 from selen ...

  4. NSRunLoop 在mac command line tool上的部分运用

    首先RunLoop相关博客参考这篇https://blog.csdn.net/lengshengren/article/details/12905627. 最近开发了一个mac上的命令行工具,我在主线 ...

  5. Promise (2) 原型上的方法

    "I'm Captain Jack Sparrow" 加勒比海盗5上映,为了表示对杰克船长的喜爱,昨天闪现了几次模仿船长的走路姿势(哈哈哈,简直妖娆). 为了周天能去看电影,要赶紧 ...

  6. 解决Qt下ssl出错的办法

    在使用 QNetworkAccessManager 时出现的ssl错误:qt.network.ssl: QSslSocket: cannot resolve SSL_set_psk_client_ca ...

  7. #WEB安全基础 : HTTP协议 | 0x12 MIME多用途邮件扩展以及多部分对象集合

    我们是怎么让邮件里又有图片又有文字的? 文字和图片是两个不同的类型,而邮件又是一个类型. C语言的结构体允许用户定义一个含有多类型的自定义类型 像这样,看不懂没关系,你只要知道邮件里有多个类型就可以了 ...

  8. 搭建apache本地服务器·Win

    1.下载apache地址:https://www.apachelounge.com/download/ 注意:下载压缩包如下 httpd-2.4.37-win64-VC15.zip 其中根据自己电脑的 ...

  9. SQL 一列数据整合为一条数据

    SQL 一列数据整合为一条数据: SELECT  STUFF(( SELECT distinct  ',' + 列名 FROM 表名 where  [条件] FOR XML PATH('') ), 1 ...

  10. kafka安装教程

    今天需要在新机器上安装一个kafka集群,其实kafka我已经装了十个不止了,但是没有一个是为生产考虑的,因此比较汗颜,今天好好地把kafka的安装以及配置梳理一下: 1,kafka版本选取: 现在我 ...