在resize/scroll/keypress/mousemove等事件触发时,会不断的调用绑定事件上的回调函数,降低了性能。然后引入了一下两个概念。
事件节流
- 什么是事件节流
在某段时间内,不管你触发了多少次事件,我都只认第一次,并在计时结束时给予响应。
假设设置的时间为2000ms,再触发了事件的2000ms之内,你在多少触发该事件,都不会有任何作用,它只为第一个事件等待2000ms。时间一到,它就会执行了。 - 方案
//时间戳方式
function throttle(fn, delay) {
let pre = Date.now()
return function () {
let context = this;
let args = arguments;
let now = Date.now()
if (now - pre > delay) {
fn.apply(context, args);
pre = Date.now()
}
}
}
//定时器方式
function throttle1(fn, delay) {
let timer = null;
return function () {
let context = this;
let args = arguments;
if (!timer) {
timer = setTimeout(function () {
func.apply(context, args);
timer = null;
}, delay);
}
}
}
事件防抖
-
什么是事件防抖
在某段时间内,不管你触发了多少次事件,我都只认最后一次。
假设设置时间为2000ms,如果触发事件的2000ms之内,你再次触发该事件,就会给新的事件添加新的计时器,之前的事件统统作废。只执行最后一次触发的事件。 -
方案
//只有在最后一次触发事件,才能在delay时间之后执行
function debounce(fn, delay) {
// 维护一个 timer
let timer = null;
return function () {
// 获取函数的作用域和变量
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay)
}
}
测试例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
<script>
function out() {
console.log(111, new Date().getSeconds())
}
//一直在监听窗口变化
//window.addEventListener('resize', out)
//防抖函数
//只有在最后一次触发事件,才能在delay时间之后执行。
function debounce(fn, delay) {
// 维护一个 timer
let timer = null;
return function () {
// 获取函数的作用域和变量
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay)
}
}
//window.addEventListener('resize', debounce(out, 1000))
//节流函数
//时间戳方式
//节流函数会在第一次触发事件时立即执行,之后每隔delay时间再次执行,最后一次不会被触发
function throttle(fn, delay) {
let pre = Date.now()
return function () {
let context = this;
let args = arguments;
let now = Date.now()
if (now - pre > delay) {
fn.apply(context, args);
pre = Date.now()
}
}
}
window.addEventListener('resize', throttle(out, 2000))
</script>
</html>