乘风破浪 激流勇进
你好!欢迎来看Tuziki's Planet !

用户体验设计——防抖函数的微操

防抖函数(debounce function)是一种限制函数执行频率的技术。它确保一个函数在特定时间内只被执行一次,即使它被多次触发。这对于处理像滚动、窗口调整、键盘事件等频繁触发的事件特别有用。

function debounce(func, wait) {
    let timeout;

    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };

        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
};

// 使用示例
const handleResize = debounce(() => {
    console.log('窗口大小改变了!');
}, 1000);

window.addEventListener('resize', handleResize);

一般来说,上面是我们需求,但是有一些情况下,是需要先执行一次之后,拦截剩下后面所有的请求,比如:


1.点击“点赞按钮”,立即生效一次,并执行点赞动画,发送点赞请求,后面一段时间内的重复点击则应视为无效点击,可以有动画执行,但是不能有接口请求,当然这里也可能是第一次点击是点赞,第二次是取消


2.当执行一些滑动加载的动画时,需要根据滑动的操作来改变UI布局,比如在H5的页面中,一般氛围头部基础信息区,中间信息列表,底部的菜单Tabbar,因为手机屏幕的大小限制,有时需要在列表向上滚动时缩小头部的信息区域的高度,这是在一般情况下的处理方式,即:“js代码如果是判定scrollTop为0时则缩小头部高度”但是在iphone中Safari浏览器会提供回弹效果,导致scrollTop = 0 会被反复触发,从而导致页面UI反复弹弹弹,这里很显然需要用到防抖函数,但是一般防抖函数需要在用户停止操作一段时间之后才会触发最终效果,也就是有停顿延时,并不能让用户在第一时间感受到比较顺滑的UI交互,这里可以将防抖函数修改:每当触发事件时就执行一次,在之后的指定时间内再次触发都不执行


具体的改造如下:

function debounce(func, wait) {
  let timeout;
  let executed = false; // 新增标志,用于跟踪函数是否已经执行过

  return function (...args) {
    const later = () => {
      clearTimeout(timeout);
      executed = false; // 重置执行标志,允许函数再次立即执行
    };

    if (!executed) {
      func.apply(this, args); // 立即执行函数
      executed = true; // 标记为已执行
    }

    clearTimeout(timeout);
    timeout = setTimeout(later, wait); // 重置等待时间
  };
}
// 使用示例
const handleResize = debounce(() => {
    console.log('窗口大小改变了!');
}, 1000);

window.addEventListener('resize', handleResize);


当事件首次触发时,timeout 是 null,因此 func 会被立即执行。随后,设置了一个延时,在这段延时内,无论事件被触发多少次,都不会再执行 func。一旦延时过去(即 setTimeout 执行完毕),timeout 被设置回 null,允许函数在下一次事件触发时再次执行。

返回列表
返回顶部←