@@ -107,7 +107,9 @@ export function encodeURIComponentPlus(value) {
107107 *
108108 * @param {T } func
109109 * @param {number } wait
110- * @param {boolean } immediate
110+ * @param {boolean | function } immediate If true, calls func on the leading edge. If a
111+ * function is provided, that function is called on the leading edge instead of `func`.
112+ * `func` is still called on the trailing edge.
111113 * @return {T }
112114 */
113115export function debounce ( func , wait , immediate ) {
@@ -117,12 +119,18 @@ export function debounce(func, wait, immediate) {
117119 const args = arguments ;
118120 const later = ( ) => {
119121 timeout = null ;
120- if ( ! immediate ) func . apply ( context , args ) ;
122+ if ( ! immediate || typeof immediate === 'function' ) func . apply ( context , args ) ;
121123 } ;
122124 const callNow = immediate && ! timeout ;
123125 clearTimeout ( timeout ) ;
124126 timeout = setTimeout ( later , wait ) ;
125- if ( callNow ) func . apply ( context , args ) ;
127+ if ( callNow ) {
128+ if ( typeof immediate === 'function' ) {
129+ immediate . apply ( context , args ) ;
130+ } else {
131+ func . apply ( context , args ) ;
132+ }
133+ }
126134 } ;
127135}
128136
@@ -311,3 +319,25 @@ export function sortBy(array, valueFn) {
311319 return aValue < bValue ? - 1 : aValue > bValue ? 1 : 0 ;
312320 } ) ;
313321}
322+
323+ /**
324+ * @param {Function } callback
325+ * @param {Object } options
326+ * @param {number } [options.scrollDelay=20] How many pixels to scroll before triggering
327+ * @returns {function(): void }
328+ */
329+ export function onScrollUp ( callback , { scrollDelay = 20 } = { } ) {
330+ let lastScrollTop = 0 ;
331+ let accumulatedScroll = 0 ;
332+ return function ( ) {
333+ const st = this . scrollTop ;
334+ if ( st < lastScrollTop ) {
335+ accumulatedScroll += lastScrollTop - st ;
336+ if ( accumulatedScroll >= scrollDelay ) {
337+ callback ( ) ;
338+ accumulatedScroll = 0 ;
339+ }
340+ }
341+ lastScrollTop = st ;
342+ } ;
343+ }
0 commit comments