“油门防抖”和“油门防抖”这两个词对于一些刚接触JavaScript的同学来说可能会比较陌生。下面文章主要介绍js防抖的具体实现和详细原理步骤的相关信息,通过示例代码详细介绍。有需要的朋友可以参考一下。
目录
为什么?为什么要有防抖?什么?什么是防抖?怎么会?防抖怎么用?什么是延迟去抖?总结:本文将从一个案例一步步展开,在这个案例中,你不仅可以知道防抖是如何实现的,还可以了解到this、apply、arguments等知识的具体应用。
Why?为啥要有防抖?
有时候频繁的事件触发是没有意义的,不仅影响性能,还可能造成卡顿。
为了避免这种情况,我们需要使用防抖来解决这个问题。
What? 啥是防抖?
去抖:简单来说,防抖的效果是
在一定的时间间隔内,多次触发只有一次触发产生
。How? 防抖咋用啊?
让我们从一个例子开始:
我们设置一个按钮来切换上面文本的颜色,如下:
h2 id=demohello/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=demohello/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防抖实现的更多信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!