前言 :
防抖函数和节流函数是优化高频率执行js代码的一种手段,js中的一些事件,比如浏览器中的resize,scroll,鼠标事件mouseover,mousemove,input输入框的keypress等事件在触发时,会不断的调用绑定在事件上的回调函数,极大的浪费资源,降低前端性能,为了优化体验,需要对这类事件进行调用的次数的限制,这里就需要我们的函数节流和函数防抖.
防抖和节流异同点
相同:在不影响客户体验的前提下,将频繁的回调函数,进行次数缩减,避免大量计算导致的页面卡顿
不同:防抖是将多次执行变为是最后一次执行,节流是将多次执行变为在规定时间内只执行一次
防抖函数
防抖概念:指触发事件后在规定时间内回调函数只能执行一次,如果在规定时间内又触发了该事件,则会重新开始算规定时间。(每次执行事件都会清除前一次的事件)
打个简单的比如:
函数防抖就是法师发技能的时候要读条,技能读条没完再按技能就会刷新技能,重新进行读条。
也就是说,这个事件还未执行完,但是你再一次触发了这个函数,这个就会事件抖动的效果,如何避免这个问题,就用到了防抖函数的思想,就是在每次事件开始前都需要清理一下之前的事件。
代码如下:
var debounce=function(fn, wait){
var timer = null;
return function(){
if(timer!== null) clearTimeout(timeout);
timer= setTimeout(fn, wait);
}
};
function yourfunc(){
console.log(Math.random())
};
window.addEventListener('scroll',debounce(yourfunc,1000));
节流函数
节流的概念:当持续触发事件时,在规定时间段内只能调用一次回调函数。如果在规定时间内又触发了该事件,则什么也不做,也不会重置定时器.
<script>
var throttle = function(func, delay) {
var timer = null;
return function() {
var context = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function() {
func.apply(context, args);
timer = null;
}, delay);
}
}
}
function yourfunc() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(yourfunc, 1000));
</script>
上面这个方法的执行理念就是,当函数开始执行可以设置一个标记变量,当函数完全执行完全,再把标记的变量设置为原来的变量,每次执行的时候都需要判断变量的值.
防抖函数和节流函数的比较
相同点:
都可以通过使用 setTimeout 实现。 目的都是,降低回调执行频率。节省计算资源。
不同点:
-
1)函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout 和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能。
-
2)函数防抖关注一定时间连续触发的事件只在最后执行一次,而函数节流侧重于一段时间内只执行一次。
防抖函数使用场景
连续的事件,只需触发一次回调的场景有:
搜索框搜索输入。只需用户最后一次输入完,再发送请求 手机号、邮箱验证输入检测 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
函数节流使用场景
间隔一段时间执行一次回调的场景有:
滚动加载,加载更多或滚到底部监听
谷歌搜索框,搜索联想功能
高频点击提交,表单重复提交
在Vue中的使用
Lodash是一个轻量级的JavaScript工具函数库,它方便了日常开发中对数据的操作,提高了开发效率。
日常开发中,通常会对数据,特别是数组和对象进行各种读写等操作:比如去重,拷贝,合并,过滤,求交集,求和等等。
而在lodash中也有对函数节流和函数防抖的介绍
lodash中的函数节流
_.throttle(func, [wait=0], [options={}])
func (Function): 要节流的函数。
[wait=0] (number): 需要节流的毫秒数。
[options={}] (Object): 选项对象。
[options.leading=true] (boolean): 指定调用在节流开始前,默认true。
[options.trailing=true] (boolean): 指定调用在节流结束后,默认true
lodash中函数的防抖
_.debounce(func, [wait=0], [options={}])
func (Function): 要防抖动的函数。
[wait=0] (number): 需要延迟的毫秒数。
[options={}] (Object): 选项对象。
[options.leading=false] (boolean): 指定在延迟开始前调用,默认false。
[options.maxWait] (number): 设置 func 允许被延迟的最大值。
[options.trailing=true] (boolean): 指定在延迟结束后调用,默认true。
补充:用户在频繁操作事件的时候,除了可以用到函数的防抖和节流之外还可以用到其他的方法
-
1)防止重复点击可以添加一个开关,让这个开关默认是true,第一次点击,将其变为false,点击事件的执行需要判断这个开关是否为true,为true执行,false不执行
-
2)还有一个方法就是点击后off(‘click’)解除绑定事件,然后设置定时器一定事件后重新on(‘click’,函数名)绑定事件。