js 防抖实现,js防抖函数,js防抖具体实现以及详细原理步骤说明(附实例)

js 防抖实现,js防抖函数,js防抖具体实现以及详细原理步骤说明(附实例)

“油门防抖”和“油门防抖”这两个词对于一些刚接触JavaScript的同学来说可能会比较陌生。下面文章主要介绍js防抖的具体实现和详细原理步骤的相关信息,通过示例代码详细介绍。有需要的朋友可以参考一下。

目录

为什么?为什么要有防抖?什么?什么是防抖?怎么会?防抖怎么用?什么是延迟去抖?总结:本文将从一个案例一步步展开,在这个案例中,你不仅可以知道防抖是如何实现的,还可以了解到this、apply、arguments等知识的具体应用。

Why?为啥要有防抖?

有时候频繁的事件触发是没有意义的,不仅影响性能,还可能造成卡顿。

为了避免这种情况,我们需要使用防抖来解决这个问题。

What? 啥是防抖?

去抖:简单来说,防抖的效果是在一定的时间间隔内,多次触发只有一次触发产生

How? 防抖咋用啊?

让我们从一个例子开始:

我们设置一个按钮来切换上面文本的颜色,如下:

h2 id='demo'hello/h2

Button id='btn '单击我/button

脚本类型='文本/javascript '

var BTN=document . getelementbyid(' BTN ');

btn.addEventListener('click ',changeColor,false);

var flag=true

函数changeColor() {

如果(标志){

document . getelementbyid(' demo '). style . color=' pink '

}否则{

document . getelementbyid(' demo '). style . color=' blue '。

}

flag=!旗

}

如果想让用户在1秒内不频繁切换,也就是只能在1秒内改变文字颜色。

那么你可以用定时器来实现,但是直接写一个定时器是不够的,因为你只能实现多次触发延时执行而不能实现限制触发。

您可以使用一个变量来确定每次按下按钮时是否触发了计时器。如果已经触发,可以清除已经触发不到1秒的定时器,然后启动新的定时器1秒。如果没有被触发,说明你在1秒内没有按。只需创建一个新的1秒钟计时器。

这样才能保证防抖效果。请看代码:

h2 id='demo'hello/h2

Button id='btn '单击我/button

脚本类型='文本/javascript '

var BTN=document . getelementbyid(' BTN ');

btn.addEventListener('click ',debounce(changeColor),false);

var flag=true

函数changeColor() {

如果(标志){

document . getelementbyid(' demo '). style . color=' pink '

}否则{

document . getelementbyid(' demo '). style . color=' blue '。

}

flag=!旗

}

功能去抖(fn) {

设t=空

返回函数(){

//清除计时器(如果存在)

如果(t) {

清除超时(t)

}

//否则,创建新的计时器

t=setTimeout(function() {

fn()

}, 1000)

}

}

/脚本

看完代码,你可能会有以下疑惑:

1.怎么这个debounce函数里面不能直接写执行内容吗?非要return一个函数?

解:因为你已经把changeColor函数作为参数传递给了去抖函数(见下面的代码变化),所以如果你想在btn上绑定去抖事件,就要把修改后的changeColor事件作为回调函数写入去抖。

//btn.addEventListener('click ',changeColor,false);

btn.addEventListener('click ',debounce(changeColor),false);

2.这个 let t = null; 岂不是会每次都将 t 置为 null ??这可咋实现呢?

解:你以为btn绑定了去抖,所以你以为每个触发器都会执行t=null。

泄漏!Btn绑定了去抖(changeColor)!这个括号不能忽略。实际上,每次触发click事件,都会执行它的回调,也就是返回的内容。let t=null在初始化期间只执行一次。

虽然目前已经达到了防抖的效果,但是如果这样写的话,你会发现changeColor函数无法获得事件对象,也就是说无法获得本该属于它的事件。

要让它回到它的事件,您可以这样做:

1.基于当前事件已经在去抖的事实,可以使用e作为参数传递给 debounce 里回调的函数

2.放e传给回调函数中定时器里的 fn(),即fn(e)

功能去抖(fn) {

设t=空

//在此发送E

返回函数(e) {

如果(t) {

清除超时(t)

}

t=setTimeout(function() {

//再次带到fn

fn(e)

}, 1000)

}

}

这时候你会发现changeColor已经拿到事件对象了!

如果你问,这个E跟你有什么关系?

那我只能说你得到E的时候可以用E做点什么(e.target可以改变等等。),而且E不做什么不传也没关系,只是这样写可以更接近一个完美的防抖功能。

但是你不能保证changeColor只需要传一个参数,所以传参数的时候不能只写一个e就传多个参数。所以,为了更完美,还是换一个吧。

谈到传递多个参数,您可能会想到参数列表arguments 。没错!就是这样!

如果你不知道论点,请到:学习论点。

arguments对象是局部变量,可用于所有(非箭头)函数。可以使用arguments对象在函数中引用函数的参数。该对象包含传递给函数第一个参数在索引0处的每个参数。

首先,我们试着用arguments[0] 代替刚刚通过的E,你会发现:

该返回中的参数[0]根本无法到达计时器,更不用说changeColor了。

因为每个函数里的 arguments 都是自己函数内部的,计时器中的函数没有参数,所以未定义。

要解决这个问题,可以通过赋值来保存参数,也可以使用arrow函数。

接下来用箭头函数的方法求解:

因为arrow函数内部没有arguments对象,所以它会在外部寻找,这样您就可以获得参数作为回报。

功能去抖(fn) {

设t=空

返回函数(){

Console.log('我是回调的参数',arguments[0]);

如果(t) {

清除超时(t)

}

//在这里使用箭头函数

t=setTimeout(()={

fn(参数[0])

Console.log('我是计时器中的参数',arguments [0])

//console.log(this)

}, 1000)

}

}

这样就实现了传参[0]的问题。如果有多个参数,可以使用apply 方法将整个参数作为参数传递,如下所示:

功能去抖(fn) {

设t=空

返回函数(){

如果(t) {

清除超时(t)

}

t=setTimeout(()={

fn.apply(这,参数)

}, 1000)

}

}

其中apply方法的第一个参数还可以将 changeColor 的 this 由 Window 转为 btn是一箭双雕的大动作。(因为arrow函数将寻找这种继承,所以它获得这种继承,然后将其传递给changeColor)

如果您不知道申请,请访问:学习申请

写到这里,一个 延迟debounce诞生了!

什么是延迟debounce??

顾名思义,在延迟结束那一刻才触发回调。

如果你觉得每次按下按钮都要等着换颜色真的很烦,估计你会先关闭网页再换颜色。

前缘debounce可以解决这个问题!(即事件在计时器启动时触发)

再改代码就能得到前沿去抖了!

功能去抖(fn) {

设t=空

返回函数(){

//使用firstClick记录每次定时器启动的第一次按下动作。

var firstClick=!t

如果(t) {

清除超时(t)

}

如果(首次点击){

fn.apply(这,参数)

}

//等待1秒,将T设置为null。如果你在这1秒钟内再次点击事件,你将进入if(t)的执行

t=setTimeout(()={

t=空

}, 1000)

}

}

这个前缘debounce将会实现每次连续点击后先响应一次事件,再去等1秒。

总结

以上就是本文关于js防抖的具体实现和详细的原理和步骤。关于js防抖实现的更多信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: