防抖和节流的区别
- 防抖是如果多次触发事件,而上一次事件还没执行完,那么就清除上一次事件,直接执行这次事件,相当于触发多次事件的话,只执行最后一次
- 节流就是多吃触发事件,在一定的时间内只执行这一次。
为什么使用防抖和节流 ?
防抖和节流都是为了解决 短时间内大量触发某函数 而导致的 性能问题, 比如触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。 但二者应对的业务需求不一样,所以实现的原理也不一样
在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。
通常这种情况下我们怎么去解决的呢?一般来讲,防抖和节流是比较好的解决方案。
作者:淘淘笙悦
链接:https://www.jianshu.com/p/c8b86b09daf0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
let num = 1;
let content = document.getElementById('content');
function count() {
content.innerHTML = num++;
};
content.onmousemove = count;
防抖是什么 ?
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
防抖函数分为非立即执行版和立即执行版。
非立即执行版:
function debounce(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
// 详细
<body>
<div id="content" style="height:150px;background-color:#ccc;"></div>
<div class="last" style="height:150px;"></div>
</body>
</html>
<script>
let num = 1;
let content = document.getElementById('content');
let last = document.querySelector('.last');
function debounce(func, wait) {
let timeout;
console.log('this1', this); // window
return function () {
console.log('this2', this);
// console.log('func',func);
let context = this;
let args = arguments;
// console.log('args',args);
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
function count(a, b, c) {
content.innerHTML = num++;
};
// count(1,2,3);
// console.log(debounce(count,1000));
content.onmousemove = debounce(count,2000); // 因为在触发鼠标滑过事件前debounce就会执行返回一个函数
// last.onmousemove = debounce; // last
// last.onclick =count; // last 只有在点击才会触发count方法 注意小括号 , 加括号代表直接调用,不叫括号代表触发调用
</script>
节流是什么
- 节流就是函数多次触发,只执行一次
// 防抖节流都是通过闭包来实现的
function throttle() {
let canRun = true;
return function () {
// 如果canRun 为false 就证明有函数在执行
if(!canRun) return
// 如果canRun为true那么往下执行的时候直接修改其值
canRun = false;
// 然后在延时器里执行这个事件
setTimeout( () => {
// 这里替换this我也不明白,反正执行你想执行的函数就对了
fn.apply(this,arguments);
/* 执行完以后修改 canRun 的状态 ,这时候就可以接收下一次事件的执行了
* 但是如果canRun的状态为false的话,那么就证明有函数没执行完,直接return,
* 等待这次函数执行完以后修改canRun 为true
*/
} , 500 )
}
}
节流 第一次延迟执行最后一次立即执行