节流:在频繁操作的时候,我们能降低触发的频率
节流函数原理:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
<html>
<input id="search" type="text" />
</html>
<script>
const throttle = (fn, delay = 500) => {
let flag = true
return (...args) => {
if (!flag) return
flag = false
setTimeout(() => {
fn.apply(this, args)
flag = true
}, delay)
}
}
/* 主要实现思路就是通过 setTimeout 定时器,通过设置延时时间。
在第一次调用时,创建定时器,先设定一个变量true,写入需要执行的函数。
第二次执行这个函数时,会判断变量是否true,是则返回。
当第一次的定时器执行完函数最后会设定变量为false。
那么下次判断变量时则为false,函数会依次运行。
目的在于在一定的时间内,保证多次函数的请求只执行最后一次调用。 */
const suggest = () => {
console.log('fetch')
}
const debounceSuggest = throttle(suggest, 1000)
let inputSearch = document.getElementById('search')
inputSearch.addEventListener('input', () => {
console.log('input')
debounceSuggest()
})
</script>
时间戳实现的方式
<script>
// fn 是需要执行的函数
// wait 是时间间隔
const Throttle = (fn, wait = 50) => {
// 上一次执行 fn 的时间
let previous = 0
// 将 Throttle 处理结果当作函数返回
return function (...args) {
// 获取当前时间,转换成时间戳,单位毫秒
let now = +new Date()
// 将当前时间和上一次执行函数的时间进行对比
// 大于等待时间就把 previous 设置为当前时间并执行函数 fn
if (now - previous > wait) {
previous = now
fn.apply(this, args)
}
}
}
// DEMO
// 执行 Throttle 函数返回新函数
const betterFn = Throttle(() => console.log('fn 函数执行了'), 1000)
// 每 10 毫秒执行一次 betterFn 函数,但是只有时间差大于 1000 时才会执行 fn
setInterval(betterFn, 10)
</script>
<script>
const handle = function handle(ev) {
console.log('ok')
}
/**
* 函数节流处理
* @params
* func:最终要执行的函数[必传]
* wait:设定的触发频率[默认300MS]
*
* 默认:每间隔3MS左右,只要滚动条在滚动,我们就会把handle执行一次[触发频率是3MS]
*/
const throttle = function throttle(func, wait) {
if (typeof func !== 'function') throw new TypeError('func must be function')
if (typeof wait !== 'number') wait = 300
let timer,
previous = 0
return function proxy(...params) {
let now = +new Date(),
remaining = wait - (now - previous),
self = this
if (remaining <= 0) {
// 间隔时间已经超过wait[包含第一次触发],无需等待,立即执行
if (timer) {
clearTimeout(timer)
timer = null
}
func.call(self, ...params)
previous = now
} else if (!timer) {
timer = setTimeout(() => {
if (timer) {
clearTimeout(timer)
timer = null
}
func.call(self, ...params)
previous = +new Date()
}, remaining)
}
}
}
window.onscroll = throttle(handle, 300)
</script>