函数节流 与 函数防抖
防抖与节流都是为了限制函数的执行次数,用来优化事件频率过高导致性能问题。
- 防抖:触发高频事件后 n 秒内函数只执行一次,在此期间如果再次被触发,则重新计算时间;
- 节流:事件触发后,n 秒内无论点击多少次,都只按照第一次时间计算。
防抖 debounce
实现思路:把目标动作包装到 setTimeOut 中,然后该方法是一个事件的回调函数,如果该回调在指定事件内被重新触发,则回调不执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>debounce</title>
</head>
<body>
<div>
<div class="outer">
<div class="input">
<input type="text" placeholder="test">
</div>
<script type="text/javascript">
function debounce( func, delay){
var timeout;
return function( e){
console.log( '清除', timeout, e.target.value);
clearTimeout( timeout); //每次调用 debounce 清除之前的 time, 确保只执行一次。
var context = this;
var args = arguments;
console.log( 'new', timeout, e.target.value);
timeout = setTimeout( function(){
console.log( '-----');
func.apply( context, args);
}, delay)
}
}
var validate = debounce( function(e){
console.log( 'change', e.target.value, new Date());
}, 3000);
document.querySelector('input').addEventListener('input', validate);
</script>
</body>
</html>
节流 throttle
实现思路:设置一个计时器,如果计时器不满足条件则不执行;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>debounce</title>
</head>
<body>
<div>
<div class="outer">
<div class="input">
<input type="text" placeholder="test">
</div>
<script type="text/javascript">
function throttle( func, delay){
var preTime = Date.now();
return function(){
var context = this;
var args = arguments;
var nowTime = Date.now();
if( nowTime - preTime > delay){
func.apply( context, args);
preTime = Date.now();
}
}
}
var validate = throttle( function(e){
console.log( 'change', e.target.value, new Date());
}, 1000);
document.querySelector('input').addEventListener('input', validate);
</script>
</body>
</html>