How to limit handling of event to once per X seconds with jQuery / javascript?

筅森魡賤 提交于 2019-12-29 04:26:06

问题


For a rapidly-firing keypress event, I want to limit the handling of the event to a maximum of once per X seconds.

I'm already using jQuery for the event handling, so a jQuery-based solution would be preferred, though vanilla javascript is fine too.

  • This jsfiddle shows keypress firing rapidly without any limiting on the handling

  • This jsfiddle implements limiting the handling to once per 0.5 seconds in vanilla JS using setTimeout()

My question is

  1. Does jQuery have an inbuilt way of doing this? I don't see anything in the .on() docs

  2. If not, is there a better pattern for doing this in vanilla JS than I've used in my second jsfiddle example?


回答1:


Does jQuery have an inbuilt way of doing this?

No.

If not, is there a better pattern for doing this in vanilla JS than I've used in my second jsfiddle example?

Instead of using setTimeout and flags, you can keep track of when the handler was called the last time and only call it after a defined interval has passed. This is referred to as throttling and there are various ways to implement this.

In its simplest form you just have to ignore every call that is made within the time of lastCall + interval, so that only one call in every interval occurs.

E.g. here is a function that returns a new function which can only be called once every X milliseconds:

function throttle(func, interval) {
    var lastCall = 0;
    return function() {
        var now = Date.now();
        if (lastCall + interval < now) {
            lastCall = now;
            return func.apply(this, arguments);
        }
    };
}

which you can use as

$("#inputField").on("keypress", throttle(function(event) {
   $("div#output").append("key pressed <br/>");  
}, 500));

DEMO


As Esailija mentions in his comment, maybe it is not throttling that you need but debouncing. This is a similar but slightly different concept. While throttling means that something should occur only once every x milliseconds, debouncing means that something should occur only if it didn't occur in the last x milliseconds.

A typical example is the scroll event. A scroll event handler will be called very often because the event is basically triggered continuously. But maybe you only want to execute the handler when the user stopped scrolling and not while he is scrolling.

A simple way to achieve this is to use a timeout and cancel it if the function is called again (and the timeout didn't run yet):

function debounce(func, interval) {
    var lastCall = -1;
    return function() {
        clearTimeout(lastCall);
        var args = arguments;
        var self = this;
        lastCall = setTimeout(function() {
            func.apply(self, args);
        }, interval);
    };
}

A drawback with this implementation is that you cannot return a value from the event handler (such as return false;). Maybe there are implementations which can preserve this feature (if required).

DEMO




回答2:


I would do that event throttling as simple as this:

$("#inputField").on("keypress", function(event) {
    var now = Date.now();
    var nt = $(this).data("lastime") || now; 
    if( nt > now ) return;
    $(this).data("lastime", now + 500);  
    $("div#output").append("key pressed <br/>");  
});



回答3:


Record when the last time you processed the event was, and each time you get an event, do a check to see if the interval you want has elapsed.



来源:https://stackoverflow.com/questions/18177174/how-to-limit-handling-of-event-to-once-per-x-seconds-with-jquery-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!