防抖
只一定时间间隔内,多次调用一个方法,只执行一次
*
* @param {*} func 要进行debouce的函数
* @param {*} wait 等待时间,默认500ms
* @param {*} immediate 是否立即执行
*/
export function debounce(func, wait=500, immediate=false) {
var timeout
return function() {
var context = this
var args = arguments
if (timeout) clearTimeout(timeout)
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout
timeout = setTimeout(function() {
timeout = null
}, wait)
if (callNow) func.apply(context, args)
} else {
timeout = setTimeout(function() {
func.apply(context, args)
}, wait)
}
}
}
如果第三个参数immediate传true,则会立即执行一次调用,后续的调用不会在执行,可以自己在代码中试一下
节流
多次调用一个方法,按照时间间隔执行
* 节流,多次触发,间隔时间段执行
* @param {Function} func
* @param {Int} wait
* @param {Object} options
*/
export function throttle(func, wait=500, options) {
//container.onmousemove = throttle(getUserAction, 1000);
var timeout, context, args
var previous = 0
if (!options) options = {leading:false,trailing:true}
var later = function() {
previous = options.leading === false ? 0 : new Date().getTime()
timeout = null
func.apply(context, args)
if (!timeout) context = args = null
}
var throttled = function() {
var now = new Date().getTime()
if (!previous && options.leading === false) previous = now
var remaining = wait - (now - previous)
context = this
args = arguments
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout)
timeout = null
}
previous = now
func.apply(context, args)
if (!timeout) context = args = null
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining)
}
}
return throttled
}
这里重点解释一下第三个参数 options
- leading,函数在每个等待时延的开始被调用,默认值为false
- trailing,函数在每个等待时延的结束被调用,默认值是true
可以根据不同的值来设置不同的效果:
- leading-false,trailing-true:默认情况,即在延时结束后才会调用函数
- leading-true,trailing-true:在延时开始时就调用,延时结束后也会调用
- leading-true, trailing-false:只在延时开始时调用