防抖与节流

节流

核心思想: 如果在定时器的时间范围内再次触发,则不予理睬,等当前定时器完成,才能启动下一个定时器任务。即一段时间内,多个任务只认第一个

基本代码如下

function throttle(fn, interval) {
  let flag = true;
  return (...args) => {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn(args);
      flag = true;
    }, interval);
  };
}
原理
  1. 首先在任务外层定义一个flag=true(不用闭包可以是全局)
  2. 如果有调用时flag=false
  3. 然后在以后的多次调用中判断flag是否为false,即任务是否已经正在执行,以防止重复调用
例子
<body>
  <div>任务执行了<span id="show">0</span>次</div>
  <br />
  <button onclick="taskRun()">任务执行 请连续急速点击</button>
</body>
// 1. 先定义一个节流函数
function throttle(fn, interval) {
  let flag = true;
  return (...args) => {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn(args);
      flag = true;
    }, interval);
  };
}
// 2. 初始化任务
let count = 0;
const task = throttle(() => {
  count++;
  document.querySelector("#show").innerHTML = count;
}, 3000); // 不管调用多少次,保证间隔3秒
// 3. 运行函数
function taskRun() {
  task();
}

防抖

核心思想: 每次事件触发则删除原来的定时器,建立新的定时器。即多次操作,只认最后一次操作

基本代码如下

function debounce(fn, delay) {
  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() {
      fn(args);
    }, delay);
  };
}
原理
  1. 首先在任务外层定义一个timer=null(不用闭包可以是全局)
  2. 每次重复调用时判断有没有存在的定时器,如果有就清除,然后重新定义
例子
<body style="height:5000px">
  <div class="tip">状态:<span id="show">停止滚动</span> (请滚动鼠标)</div>
</body>
// 1. 先定义一个防抖函数
function debounce(fn, delay) {
  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() {
      fn(args);
    }, delay);
  };
}

// 2. 初始化任务
let count = 0;
const task = debounce(() => {
  count++;
  document.querySelector("#show").innerHTML =
    "停止滚动 调用主要任务" + count + "次";
}, 300); // 不管调用多少次,保证任务只执行最后一次
// 3. 运行函数
function taskRun() {
  task();
}
window.onscroll = () => {
  console.log("scroll");
  document.querySelector("#show").innerHTML = "滚动中...";
  taskRun();
};

完整demo


zpfei
186 声望7 粉丝

往事如风~