Search code examples
javascriptaddeventlistenerthrottling

Pass scroll event data into throttle function


I am trying to create my own simple full height scrolling script using the wheel event and a throttle function (as I only want 1 scroll to be registered every X milliseconds. I want to pass the event data of the wheel event into the function that is being throttled by my throttle() function.

Here is a simplified version of my code:

function throttle(callback, limit) {
    var wait = false; // Initially, we're not waiting
    return function () { // We return a throttled function
        if (!wait) { // If we're not waiting
            callback.call(); // Execute users function
            wait = true; // Prevent future invocations
            setTimeout(function () { // After a period of time
                wait = false; // And allow future invocations
            }, limit);
        }
    }
}

function onScroll(event) {
  // do stuff here on scroll
}

window.addEventListener('wheel', throttle(onScroll, 700), false);

This would work fine if I didn't need data from the wheel event, but I need to determine the scroll directions inside of my onScroll() function using event.deltaY.

Essentially I want to change the last line to the following (although I know this wouldn't work):

window.addEventListener('wheel', throttle(onScroll(event), 700), false);

So...

How can I pass the wheel event data into the onScroll() function whilst still throttling it?

What I've tried:

I tried the following code so that I could pass the event data into the throttle() function, which worked successfully

window.addEventListener('wheel', function(e) {
  throttle(onScroll, 700, e)
}, false);

But I am then not sure what to do with e inside of my throttle() function to be able to pass it to the onScroll() function. I tried changing the line with:

callback.call(); // Execute users function

to:

callback.call(e); // Execute users function (using the e passed into the throttle function)

But that stopped the onScroll function from even being called... (I assume because throttle() is returning a function but this returned function isn't being called because it's wrapped inside another function in the eventListener?)


Solution

  • Just pass through the arguments:

    function throttle(callback, limit) {
      var wait = false;
      return function (...args) { 
        if (!wait) {
            callback(...args);
            wait = true; 
            setTimeout(function () { 
                wait = false; 
            }, limit);
        }
      }
    }