-
Notifications
You must be signed in to change notification settings - Fork 0
/
throttled.html
88 lines (76 loc) · 2.24 KB
/
throttled.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
<title>throttled</title>
<style>
#container {
width: 100%;
height: 200px;
line-height: 200px;
text-align: center;
color: #fff;
background-color: #444;
font-size: 30px;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
var count = 1;
var container = document.getElementById('container');
function getUserAction(e) {
container.innerHTML = count++;
};
container.onmousemove = throttle(getUserAction, 1000);
// 防抖
/**
* @param {function} 需要执行的函数
* @param {number} 延迟执行的时间间隔
* @return {number[]}
*/
function throttle(fn, wait) {
let timeout, context, args;
let previous = 0;
let throttled = function () {
context = this;
args = arguments;
let now = new Date();
// 下次触发 fn 的剩余时间,间隔时间 - 当前时间与上一次 fn 执行时间的时间差
let remaining = wait - (now - previous);
// remaining <=0,说明当前距离上次执行的间隔时间大于等待时间,可以立即执行
// remaining > wait,说明改了系统时间
// 比如 previous = 9:01,now = 9:00,间隔时间 60s,那么 remaining = 120s,实际间隔时间到了也不会执行
if (remaining <= 0 || remaining > wait) {
if (timeout) {
// 清除 timeout
clearTimeout(timeout);
timeout = null;
}
// 立即执行 fn
previous = now;
fn.apply(context, args);
} else if (!timeout) {
// !timeout = true, 说明没有正在等待执行的延时函数,可以立即执行
timeout = setTimeout(() => {
previous = new Date();
timeout = null;
fn.apply(context, args);
}, remaining);
}
}
// 取消
throttled.cancel = function () {
if (timeout) {
clearTimeout(timeout);
previous = 0;
timeout = null;
}
}
return throttled;
}
</script>
</body>
</html>