防抖 & 节流
发布于: 1 小时前
防抖
在一定时间间隔内,多次调用一个方法,只会执行一次.
/**
*
* @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)
}
}
}
复制代码
使用方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input id="input" />
<script>
function onInput() {
console.log('1111')
}
const debounceOnInput = debounce(onInput)
document
.getElementById('input')
.addEventListener('input', debounceOnInput) //在Input中输入,多次调用只会在调用结束之后,等待500ms触发一次
</script>
</body>
</html>
复制代码
vue 中使用方式:
methods: {
getSearchUser: debounce(function() {
}, 1000)
}
复制代码
如果第三个参数 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:只在延时开始时调用
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input id="input" />
<script>
function onInput() {
console.log('1111')
}
const throttleOnInput = throttle(onInput)
document
.getElementById('input')
.addEventListener('input', throttleOnInput) //在Input中输入,每隔500ms执行一次代码
</script>
</body>
</html>
复制代码
划线
评论
复制
发布于: 1 小时前阅读数: 4
版权声明: 本文为 InfoQ 作者【达摩】的原创文章。
原文链接:【http://xie.infoq.cn/article/3df24cb8ffad7aed5914e95f0】。文章转载请联系作者。
达摩
关注
还未添加个人签名 2019.12.04 加入
还未添加个人简介
评论