栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

一起扫荡JavaScript(十)—— 防抖与节流

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一起扫荡JavaScript(十)—— 防抖与节流

防抖和节流其实是一种思想,是一种性能优化的方案,并非Javascript独有,只不过Javascript多运行于用户端(也就是前端),而用户端的交互是很频繁的,有不少的请求或交互实际上是重复的。而这就给了防抖和节流很大的用武之地。
  ① 防抖

  防抖,顾名思义,防止手抖,曾经多少英雄豪杰,因为一时手抖擦枪走火而悔恨终身,也曾经多少富甲一方的商贾因为手抖多打了个0而家破人亡。

  防抖的作用就是无论你是手滑了还是手抖了,还是打多了一个0,它仍然会沿着旧有的节奏走,从而防止手滑导致的一系列问题。

  防抖的实现思路大体上是这样:

  当持续触发事件时(比如用户输入时不断的键盘敲击),一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

  可以看看下面的函数:


const debounce = (fn, wait) => {

    let timeout = null;

    return function () {

 timeout !== null && clearTimeout(timeout);

 timeout = setTimeout( fn, wait );
    }
};

  定时器一边在走,而这边继续监听触发,假如两次触发的时间间隔大于设置的防抖延迟,则这时候定时器里的函数已经执行了,而假如小于,定时器里的函数还没来得及执行,定时器就被清除了。

  看一下调用,假如此时有一块DOM结构是这样的话。

在调用上方的防抖函数debounce。如下:

const debounceDiv = () => console.log('debounceDiv'); // 定义一下需要触发的函数

document.querySelector('.shake').addEventListener('mousemove', debounce(debounceDiv, 300));

  鼠标滑动的触发频率是很高的,可能不小心手抖鼠标滑动了一大下,这时候可能某个函数就被执行了好几十次,而处于中间的那些可能实际上我们并不需要,而通过防抖机制,尽管这个函数所处的环境被触发了几十次,但该函数实际上只会执行最后的那一次,这样就节省了资源,提高了性能。

  再来看防抖实际应用中很多的例子 —— 输入。

  假如你现在在编辑Markdown文本,或者搜索栏的一些输入,而这时候可能Javascript做的一个监听动作就是你键盘的按下或抬起动作,但相比你打的字而言,你的键盘敲击速度实在是太快了,快到可能接近程序的一些操作或者搜索栏的一些结果联想,甚至比之还快,但就如这一个简单的打字而言,用户刚刚打了一个f,程序不管不顾立马执行,这没有问题,但可能用户是想打一个“防”字,他对f是几乎无察觉无认知的,而这部分假如还去执行结果,无疑是一种极大的浪费。

  看看代码,由于这时候我们需要在一个恰当的时机,将用户输入的值打印到界面上,原来的debounce 函数需要稍微变一下,将监听的this值做下绑定:
  变成:


const debounce = (fn, wait) => {

    let timeout = null;

    return function () {

 timeout !== null && clearTimeout(timeout);

 let _self = this;

 timeout = setTimeout( () => fn.call(_self), wait);
    }
};

  再看一下应用:

const debounceInput = function () { document.querySelector('.shake').innerHTML = this.value; }

document.querySelector('.shake-input').addEventListener('keyup', debounce.call(this, debounceInput, 300));

  这样10行代码左右也就简单的完成了我们的防抖。

  ② 节流

  节流,也顾名思义 —— 任尓滔滔江水,我自涓涓细流。它就像一个水闸,或者说管道,尽管可能某段时间内这个事件触发了很多次,但在这里,统统无效,只会每间隔一定时间触发一次。它更贴切的一个描述可以看下图:

  当持续触发事件时,保证一定时间段内只调用一次事件处理函数,这就是节流。

const throttle = (fn, delay) => {

    let timeNode = Date.now();

    return function () {

 let time = Date.now();

 if(time - timeNode >= delay) {

     fn.call(this);

     timeNode = Date.now();
 }
    }
}

const throttleDiv = () => console.log('throttleDiv');

const throttleInput = function () { document.querySelector('.throttle').innerHTML = this.value; }

document.querySelector('.throttle').addEventListener('mousemove', throttle(throttleDiv, 300));

document.querySelector('.throttle-input').addEventListener('keyup', throttle.call(this, throttleInput, 300));

最后吧,贴一下完整的测试用例。

html部分:




    
    
    
    document
    


    

js部分



//  防抖
// 函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时

const debounce = (fn, wait) => {

    let timeout = null;

    return function () {

 timeout !== null && clearTimeout(timeout);

 let _self = this;

 timeout = setTimeout( () => fn.call(_self), wait);
    }
};

const debounceDiv = () => console.log('debounceDiv');

const debounceInput = function () { document.querySelector('.shake').innerHTML = this.value; }


document.querySelector('.shake').addEventListener('mousemove', debounce(debounceDiv, 300));

document.querySelector('.shake-input').addEventListener('keyup', debounce.call(this, debounceInput, 300));


//  节流

const throttle = (fn, delay) => {

    let timeNode = Date.now();

    return function () {

 let time = Date.now();

 if(time - timeNode >= delay) {

     fn.call(this);

     timeNode = Date.now();
 }
    }
}

const throttleDiv = () => console.log('throttleDiv');

const throttleInput = function () { document.querySelector('.throttle').innerHTML = this.value; }

document.querySelector('.throttle').addEventListener('mousemove', throttle(throttleDiv, 300));

document.querySelector('.throttle-input').addEventListener('keyup', throttle.call(this, throttleInput, 300));

  好了,防抖和节流就先说到这了,以后有想到的再补充吧。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号