一、节流throttle
控制事件的触发频率,针对高频触发的事件,在指定时间内只触发一次。--resize
以下用时间戳和定时器的方法实现一个简单的节流函数;
示例是一个盒子中的鼠标移动所触发的事件
html代码(添加了一点点样式):
<div class="box">0</div>
<style>
body {
display: flex;
justify-content: center;
}
.box {
width: 200px;
height: 200px;
background-color: rgb(179, 172, 172);
text-align: center;
margin: auto;
line-height: 200px;
font-size: 24px;
color: red;
}
</style>
js代码:
const box = document.querySelector('.box')
box.addEventListener('mousemove', throttle(move, 500))
// 1.节流函数
// 方法1:时间戳
function throttle(fn, delay) {
// 节流阀
let temp = false;
let time = Date.now()
if (temp) {
return
} else {
temp = true
return function () {
if (Date.now() - time > delay) {
fn()
time = Date.now()
}
}
}
}
// 方法2:使用定时器
function throttle(fn, delay) {
let timer;
return function () {
if (!timer) {
timer = setTimeout(function () {
timer = null;
fn()
temp = false;
}, delay)
}
}
}
// 2.业务逻辑
function move() {
box.innerHTML = ++box.innerHTML
console.log('移动');
}
应用场景(resize):
function throttle(fn, delay) {
// 节流阀
let temp = false;
return function () {
if (temp) {
return;
} else {
temp = true;
setTimeout(() => {
fn.apply(this, arguments);
temp = false;
}, delay);
}
};
}
function visInterface(e) {
console.log(e.target.innerWidth, e.target.innerHeight);
}
window.addEventListener('resize', throttle(visInterface, 1000));
二、防抖debounce
当事件被触发后,延迟一定时间后触发回调,如果在这期间又被触发,则重新计时;
一般用于高频触发的事件,只触发最后一次--input搜索
应用示例:
// 获取dom元素
const input = document.querySelector('#input')
// 给元素添加事件
input.addEventListener('input', debounce(methodBtn, 500))
// 防抖函数
function debounce(fn, delay) {
let timer
return function () {
clearTimeout(timer)
timer = setTimeout(function () {
fn()
}, delay)
}
}
// 业务逻辑
function methodBtn() {
console.log(input.value);
}
三、lodash
当然,如果我们实在不想自己写防抖和节流函数的话,我们可以使用lodash封装好的方法
我们先下载lodash依赖,同时引入
我们用lodash的内置_.debounce()和_.throttle来做我们的防抖函数和节流函数,这个写法跟以上我们自行封装的防抖节流函数逻辑大概相同,都是接受两个参数,第一个是我们业务逻辑的回调,第二个就是延时时间。
<body>
<input type="text" id="input">
</body>
<script src="./node_modules/lodash/lodash.js"></script>
<script>
// 获取dom元素
const input = document.querySelector('#input')
// 给元素添加事件
input.addEventListener('input', _.debounce(methodBtn, 500))
// 业务逻辑
function methodBtn() {
console.log(input.value);
}
</script>
<style>
body {
display: flex;
justify-content: center;
}
.box {
width: 200px;
height: 200px;
background-color: rgb(179, 172, 172);
text-align: center;
margin: auto;
line-height: 200px;
font-size: 24px;
color: red;
}
</style>
<body>
<div class="box">0</div>
</body>
<script src="./node_modules/lodash/lodash.js"></script>
<script>
const box = document.querySelector('.box')
box.addEventListener('mousemove', _.throttle(move, 500))
// 业务逻辑
function move() {
box.innerHTML = ++box.innerHTML
console.log('移动');
}
</script>