Skip to content

Instantly share code, notes, and snippets.

@MrFant
Last active October 9, 2019 14:01
Show Gist options
  • Save MrFant/74185a2fc134d5eb6c3529909615d8ba to your computer and use it in GitHub Desktop.
Save MrFant/74185a2fc134d5eb6c3529909615d8ba to your computer and use it in GitHub Desktop.
JS的函数节流和函数防抖

JS的函数节流和函数防抖

debounce 函数防抖

个人理解 函数防抖就是法师发技能的时候要吟唱,技能吟唱没完再按技能就会重新读吟唱。

throttle 函数节流

个人理解 函数节流就是fps游戏的射速,就算一直按着鼠标射击,也只会在规定射速内射出子弹。

结合应用场景

debounce

  • search搜索联想,用户在不断输入值时,用防抖来节约请求资源。

  • window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

throttle

  • 鼠标不断点击触发,mousedown(单位时间内只触发一次)

  • 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

<html>
<title>函数节流和函数防抖</title>
<head>
</head>
<body>
<p>
<label>
没有防抖的input
<input id="unDebounce" type="text">
</label>
</p>
<p>
<label for="">
防抖后的input
<input id="debounce" type="text">
</label>
</p>
<p>
<label for="">
节流后的input
<input id="throttle" type="text">
</label>
</p>
<script src="./test.js"></script>
</body>
</html>
//模拟一段ajax请求
function ajax(content) {
console.log('ajax request ' + content+' '+new Date().getSeconds())
}
let inputa = document.getElementById('unDebounce')
inputa.addEventListener('keyup', function (e) {
ajax(e.target.value)
})
// --------------------------------------
function debounce(fun, delay) {
return function (args) {
// 每次执行都会把上一次的定时器清除,所以一直按的话会不停的清除创建定时器
let that = this
let _args = args
console.log(fun.id)
// fun.id 存储上一个timer的id,不能用块作用域变量所以绑定到fun上
clearTimeout(fun.id)
fun.id = setTimeout(function () {
fun.call(that, _args)
}, delay)
}
}
let inputb = document.getElementById('debounce')
// 延迟时间,单位毫秒
let debounceAjax = debounce(ajax, 1200)
inputb.addEventListener('keyup', function (e) {
debounceAjax(e.target.value)
})
// --------------------------------------
function throttle(fun, delay) {
let last, deferTimer
return function (args) {
let that = this
let _args = arguments
let now = +new Date()
// 当一次keyup事件来的时候判断距离上次调用ajax(而不是上次keyup)是否隔了delay时间
// note:这里的last都是在调用时才修改值,所以为了保证最短间隔时间不低于delay
if (last && now < last + delay) {
clearTimeout(deferTimer)
// 注意这里的定时器延时时间
deferTimer = setTimeout(function () {
last = now
fun.apply(that, _args)
}, last+delay-now)
}else {
last = now
fun.apply(that,_args)
}
}
}
let throttleAjax = throttle(ajax, 1000)
let inputc = document.getElementById('throttle')
inputc.addEventListener('keyup', function(e) {
throttleAjax(e.target.value)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment