7

急速に発生するイベントの場合、イベントの処理を最大Xkeypressに 1 回に制限したいと考えています。

私はすでにイベント処理に jQuery を使用しているため、jQuery ベースのソリューションが推奨されますが、バニラ Javascript も問題ありません。

  • このjsfiddleは、処理を制限することなくキープレスが急速に発火することを示しています

  • この jsfiddleは、バニラ JS で処理を 0.5 秒に 1 回に制限する実装を使用します。setTimeout()

私の質問は

  1. jQueryにはこれを行う組み込みの方法がありますか? ドキュメントには何も表示されません.on()

  2. そうでない場合、 2番目のjsfiddleの例で使用したよりも、バニラJSでこれを行うためのより良いパターンはありますか?

4

3 に答える 3

31

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;) から値を返すことができないことです。この機能を保持できる実装があるかもしれません (必要な場合)。

デモ

于 2013-08-11T22:14:10.300 に答える
2

私なら、次のように簡単にイベントの調整を行います。

$("#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/>");  
});
于 2013-08-11T22:19:50.963 に答える