关于js的防抖和节流
看例子:
当鼠标在橙色区域来回移动时
可以看到数值在不可控的快速增加,说明该函数被频繁触发。
对于这种快速连续触发和不可控的高频率触发问题,我们有
防抖(debounce)
和
节流(throttle)
这两种解决方法。
防抖(debounce)
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
防抖函数分为非立即执行版和立即执行版。
//准备工作
let num = 1;//定义一个初始值
let content = document.getElementById('content');//先获取一下
function count() {//自增函数
content.innerHTML = num++;
};
非立即执行版:短时间内多次触发函数,只会执行最后一次,中间的不执行
//非立即执行版
function debounce(func, wait) {
let timer;
return function () {
let context = this; // 注意 this 指向
let args = arguments; // arguments中存着e
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args)
}, wait)
}
}
//使用方法
content.onmousemove = debounce(count, 1000);
立即执行版:短时间内多次触发函数,只会执行第一次,中间的不执行
//立即执行版
function debounce(func, wait) {
let timer;
return function () {
let context = this;
let args = arguments; // arguments中存着e
if (timer) clearTimeout(timer);
let callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait)
if (callNow) func.apply(context, args);
}
}
//使用方法
content.onmousemove = debounce(count, 1000);
节流(throttle)
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。
用一句话总结防抖和节流的区别:防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行
节流函数主要有两种实现方法:时间戳和定时器。
时间戳版:获取上一次触发的时间再减去当前触发的时间,如果大于指定时间就会被执行,否则就不会执行
// 时间戳版
function throttle(func, wait) {
let previous = 0;
return function () {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
//使用方法
content.onmousemove = throttle(count, 1000);
定时器版:如果一直不断地触发函数,它会按照指定的时间执行函数
//定时器版
function throttle(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
//使用方法
content.onmousemove = throttle(count, 1000);
如有错误请指正
版权声明:本文为morensheng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。