一.防抖之前端人话
防抖, 简而言之就是window 中的 resize、scroll, mousedown、mousemove, keyup、keydown等事件频繁的发生, 如果这些事件处理函数有异步方法,容易造成页面的卡顿, 解决的方法之一就是防抖(debounce), 其二是节流(throtter).
防抖和节流到底啥区别: 防抖是事件持续触发,等待事件停止触发后n才执行函数. 节流是事件持续触发的时候,每n秒执行一次函数
function debounce(func, wait) {let timeout;return function() {clearTimeout(timeout);timeout = setTimeout(func, wait);}}
一.func方法中的this和event对象
上面方法中的this是指向window, 如何将this指向当前的作用的对象, 如何获取event对象
function debounce(func, wait) {let timeout;return function() {const context = this;const args = arguments;clearTimeout(timeout);timeout = setTimeout(function() {func.apply(context, args)}, wait);}}
二.不希望等到n秒后才执行,希望立即执行, 等到停止触发n秒后才可以重新执行, 如何做 ?
function debounce(func, wait, immediate) {let timeout;return function() {const context = this;const args = arguments;if(timeout) {clearTimeout(timeout);}if(immediate) {// 如果执行过,不再执行const callNow = !timeout;timeout = setTimeout(function(){timeout = null;}, wait);if(callNow) {func.apply(context, args);}} else {timeout = setTimeout(function() {func.apply(context, args);}, wait);}}}
三.如何返回func函数的返回值?
只有当immediate为true的时候才将func的结果返回, 因为immediate为false的时候, 我们将执行函数放在定时器中,返回结果永远是undefined
function debounce(func, wait, immediate) {let timeout;let result;return function() {const context = this;const args = arguments;if(timeout) {clearTimeout(timeout);}if(immediate) {// 如果执行过,不再执行const callNow = !timeout;timeout = setTimeout(function(){timeout = null;}, wait);if(callNow) {result = func.apply(context, args);}} else {timeout = setTimeout(function() {func.apply(context, args);}, wait);}return result;}}
四.如何取消debounce函数, eg:debounce间隔是10秒,立即执行, 我只能等到10秒后才能触发执行, 这时候希望有一个按钮, 点击可以取消防抖, 这样再去触发,就可以立即执行, 如何做 ?
function debounce(func, wait, immediate) {let timeout;let result;const debouned = function() {const context = this;const args = arguments;if(timeout) {clearTimeout(timeout);}if(immediate) {// 如果执行过,不再执行const callNow = !timeout;timeout = setTimeout(function(){timeout = null;}, wait);if(callNow) {result = func.apply(context, args);}} else {timeout = setTimeout(function() {func.apply(context, args);}, wait);}return result;}debouned.cancel = function() {clearTimeout(timeout);timeout = null;}return debouned;}
二.节流
一. 时间戳实现
- 鼠标第一次移入的时候会立刻执行
- 事件停止触发后没有办法再执行 ```javascript
function throttle(func, wait) { let previous = 0 let context let args
return function() { let now = +new Date() context = this args = arguments
if (now - previous > wait) {func.apply(context, args)previous = now}
} }
<a name="0LmuN"></a>### 二. 定时器实现1. 不会立即执行, n秒后第一次执行1. 停止触发后依然会再执行一次```javascriptfunction throttle2(func, wait) {let timeoutreturn function() {let context = thislet args = argumentsif(!timeout) {timeout = setTimeout(function(){timeout = nullfunc.apply(context, args)}, wait)}}}
