当前位置: 首页 > article >正文

javaScript防抖与节流函数

文章目录

  • 一、概念
  • 二、防抖的实现
    • 1.简单思想
    • 2.中等思想
    • 3.高等思想
  • 三、节流的实现
    • 1.第一种写法:非立即执行
    • 2.第二种方法:立即执行一次
    • 3.最终写法:可选择是否立即执行

一、概念

防抖(debound):前面的所有触发都被取消,最后一次执行在规定时间之后才触发,也就是说:如果快速的触发 只会触发最后一次
节流(throttle):在规定的时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发(固定时间内只会算一次)

防抖:回城
节流:技能cd

二、防抖的实现

1.简单思想

var timer//保存计时器id

function debounce(callback,delay){
	clearTimeout(timer)//清除之前的定时
	timer = setTimeout(function(){
	callback()
	},delay)
}

但是这么写有一个坏处,会污染全局变量,所以能不能考虑将变量写在函数里面,利用闭包来实现

2.中等思想

function debounce(callback,delay){
	var timer;
	return function(){
		clearTimeout(timer)//清除之前的计时
		timer = setTimeout(function(){
		callback()
		},delay)
	}
}

//使用
var handle = debounce(function(){
	console.log(123)
},1000)

window.onresize=function(){
	handle()
}

返回的是一个函数,如果重复触发这个函数,由于使用的是同一个timer,且写在函数里面,不会造成全局变量污染,故可以达到重新计时的功能。

但是还有个问题,如果要传参怎么办?

3.高等思想

function debounce(callback,delay){
	var timer;
	return function(){
		clearTimeout(timer)//清除之前的计时
		var args=arguments//利用闭包保存参数数组
		timer = setTimeout(function(){
		callback.apply(this,args)
		},delay)
	}
}

//使用
var handle = debounce(function(width){
	console.log(width)
},1000)

window.onresize=function(){
	handle(document.documentElement.clienWidth)
}

三、节流的实现

1.第一种写法:非立即执行

function throttle(fn, delay) {
  let timer = null;
  return function () {
  //如果存在计时器那么直接返回 不做任何处理
    if (timer) {
      return;
    }
    //如果不存在计时器,那么开启一个计时器
    timer = setTimeout(() => {
    //当计时器结束之后执行
      fn.apply(this, arguments);
      //将计时器清空否则永远不会结束
      timer = null;
    }, delay);
  };
}

2.第二种方法:立即执行一次

function throttle(fn, delay) {
   let timer = null;
  return function () {
  //之前没有计时或者距离上次执行已经超过timer秒
    if (!t||Date.now()-t>=timer) {
      callback.apply(this,argument)
      t =Date.now()
    }
    //如果不存在计时器,那么开启一个计时器
    timer = setTimeout(() => {
    //当计时器结束之后执行
      fn.apply(this, arguments);
      //将计时器清空否则永远不会结束
      timer = null;
    }, delay);
  };
}

3.最终写法:可选择是否立即执行

//节流的最终形态:可选择是否立即触发
function throttle(fn, delay, immediate = true) {
  //如果没有传immediate则默认true
  if (immediate) {
    let t = null
    return function () {
      if (!t || Date.now() - t > delay) {
        //如果当前时间戳不存在或者当前时间戳减去上一次时间戳大于delay
        fn.apply(this, arguments) //执行函数
        t = Date.now() //得到当前的时间戳
      }
    }
  } else {
  //设置一个定时器id
    let timer = null
    return function () {
    //如果timer值不是setTimeout返回的则直接返回不做处理
      if (timer) {
        return
      }
      timer =setTimeout(function () {
        fn.apply(null, arguments)
        timer = null
      }, delay)
    }
  }
}

http://www.kler.cn/a/2795.html

相关文章:

  • 时间管理的三个痛点
  • -1大于4?负数与无符号整数类型:size_t的比较问题(strlen)
  • 第74期 | GPTSecurity周报
  • 使用 start-local 脚本在本地运行 Elasticsearch
  • 01-Ajax入门与axios使用、URL知识
  • 《MYSQL45讲》kill不掉的线程
  • 如何高效的导出 百万级别的数据量 到 Excel?
  • vscode 常用插件记录
  • 交通信号标志识别软件(Python+YOLOv5深度学习模型+清新界面)
  • leetcode每日一题:1005. K 次取反后最大化的数组和
  • Spring八股文
  • 菜鸟刷题Day2
  • 传输层协议----UDP/TCP
  • 利用python写一个gui小公举--制作一个小公举
  • 经典七大比较排序算法 ·上
  • 【Zblog建站】搭建属于自己的博客网站,并内网穿透实现公网访问
  • react教程01 入门
  • Golang每日一练(leetDay0014)
  • MySQL主从复制
  • 【设计模式】23种设计模式之七大原则
  • Docker6种网络配置详解,网络模式应该这么选
  • 6.S081——Lab1——Xv6 and Unix utilities
  • 7个Python中的隐藏小技巧分享
  • 算法刷题总结 (二) 回溯与深广搜算法
  • 前端处理并发的最佳实践
  • 《网络安全入门到精通》 - 2.1 - Windows基础 - DOS命令Windows防火墙Windows共享文件