问题引出:频繁调用函数造成性能浪费
当一个函数无意义的高频率调用时,需要设置函数函数防抖和函数节流,限制这种无意义的调用,通过调用次数的减少来提高代码性能
问题场景:搜索框实时发请求,onmousemove, resize, onscroll等等
1.input搜索框内容的输入:用户敲击键盘的时候去触发一个函数
2 resize,变化浏览器的大小,控制台会一直打印
3.拖动滚动条,会持续触发onscroll监听事件
4.鼠标移动事件中不断返回鼠标经过的位置
解决方法:函数防抖和函数节流
思路:不影响使用的情况下,适度降低函数的触发频率
函数防抖(debounce):触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。
函数节流(throttle):限制一个函数在一定时间内只能执行一次
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>函数防抖和函数节流</title>
<style>
#box {
width: 600px;
height: 200px;
background: pink;
margin: 0 auto;
text-align: center;
line-height: 200px;
font-size: 50px;
color: red;
}
</style>
</head>
<body>
<div id="box"></div>
</body>
<script>
var box = document.getElementById("box");
var n = 1;
function count() {box.innerHTML = n++;}
//1.调用防抖函数
// box.addEventListener("mousemove", debounce(count, 1000));
//2.调用节流函数
box.addEventListener("mousemove", throttle(count, 1000));
</script>
</html>
2.函数防抖
function debounce(fn, delay) {
var timer = null;
function innerFunc() {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.bind(this, arguments)();
console.log(this);
}, delay);
}
return innerFunc;
}
3.函数节流
function throttle(fn, delay) {
var timer = null;
return function() {
if (Date.now() - timer > delay) {
fn.bind(this, arguments)();
timer = Date.now();
}
};
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 100%;
height: 300px;
font-size: 100px;
font-weight: 900;
text-align: center;
line-height: 300px;
background: pink;
color: red;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
var div = document.querySelector("div");
var i = 0;
div.innerHTML = i;
// 鼠标移动就触发
function count() {
div.innerHTML = i++;
}
/******函数防抖:一定时间内只触发一次,若在此期间内再次触发则重新计时******/
// function debounce(fn, delay) {
// var timer = null;
// return function() {
// if (timer) clearInterval(timer);
// timer = setTimeout(() => {
// fn.bind(this, arguments)()
// }, delay);
// }
// }
// div.addEventListener("mousemove", debounce(count, 1000));
/******函数节流:一定时间内只触发一次******/
function throttle(fn, delay) {
var timer = null;
return function() {
if (Date.now() - timer > delay) {
fn.bind(this, arguments)();
timer = Date.now();
}
}
}
addEventListener("mousemove", throttle(count, 1000));
</script>
</html>