jQueryにはこれを行う組み込みの方法がありますか?
いいえ。
そうでない場合、2番目のjsfiddleの例で使用したよりも、バニラJSでこれを行うためのより良いパターンはありますか?
およびフラグを使用する代わりにsetTimeout
、ハンドラーが最後に呼び出されたときを追跡し、定義された間隔が経過した後にのみ呼び出すことができます。これはスロットリングと呼ばれ、これを実装するにはさまざまな方法があります。
最も単純な形式では、 の時間内に行われるすべての呼び出しを無視するだけでよいlastCall + interval
ため、すべての間隔で 1 つの呼び出しのみが発生します。
たとえば、次の関数は、X ミリ秒ごとに 1 回だけ呼び出すことができる新しい関数を返します。
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 <br/>");
}, 500));
デモ
Esailijaが彼のコメントで述べているように、おそらく必要なのはスロットリングではなく、デバウンスです。これは似ていますが、少し異なる概念です。スロットリングとは、x ミリ秒ごとに 1 回だけ何かが発生することを意味しますが、デバウンスとは、最後の 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;
) から値を返すことができないことです。この機能を保持できる実装があるかもしれません (必要な場合)。
デモ