概念
-
防抖:
在一定时间内持续触发事件,只执行一次
-
节流:
持续触发事件,每间隔一定时间执行一次
-
作用
一些高频事件(如:滚动页面、缩放窗口、鼠标移动等)的触发会带来性能问题,防抖或节流就是为了解决这种问题
代码实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>防抖与节流</title>
<style>
#container {
width: 100%;
height: 300px;
background: pink;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
<script>
let div = document.querySelector("#container")
div.onmousemove = debounce(move, 1000)
div.onclick = throttle(printPosition, 2000)
function move(e) {
this.innerHTML = e.clientX
}
function printPosition(e) {
console.log(e.clientX,e.clientY)
}
function debounce(fn, wait) {
let timer = null
return function() {
let args = arguments
timer && clearTimeout(timer) // 定时器存在则清除,不存在则执行下一步
timer = setTimeout(() => {
fn.apply(this, args)
}, wait);
}
}
// 时间戳实现
function throttle(fn, wait) {
let pre = 0 // 初始时间设为 0
return function() {
let args = arguments,
now = Date.now() // 记录当前时间
if (now - pre > wait) { // 时间差 > wait
setTimeout(() => {
fn.apply(this, args)
}, wait) // 定时执行 fn 函数
pre = Date.now() // 记录上次执行时间
}
}
}
// 定时器实现
function throttle2(fn, wait) {
let timer= null
return function() {
let args = arguments
/* 定时器不为 null 则执行
1.设置定时器
2.定时器中设置 timer 为 null
(注意:不能使用clearTimeout(timer),取消定时器后 timer 值仍为一个 id)
3.执行 fn 函数
*/
if (!timer) {
timer = setTimeout(() => {
timer = null
fn.apply(this, args)
}, wait)
}
}
}
</script>
</html>