什么是防抖
函数防抖(debounce):
概念: 延迟要执行的动作,若在延迟的时间内再次触发动作,则取消之前的动作,重新计算延迟时间
举例: 大家都用过无线键盘、鼠标,它们都有一个共同的特点,为了节省待机时长,都会内置防抖功能。当你在多少时间内没有动鼠标键盘时,它们会自动进入休眠状态,当你动了一下鼠标键盘,它们就会立即苏醒。
实现: 使用定时器setTimeout()
应用: 在前端,大部分情况下会在制作搜索功能的时候使用防抖,例如百度搜索(百度的服务器很强大,近几年已经不使用防抖了)
简而言之: 键盘如果在10 分钟内,没有任何操作就会进入休眠状态,当你在9 分钟时动了一下键盘(按了一下),他就会重新计算10 分钟后进入休眠(如果你在10 分钟内一直使用键盘,它就不会休眠)
具体实现
这里使用到了闭包,关于什么是闭包,你可以看我的这篇文章:https://blog.lete114.top/article/JavaScript-Closure.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <div><input type="text" /></div> <script> var inp = document.querySelector("input"); inp.onkeyup = debounce(function () { console.log(this.value); }, 300);
function debounce(callback, wait) { let timeout = null; return function () { if (timeout) clearTimeout(timeout); timeout = setTimeout(() => callback.apply(this,arguments), wait); }; } </script>
|
什么是节流
函数节流(throttle):
概念: 规定一个时间段,让函在规定的时间内只能执行一次,避免频繁触发动作
举例: 你有个评论系统,你需要限制用户的提交操作,在规定的时间内容,只能提交 1 次,如用户发了一条评论,在10 秒内如果触发一条或多条新的评论,则提示您评论太快啦!请稍后评论。,只有超过10 秒再次评论才能评论成功,如果没有做节流操作的话,很可能会照成很多次评论(评论攻击),假设有些小人用脚本频繁发生评论,1 分钟内可能评论不止60 条,如果做了防抖处理的话,1 分钟只能评论6 条
实现: 定时器 + 限制标识、定时器 + 时间戳
应用: 当鼠标滚轮滚动的时候,每隔两秒执行一次
具体实现
定时器 + 限制标识
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <style> body { height: 200vh; } </style> <script> window.onscroll = throttle(function () { let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log("滚动条位置:" + scrollTop); }, 2000);
function throttle(callback, wait) { let flag = true; return function () { if (flag) { flag = false; setTimeout(() => { flag = true; callback.apply(this,arguments); }, wait); } }; } </script>
|
定时器 + 时间戳
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <style> body { height: 200vh; } </style> <script> window.onscroll = throttle(function () { let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log("滚动条位置:" + scrollTop); }, 2000);
function throttle(callback, wait) { let pre = 0; return function () { let now = new Date(); if (now - pre > wait) { callback.apply(this,arguments); pre = now; } }; } </script>
|
总结
函数防抖(debounce): 将多次操作合并为一次操作进行。原理是维护一个计时器,在规定时间后触发函数,但是在规定时间内再次触发的话,就会取消之前的计时器而重新设置计时。只有最后一次操作能被触发
简而言之: 已经触发函数,如果在2s内继续触发函数,则永远都不会触发函数,直到你在2s内不再触发函数,才会触发一次
函数节流(throttle): 规定时间内只触发一次函数。如果在规定时间内多次触发函数,最终只会触发一次函数
简而言之: 已经触发函数,如果在2s内继续触发函数,只会触发一次(2s内不管触发多少次,最终只会触发一次函数)