节流,就是在一个时间段内只触发一次事件,比如:1秒内只发送一次请求
节流:非立即执行版(定时器版本)
- 效果图
代码
<div id="adder">0</div>
<script>
const div = document.getElementById('adder')
// 封装函数,这里可以把num作为参数传入
let divAdd = function (num) {
div.innerHTML = parseInt(div.innerHTML) + num
}
// 非立即执行版本,定时器版本
const throttle = function (fn, wait, ...arg) {
let timer = null
return function () {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, arg) // 此处使用箭头函数,this指向调用该节流函数的对象
timer = null
}, wait)
}
}
}
// 鼠标移动每次加10,每隔2秒加一次
div.onmousemove = throttle(divAdd, 2000, 10)
</script>
节流:立即执行版本(时间戳版本)
效果图
- 代码
<div id="adder">0</div>
<script>
const div = document.getElementById('adder')
// 封装函数,这里可以把num作为参数传入
let divAdd = function (num) {
div.innerHTML = parseInt(div.innerHTML) + num
}
// 立即执行版本,时间戳版本
const throttle = function (fn, wait, ...arg) {
let pre = 0 // 初始值
return function () {
let now = Date.now() // 获取当前事件戳
if (now - pre > wait) {
fn.apply(this, arg) // 这里的this也指向,调用节流函数的对象
pre = now;
}
}
}
// 鼠标移动每次加10,每隔2秒加一次
div.onmousemove = throttle(divAdd,2000,10)
</script>
节流:合并版本
使用参数来控制是否立即执行
<div id="adder">80</div>
<script>
const div = document.getElementById('adder')
const add = function(num){
div.innerHTML=parseInt(div.innerHTML)+num;
}
// 合并版本,使用immediate控制是否立即执行
const throttle = function (fn, wait, immediate, ...arg) {
let time = 0
return function () {
if (immediate) { // 立即执行
let now = Date.now()
if (now - time > wait) {
fn.apply(this, arg)
time = now;
}
} else {
if (!time) { // 非立即执行
time = setTimeout(() => {
fn.apply(this, arg)
time = 0
}, wait)
}
}
}
}
// 鼠标移动每次加10,每隔2秒加一次,不立即执行
div.onmousemove = throttle(divAdd, 2000,false, 10)
</script>