浏览器的一些事件,如:resize,scroll,keydown,keyup,keypress,mousemove等。这些事件触发频率太过频繁,绑定在这些事件上的回调函数会不停的被调用。会加重浏览器的负担,导致用户体验非常糟糕,不知哪个大神发明了防抖和节流,用来控制回调函数的次数。
//函数防抖(debounce)
function debounce(fn, wait) {
var timeout;
return function() {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(fn, wait);
}
}
function handle() {
console.log(12)
}
//滚动事件
window.addEventListener("scroll", debounce(handle, 1000))
代码解释:先执行debounce(handle, 1000)返回一个匿名函数,然后监听scroll事件,执行匿名函数,设置一个1秒后执行handle函数的定时器,由于scroll是不断触发的,如果第一次触发与第二次触发间隔1秒或者1秒多,第一次触发scroll会执行handle函数,在控制台上会打印12,如果间隔小于1秒,因为setTimeout(fn, wait)是要在1秒后执行handle 函数,小于1秒就不执行handle函数,但是timeout定时器已经不为空,第二次scroll滚动触发debounce时就执行clearTimeout(timeout),并且执行下面的代码,因为下面的代码不是放在else里面,依次类推。 总结:如果不停的触发事件,事件间隔大于设定的时间,才执行某个函数。
如果是input的情况,这时需要传递数据
//函数节流(throttle)
var throttle = function(func, delay) {
console.log("hi")
var prev = Date.now(); //返回1970 年 1 月 1日午夜与当前日期和时间之间的毫秒数。
return function() {
var now = Date.now();
if (now - prev >= delay) {
func()
prev = Date.now()
}
}
}
function handle() {
console.log(Math.random())
}
window.addEventListener("scroll", throttle(handle, 1000))
解释:当持续触发事件时,每隔一定时间(如200ms)执行一次事件处理函数 先执行throttle(handle, 1000)返回一个匿名函数,然后触发scroll事件时执行返回的匿名函数,即未滚动的时候已经执行了throttle(handle, 1000)函数
如果是input的情况(防抖)
<body>
<div style="" class="">
<input type="" id="unDebounce" />
</div>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
function ajax(content) {
console.log("ajax request" + content)
}
function debounce(fun, delay) {
var timeout;
return function(args) {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(function() {
fun(args)
}, delay)
}
}
let inputElement = document.getElementById("unDebounce")
let debounceAjax = debounce(ajax, 500)
inputElement.addEventListener("keyup", function() {
//debounceAjax(this.value)放在匿名函数里面的原因是当keyup的时候才执行,如果不放在里面会先执行此函数,导致没有值
debounceAjax(this.value)
})
</script>
</body>
如果是input的情况(节流)
<body>
<div style="" class="">
<input type="" id="throttle" />
</div>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
function ajax(content) {
console.log("ajax request" + content)
}
function throttle(func, delay) {
var pre = Date.now();
var deferTimer;
console.log("pre " + pre)
return function(args) {
var now = Date.now()
console.log("now " + now)
console.log(now - pre)
if (now - pre >= delay) {
func(args)
pre = Date.now()
} else {
clearTimeout(deferTimer);
deferTimer = setTimeout(function() {
func(args)
pre = Date.now()
}, delay)
}
}
}
var throttleAjax = throttle(ajax, 2000)
var inputc = document.getElementById('throttle')
inputc.addEventListener('keyup', function() {
throttleAjax(this.value)
})
</script>
</body>
防抖和节流的区别: 防抖是根据事件间隔是否大于设定的值来决定回调函数是否执行(取决于事件间隔,或者最后一次滚动); 节流是根据事件不停触发时时间间隔大于设定的值才执行回调函数(每隔多少秒执行一次);
公众号:前端之攻略
(adsbygoogle = window.adsbygoogle || []).push({});