如何使用jQuery / javascript将事件的处理限制为每X秒一次?

对于快速触发的keypress事件,我希望将事件的处理限制为每X秒最多一次。

我已经在使用jQuery进行事件处理,所以基于jQuery的解决方案会更受欢迎,尽管vanilla javascript也很好。

  • 这个jsfiddle快速显示按键触发,不受任何操作限制

  • 这个jsfiddle实现了使用setTimeout() vanilla JS中的处理限制为每0.5秒一次

我的问题是

  1. jQuery有内置的方法吗? 我在.on() 文档中没有看到任何内容

  2. 如果没有,在我的第二个jsfiddle例子中使用vanilla JS有没有更好的模式呢?

jQuery有内置的方法吗?

没有。

如果没有,在我的第二个jsfiddle例子中使用vanilla JS有没有更好的模式呢?

您可以跟踪上次调用处理程序的时间,而只是在定义的时间间隔过后调用它,而不是使用setTimeout和flags。 这被称为限制,并且有各种方法来实现它。

在最简单的forms中,您只需忽略在lastCall + interval时间内进行的每个调用,以便每个间隔中只发生一次调用。

例如,这是一个返回一个新函数的函数,该函数每X毫秒只能调用一次:

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

你可以用作

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

DEMO


正如Esailija在他的评论中提到的那样,也许你不需要对它进行限制。 这是一个类似但略有不同的概念。 虽然限制意味着某些事情应该每x毫秒只发生一次,但是去抖动意味着只有在最后x毫秒内没有发生某些事情时才会发生。

典型的例子是scroll事件。 将经常调用滚动事件处理程序,因为事件基本上是连续触发的。 但也许你只想在用户停止滚动而不是滚动时执行处理程序。

实现此目的的一种简单方法是使用超时并在再次调用该函数时取消它(并且超时尚未运行):

 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); }; } 

此实现的缺点是您无法从事件处理程序返回值(例如return false; )。 也许有些实现可以保留此function(如果需要)。

DEMO

我会做那个事件限制就像这样简单:

 $("#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 
"); });

记录上次处理事件的时间,并且每次收到事件时,都要检查是否已经过了所需的时间间隔。