demo效果:
![](https://i-blog.csdnimg.cn/blog_migrate/6ea3107e13d710e255136bf6c3cdbce0.gif)
demo调用:
<!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>
body { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; }
.box { width: 260px; height: 260px; float: left; margin: 40px; }
.content { width: 260px; height: 100px; background: rgba(0,0,0,.05); padding: 10px; }
.sp { font-weight: 900; color: blue; }
</style>
</head>
<body>
<div class="box">
<button id="btn1"><span class="sp">防抖</span>-时间间隔1秒</button>
<span>执行次数: </span>
<span id="count1">0</span>
<br><br>
<button id="btn1_2">立即执行防抖函数</button>
<br><br>
<button id="btn1_3">立即停止防抖函数</button>
<br><br>
<div class="content">在每执行完一次后的单位时间内连续执行, 只执行最后一次。</div>
</div>
<div class="box">
<button id="btn2"><span class="sp">节流</span>-时间间隔1秒</button>
<span>执行次数: </span>
<span id="count2">0</span>
<br><br>
<div class="content">在单位时间内最多只执行一次。</div>
</div>
</body>
<script>
/**
* 防抖
*
* @param {Function} fn 需要进行防抖的函数
* @param {Number} [ms = 500] 防抖时间间隔(毫秒)
*
* @returns {Function} handler 柯里化处理后的防抖函数
* @returns {Function} handler.finish 马上执行当前进行中的防抖函数且关闭当前进行中的定时器
* @returns {Function} handler.stop 马上关闭当前进行中的定时器
*/
const _antiShake = (fn, ms = 500) => {
let timer = null
let argNow = null
let padding = false
const handler = (...arg) => {
argNow = arg
if (padding) clearTimeout(timer)
padding = true
timer = setTimeout(() => {
padding = false
fn(...arg)
}, ms)
}
handler.finish = () => {
if (padding) {
clearTimeout(timer)
padding = false
fn(...argNow)
}
}
handler.stop = () => {
if (padding) {
padding = false
clearTimeout(timer)
}
}
return handler
}
/**
* 节流
*
* @param {Function} fn 需要进行节流的函数
* @param {Number} [ms = 500] 节流时间间隔(毫秒)
*
* @returns {Function} 柯里化处理后的节流函数
*/
const _throttle = (fn, ms = 500) => {
let status = true
return (...arg) => {
if (status) {
status = false
fn(...arg)
setTimeout(() => {
status = true
}, ms)
}
}
}
const _handleClick1 = (...arg) => {
console.log(arg)
count1.textContent = parseInt(count1.textContent) + 1
}
const handleClick1 = _antiShake(_handleClick1, 1000)
btn1.onclick = handleClick1.bind(null, '自定义参数1-1', '自定义参数1-2', '自定义参数1-3')
btn1_2.onclick = () => {
handleClick1.finish();
}
btn1_3.onclick = () => {
handleClick1.stop();
}
const _handleClick2 = (...arg) => {
console.log(arg)
count2.textContent = parseInt(count2.textContent) + 1
}
const handleClick2 = _throttle(_handleClick2, 1000)
btn2.onclick = handleClick2.bind(null, '自定义参数2-1', '自定义参数2-2', '自定义参数2-3')
</script>
</html>
功能代码实现:
/**
* 防抖
*
* @param {Function} fn 需要进行防抖的函数
* @param {Number} [ms = 500] 防抖时间间隔(毫秒)
*
* @returns {Function} handler 柯里化处理后的防抖函数
* @returns {Function} handler.finish 马上执行当前进行中的防抖函数且关闭当前进行中的定时器
* @returns {Function} handler.stop 马上关闭当前进行中的定时器
*
* @example 例子在下方 ↓↓↓
*
*/
export const _antiShake = (fn, ms = 500) => {
let timer = null
let argNow = null
let padding = false
const handler = (...arg) => {
argNow = arg
if (padding) clearTimeout(timer)
padding = true
timer = setTimeout(() => {
padding = false
fn(...arg)
}, ms)
}
handler.finish = () => {
if (padding) {
clearTimeout(timer)
padding = false
fn(...argNow)
}
}
handler.stop = () => {
if (padding) {
padding = false
clearTimeout(timer)
}
}
return handler
}
/**
* @example
* 需要防抖处理的函数:
const needFn = (a, b) => {
console.log(a, b)
}
* 用法:
const antiShake_needFn = _antiShake(needFn, 1000)
* 调用:
antiShake_needFn('aaa', 'bbb') // 打印出: 'aaa', 'bbb'
* 调用finish()方法:
antiShake_needFn.finish()
* 调用stop()方法:
antiShake_needFn.stop()
*
*/
// -----------------------------------------------------------------------------------
/**
* 节流
*
* @param {Function} fn 需要进行节流的函数
* @param {Number} [ms = 500] 节流时间间隔(毫秒)
*
* @returns {Function} 柯里化处理后的节流函数
*
* @example 例子在下方 ↓↓↓
*
*/
export const _throttle = (fn, ms = 500) => {
let status = true
return (...arg) => {
if (status) {
status = false
fn(...arg)
setTimeout(() => {
status = true
}, ms)
}
}
}
/**
* @example
* 需要节流处理的函数:
const needFn = (a, b) => {
console.log(a, b)
}
* 用法:
const antiShake_needFn = _antiShake(needFn, 1000)
* 调用:
antiShake_needFn('aaa', 'bbb') // 打印出: 'aaa', 'bbb'
*
*/