消抖(debounce
):
- 当函数被调用后,n秒之后才会触发该函数,如果在此期间函数再次被调用,则重新开始计时,n秒之后才会触发该函数。
其作用是为了避免某个事件在短时间内连续触发从而影响性能,也可用于避免在一定时间内重复提交表单等。
节流(throttle
):
- 函数被调用后,立即触发该函数,在之后的n秒之内不能再次重复触发。
该函数可以用于限制浏览器scroll,mousemove等高频触发事件的触发频率
下面介绍debounce
和throttle
的实现方式
这两种方法在lodash里已经给封装好了,下面用原生js实现
debounce
利用闭包,设置一个timer:
- 每次执行都clearTimeout(timer)
- 每次执行设置timer = setTimeout()执行函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function debounce(func, delay) { let timer = null return function() { clearTimeout(timer) timer = setTimeout(()=> {
let args = Array.from(arguments)
func.apply(this, args)
}, delay) } }
|
debounce实例
在input事件使用debounce,减少触发次数,这里设置延迟为1秒,是不是有点像搜索引擎的提示呈现
代码
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 32 33 34 35 36 37 38 39 40 41
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <input type="text" placeholder="debounce"/> <p>debounce test</p> </body> </html>
<script> const input = document.querySelector('input') const p = document.querySelector('p') input.addEventListener('input', debounce(function(e){ p.innerText = e.target.value }, 1000))
function debounce(func, delay) { let timer = null return function() { clearTimeout(timer) timer = setTimeout(()=> {
let args = Array.from(arguments)
func.apply(this, args)
}, delay) } }
</script>
|
codepen
throttle
利用闭包,设置一个exec记录当前函数执行状态:
- 若正则执行,则跳过if,直接退出函数
- 若没有在执行,则执行函数,设置exec为true,一段时间后置为false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function throttle(func, delay) { let exec = false return function() { if (!exec){ let args = Array.from(arguments) func.apply(this, args) exec = true
setTimeout(()=>{ exec = false }, delay) } } }
|
throttle实例
这里同样使用上面的例子,看看有什么区别
如果还看不出区别,请看下图
很明显了对吧
不过throttle一般不用于这里,一般用于scroll,mousemove等触发频率很高的事件,对其进行限制
codepen
以上就是对debounce和throttle的介绍,希望能帮助到大家