We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
概念:防抖(在事件被触发n秒之后再执行回调函数,如果在这n秒内又被触发,则重新计时)
我们以一个输入框的keyup事件为例,先看一个没有防抖的例子:
keyup
<div> <span>没有防抖的input:</span> <input type="text" id="inputA"> </div> <script> //模拟一段ajax请求 function ajax(content){ console.log('ajax request' + content); } let inputA = document.querySelector('#inputA'); inputA.addEventListener('keyup', function(e){ ajax(e.target.value); }); </script>
当我们不停输入时,运行结果如下:
按照上面的的概念,我们先试着实现一个简单版本的防抖:
<div> <span>防抖后的input:</span> <input type="text" id="inputB"> </div> <script> // 防抖初始版本 function debounceFn1(func, wait) { let timer = null; return (...args) => { timer && clearTimeout(timer); timer = setTimeout( () => { func.apply(this, args); }, wait); } } let inputB = document.querySelector('#inputB'); let debounceAjax = debounceFn1(ajax, 500); inputB.addEventListener('keyup', function(e){ debounceAjax(e.target.value); }) </script>
观察打印的结果发现,当我们快速输入时并不会不停发出请求了,嗯,不错不错,基本功能是实现了,可是这种方式并不会马上运行我们的请求代码,如果我们需要马上运行一次再防抖呢,那就加个参数吧,哈哈,上代码:
// 增加立即执行的防抖版本 function debounceFn2(func, wait, immediate) { let timer = null; return (...args) => { timer && clearTimeout(timer); //要实现只有首次立即执行的关键是变量timer,它是闭包中引用的一个变量,是不会被马上销毁的 //所以timer只有在初始化时是null,之后是一直有值的,存的是定时器的ID if(immediate && !timer) { func.apply(this, args); } timer = setTimeout( () => { func.apply(self, args); }, wait); } } let debounceAjax = debounceFn2(ajax, 500, true); inputB.addEventListener('keyup', function(e){ debounceAjax(e.target.value); })
当快速输入值时,运行结果如下:
好了,一个能应付日常有防抖需求的函数基本上写好了,如果还需要更多功能可以参考underscore是如何实现debounce的,由于我还没用过,有使用心得了下次再总结。
underscore
debounce
概念:在一个单位时间内,只能触发一次函数,如果在这个时间段内触发了多次,只有一次能生效。
节流又分为两种实现方式,分别为有时间戳和计时器,下面先看一个用时间戳实现的栗子:
<div> <span>节流后的input:</span> <input type="text" id="inputC"> </div> <script> // 函数节流(时间戳版本) function throttleFn1(func, wait) { // 上一次执行的时间 let previous = 0; return (...args) => { // 当次执行的时间 let now = +new Date(); if(now - previous > wait) { previous = now; func.apply(this, args); } } } let throttleAjax = throttleFn1(ajax, 1000); inputC.addEventListener('keyup', function(e){ throttleAjax(e.target.value); }) </script>
这种方法实现节流的核心是两次函数执行的时间差大于等待时间时才执行回调函数,同时将这个执行的时间设为对比时间,这样就保证了再等待时间间隔内永远只会执行一次回调函数。当快速输入数字时,上面代码执行结果如下:
另一种实现节流的方法就是类似于防抖那样利用定时器实现,这个定时器的所定时长就是这个等待值。实现代码如下:
// 节流版本(定时器版本) function throttleFn2(func, wait) { let timer = null; return (...args) => { if(!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, wait); } } } let throttleAjax = throttleFn2(ajax, 1000); inputC.addEventListener('keyup', function(e){ throttleAjax(e.target.value); })
当快速输入时,运行结果如下:
resize
函数的防抖和节流,出现的目的是为了提高代码性能,因为减少了不必要的请求和浏览器资源消耗(比如重绘和回流),算是性能优化的一种方式。
归根到底,防抖和节流是利用了函数的闭包缓存了状态值变量,从而可以对频繁的调用函数根据一定的规则做过滤。以上就是我个人看了一些大佬的文章之后做的总结,代码都是一点一点手打了之后验证过的,感兴趣的童鞋可以复制之后验证一下,当然有理解不足之处欢迎留言指出!
The text was updated successfully, but these errors were encountered:
No branches or pull requests
防抖(debounce)
我们以一个输入框的
keyup
事件为例,先看一个没有防抖的例子:当我们不停输入时,运行结果如下:
按照上面的的概念,我们先试着实现一个简单版本的防抖:
当我们不停输入时,运行结果如下:
观察打印的结果发现,当我们快速输入时并不会不停发出请求了,嗯,不错不错,基本功能是实现了,可是这种方式并不会马上运行我们的请求代码,如果我们需要马上运行一次再防抖呢,那就加个参数吧,哈哈,上代码:
当快速输入值时,运行结果如下:
好了,一个能应付日常有防抖需求的函数基本上写好了,如果还需要更多功能可以参考
underscore
是如何实现debounce
的,由于我还没用过,有使用心得了下次再总结。节流(throttle)
节流又分为两种实现方式,分别为有时间戳和计时器,下面先看一个用时间戳实现的栗子:
这种方法实现节流的核心是两次函数执行的时间差大于等待时间时才执行回调函数,同时将这个执行的时间设为对比时间,这样就保证了再等待时间间隔内永远只会执行一次回调函数。当快速输入数字时,上面代码执行结果如下:
另一种实现节流的方法就是类似于防抖那样利用定时器实现,这个定时器的所定时长就是这个等待值。实现代码如下:
当快速输入时,运行结果如下:
应用场景
resize
事件,如果等待时间设置合理并且 调整的快的话可以做到只触发一次回调事件。小节
函数的防抖和节流,出现的目的是为了提高代码性能,因为减少了不必要的请求和浏览器资源消耗(比如重绘和回流),算是性能优化的一种方式。
归根到底,防抖和节流是利用了函数的闭包缓存了状态值变量,从而可以对频繁的调用函数根据一定的规则做过滤。以上就是我个人看了一些大佬的文章之后做的总结,代码都是一点一点手打了之后验证过的,感兴趣的童鞋可以复制之后验证一下,当然有理解不足之处欢迎留言指出!
参考
The text was updated successfully, but these errors were encountered: