防抖和节流函数详解(立即执行/非立即执行)

在线查看效果移动鼠标触发

1.防抖(立即执行/非立即执行)

  • 什么是防抖:一个事件在触发后,设置定时器,若n秒内该事件没有再次发生,那么执行这个函数,如果n秒内该事件再次发生了,那么定时器重新开始计时。
  • 应用
    • 每次 resize / scroll 触发统计事件
    • 文本输入的验证 (连续输入文字后发送AJAX请求进行验证,验证一次就好)
  • 1.1 非立即执行版
//防抖(非立即执行)
function debounce_1(fn,wait){
  var timerId = null;
  return function(){
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this,arguments)
    },wait)
  }
}
  • 1.2 立即执行版
//防抖(立即执行)
function debounce_2(fn,wait){
  var timerId = null;
  var flag = true;
  return function(){
    clearTimeout(timerId);
    if(flag){
      fn.apply(this,arguments);
      flag = false
      }
    timerId = setTimeout(() => { flag = true},wait)
  }
}
  • 1.3 合并版
//防抖(合并版)
function debounce_merge(fn,wait = 500,isImmediate = false){
  var timerId = null;
  var flag = true;
  if(isImmediate){
    return function(){
      clearTimeout(timerId);
      if(flag){
        fn.apply(this,arguments);
        flag = false
        }
      timerId = setTimeout(() => { flag = true},wait)
    }
  }
  return function(){
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this,arguments)
    },wait)
  }
}

2.节流(立即执行/非立即执行)

  • 什么是节流:一个事件在n秒内被多次触发,但绑定的函数在期间只会执行一次(也就是降低函数的执行频率)
  • 应用
    • 与mousemove keyup/keydown 等相密切联系的函数
  • 2.1 非立即执行版
//定义函数
//节流(非立即执行)
function throttle_1(fn,wait){
  var flag = true;
  return function(){
    if(flag == true){
      flag = false
      var timer = setTimeout(() => {
        fn.apply(this,arguments)
        flag = true
      },wait)
    }
  }
}
  • 2.2 立即执行版
//节流(立即执行)
function throttle_2(fn,wait){
  var flag = true;
  var timer = null;
  return function(){
    if(flag) {
      fn.apply(this,arguments);
      flag = false;
      timer = setTimeout(() => {
        flag = true
      },wait)
    }
  }
}
  • 2.3 合并版
//节流(合并)
function throttle_merge(fn,wait = 500,isImmediate = false){
  var flag = true;
  var timer = null;
  if(isImmediate){
    return function(){
      if(flag) {
        fn.apply(this,arguments);
        flag = false;
        timer = setTimeout(() => {
          flag = true
        },wait)
      }
    }
  }
  return function(){
    if(flag == true){
      flag = false
      var timer = setTimeout(() => {
        fn.apply(this,arguments)
        flag = true
      },wait)
    }
  }
}

3.补充

  • 看文字远不如亲自操作了解得透彻,希望还不太明白的小伙伴在下面演示代码具体操作操作
  • 这里的几个函数都是使用的setTimeout来实现的,也可以使用 Date.now()来实现,思路一样,偷个懒就不写了,嘿嘿;
  • 合并版的 debounce(fn,wait,isImmediate) throttle(fn,wait,isImmediate)

4.演示代码

截图
防抖和节流函数详解(立即执行/非立即执行)_第1张图片
在线查看效果


<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Documenttitle>
  <style>
    body{height: 1200px;}
  	div{width: 100%;background-color: lightcyan;overflow: hidden;}
	p{float: left;width: 10px;height:10px;background-color: pink;margin: 1px;}
  style>
head>
<body>
    防抖(非立即执行) <div id="d1_1">div>
    防抖(立即执行) <div id="d1_2">div>
    节流(非立即执行) <div id="d2_1">div>
    节流(立即执行) <div id="d2_2">div>
    
body>
<script>
//防抖(非立即执行)
function debounce_1(fn,wait){
  var timerId = null;
  return function(){
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this,arguments)
    },wait)
  }
}
//防抖(立即执行)
function debounce_2(fn,wait){
  var timerId = null;
  var flag = true;
  return function(){
    clearTimeout(timerId);
    if(flag){
      fn.apply(this,arguments);
      flag = false
      }
    timerId = setTimeout(() => { flag = true},wait)
  }
}
//节流(非立即执行)
function throttle_1(fn,wait){
  var flag = true;
  return function(){
    if(flag == true){
      flag = false
      var timer = setTimeout(() => {
        fn.apply(this,arguments)
        flag = true
      },wait)
    }
  }
}
//节流(立即执行)
function throttle_2(fn,wait){
  var flag = true;
  var timer = null;
  return function(){
    if(flag) {
      fn.apply(this,arguments);
      flag = false;
      timer = setTimeout(() => {
        flag = true
      },wait)
    }
  }
}

//定义事件函数
function debounce_fn1(){ addElement(d1_1) }
function debounce_fn2(){ addElement(d1_2) }
function throttle_fn1(){ addElement(d2_1) }
function throttle_fn2(){ addElement(d2_2) }
// function origin(){ addElement(d3) }

//注册事件
var body = document.getElementsByTagName('body')[0]
body.addEventListener("mousemove",debounce_1(debounce_fn1,500))
body.addEventListener("mousemove",debounce_2(debounce_fn2,500))
body.addEventListener("mousemove",throttle_1(throttle_fn1,500))
body.addEventListener("mousemove",throttle_2(throttle_fn2,500))
// body.addEventListener("mousemove",origin)


//辅助函数
function addElement(f){
  var node=document.createElement("p");
	f.appendChild(node);
}
script>
html>

你可能感兴趣的:(js,性能优化)