我记得早期的 JavaScript ,要完成任何事情几乎都绕不开一些简单的函数,因为浏览器提供商实现功能有所差异,而且不只是边缘功能,基础功能也一样,如 addEventListener
和 attachEvent
。虽然时代变了,但仍有一些函数是每个开发者都应该掌握的,以便于完成某些功能和提高性能。
debounce
对于高耗能事件,debounce 函数是一种不错解决方案。如果你不对 scroll
、resize
、和 key*
事件使用 debounce 函数,那么你几乎等同于犯了错误。下面的 debounce
函数能让你的代码保持高效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// 返回一个函数,如果它被不间断地调用,它将不会得到执行。该函数在停止调用 N 毫秒后,再次调用它才会得到执行。如果有传递 ‘immediate’ 参数,会马上将函数安排到执行队列中,而不会延迟。 function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; // 用法 var myEfficientFn = debounce(function() { // 所有繁重的操作 }, 250); window.addEventListener('resize', myEfficientFn); |
debounce
函数不允许回调函数在指定时间内执行多于一次。当为一个会频繁触发的事件分配一个回调函数时,该函数显得尤为重要。
poll
尽管上面我提及了 debounce
函数,但如果事件不存在时,你就不能插入一个事件以判断所需的状态,那么就需要每隔一段时间去检查状态是否达到你的要求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
function poll(fn, callback, errback, timeout, interval) { var endTime = Number(new Date()) + (timeout || 2000); interval = interval || 100; (function p() { // 如果条件满足,则执行! if(fn()) { callback(); } // 如果条件不满足,但并未超时,再来一次 else if (Number(new Date()) < endTime) { setTimeout(p, interval); } // 不匹配且时间消耗过长,则拒绝! else { errback(new Error('timed out for ' + fn + ': ' + arguments)); } })(); } // 用法:确保元素可见 poll( function() { return document.getElementById('lightbox').offsetWidth > 0; }, function() { // 执行,成功的回调函数 }, function() { // 错误,失败的回调函数 } ); |
Polling 在 web 中已被应用很长时间了,并在将来仍会被使用。
once
有时候,你想让一个给定的功能只发生一次,类似于 onload 事件。下面的代码提供了你所说的功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 8bbe965822745130-15">15 16 17 18 19 ڄ JavaScript ,要完成任何事情几乎都绕不开一些简单的函数,因为浏览器提供商实现功能有所差异,而且不只是边缘功能,基础功能也一样,如 addEventListener 和 attachEvent 。虽然时代变了,但仍有一些函数是每个开发者都应该掌握的,以便于完成某些功能和提高性能。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// 返回一个函数,如果它被不间断地调用,它将不会得到执行。该函数在停止调用 N 毫秒后,再次调用它才会得到执行。如果有传递 ‘immediate’ 参数,会马上将函数安排到执行队列中,而不会延迟。 function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; // 用法 var myEfficientFn = debounce(function() { // 所有繁重的操作 }, 250); window.addEventListener('resize', myEfficientFn); |
debounce
函数不允许回调函数在指定时间内执行多于一次。当为一个会频繁触发的事件分配一个回调函数时,该函数显得尤为重要。
poll
尽管上面我提及了 debounce
函数,但如果事件不存在时,你就不能插入一个事件以判断所需的状态,那么就需要每隔一段时间去检查状态是否达到你的要求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
function poll(fn, callback, errback, timeout, interval) { var endTime = Number(new Date()) + (timeout || 2000); interval = interval || 100; (function p() { // 如果条件满足,则执行! if(fn()) { callback(); } // 如果条件不满足,但并未超时,再来一次 else if (Number(new Date()) < endTime) { setTimeout(p, interval); } // 不匹配且时间消耗过长,则拒绝! else { errback(new Error('timed out for ' + fn + ': ' + arguments)); } })(); } // 用法:确保元素可见 poll( function() { return document.getElementById('lightbox').offsetWidth > 0; }, function() { // 执行,成功的回调函数 }, function() { // 错误,失败的回调函数 } ); |
Polling 在 web 中已被应用很长时间了,并在将来仍会被使用。
once
有时候,你想让一个给定的功能只发生一次,类似于 onload 事件。下面的代码提供了你所说的功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 line="crayon-5812a28bbe965822745130-20">20 |