JavaScript的防抖的讲解与实现

前言

在我们写项目遇到不听话的用户的时候,例如一个登录按钮,他就偏偏要反复点好几次,调用了/login接口好多次,是不是很烦?

因为涉及到ajax请求,就会有这样的情况,假设 1 秒触发了 60 次,每个回调就必须在 1000 / 60 = 16.67ms 内完成,否则就会有卡顿出现。

那么只有请求需要写防抖吗?

当然不是,凡是(可能)涉及到频繁事件触发的地方,都需要写防抖。

  1. window 的 resize、scroll
  2. mousedown、mousemove
  3. keyup、keydown
  4. click事件
  5. ……

我们简单的写一个小demo,看一下没有防抖跟有防抖的效果。

代码:

// html
<button id="btn" onclick="shake()">
		<span id="container">点击我</span>
</button>

// js
var count = 1;
var container = document.getElementById('container');
var btn = document.getElementById('btn')
function shake() {
    container.innerHTML = count++;
};

未防抖.gif


如何实现防抖

实现防抖,就要了解防抖的原理。

防抖就是,不管你触发了几次,我只看你最后触发的那一次,并且在若干时间后去执行此次事件。

根据这个原理,我们可以写出这段代码:

function preventShake(todo,time){
	let timeout;
    return function () {
        clearTimeout(timeout)
        timeout = setTimeout(todo, time);
    }
}

设置一个延迟操作的事件,并且如果再次触发就把之前的延迟取消掉,重新进入计时。

将它运用在刚刚的例子上:

var count = 1;
var container = document.getElementById('container');
var btn = document.getElementById('btn')
function shake() {
    container.innerHTML = count++;
};
function preventShake(todo,time){
    var timeout;
    return function () {
        clearTimeout(timeout);
        timeout = setTimeout(todo, time);
    }
}
btn.onclick = preventShake(shake,1000);

防抖未优化.gif


我们已经实现了基础的它,那么我们继续优化一下吧!

this指向优化

看似上面的结果没有什么太大问题,但是我们打印一下原先的shake和使用了preventShake后的this就会知道,他们指向的并不是一个东西。

  • 原先指向的是

    <button id="btn">
        <span id="container">点击我</span>
    </button>
    
  • 使用了preventShake后this指向的是Window对象!

于是我们要加一步,就是改变this指向。

欸,这个是不是又是一篇文章??

function preventShake(todo,time){
    var timeout;
    return function () {
        var that = this;
        clearTimeout(timeout);
        timeout = setTimeout(function(){
            todo.apply(that);
        }, time);
    }
}

这样就解决了this指向可能带来的问题。

最后

至此,这个简易的防抖函数就写完了,可能我想的还不太完善,希望大家给予建议,我也会及时学习,之后将其完善,争取做的更好。

感兴趣的朋友可以留个赞,我们一同进步!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JavaScript中可以使用定时器来实现节流和防抖的效果。下面是一些基本的实现示例: 1. 节流实现: ```javascript function throttle(func, delay) { let timer = null; return function() { if (!timer) { timer = setTimeout(() => { func.apply(this, arguments); timer = null; }, delay); } }; } ``` 使用示例: ```javascript function handleScroll() { console.log('Scroll event'); } const throttledScroll = throttle(handleScroll, 200); window.addEventListener('scroll', throttledScroll); ``` 上述代码中,`throttle`函数接受一个函数和一个延迟时间作为参数,返回一个新的函数。这个新的函数在被调用时,如果定时器不存在,则设置一个定时器,并在延迟时间后执行传入的函数。如果定时器已经存在,则不执行传入的函数。 2. 防抖实现: ```javascript function debounce(func, delay) { let timer = null; return function() { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, arguments); }, delay); }; } ``` 使用示例: ```javascript function handleInput() { console.log('Input event'); } const debouncedInput = debounce(handleInput, 500); inputElement.addEventListener('input', debouncedInput); ``` 上述代码中,`debounce`函数接受一个函数和一个延迟时间作为参数,返回一个新的函数。这个新的函数在被调用时,会先清除之前的定时器,然后设置一个新的定时器,并在延迟时间后执行传入的函数。 这些是基本的节流和防抖实现示例,你可以根据实际需求进行调整和扩展。希望对你有所帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是乃德也是Ned

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值