14

ユーザーが結果をフィルター処理できるように、Web ページにチェック ボックスのある検索ボックスがあります。一度にチェックできるチェック ボックスは 1 つだけです。

チェック ボックスをクリックすると、コードが実行され、フィルタがリストに適用され、正しい結果が返されます。

私が抱えている問題は、チェックボックスが立て続けに複数回クリックされると、リクエストがキューに入れられ、1 つずつ引き戻されることです。チェックボックスを何度もオンにしてからオフにすると、時間がかかる場合があります。

関数が再度呼び出されたことを関数に通知し、この最後の要求以外のすべてを停止する必要があることを Javascript に通知する方法はありますか?

4

3 に答える 3

17

onclick次のようなデバウンス関数でコールバックをラップしたい

http://underscorejs.org/#debounce

これを持っていると言う

function search() {
    // ...
}

$jquery(".myFilterCheckboxes").click(search);

上記を次のように変更できるはずです。

// Only allow one click event / search every 500ms:
$jquery(".myFilterCheckboxes").click(_.debounce(search, 500));

デバウンス関数はたくさんありますが、underscore.js を含めることができない場合、または含めたくない場合は、独自の関数を作成することは大したことではありません。

短期間に複数のイベントを作成する複数のクリックについて言及したため、最初に考えたのはデバウンスです。デバウンスは、先行入力検索やオートコンプリートなどでよく使用され、キーを押す間に思考時間を確保するためのわずかなスペースを提供します。

他の人が言及しているように、検索の実行中にチェックボックス/クリックイベントを無効にする方が理にかなっている場合があります。その場合は、次のようにしてみてください。

function disableClick(elem) {
  elem.unbind("click");
  elem.attr("disabled", true);
}

function enableClick(elem, onclick) {
  // Enable click events again
  elem.live("click", search);
  // Enable the checkboxes
  elem.removeAttr("disabled");
}

function search() {
  var boxes = $jquery(".myFilterCheckboxes");
  disableClick(boxes);
  $.get(...).always(function() {
    enableClick(boxes, search);
  });
}

$jquery(".myFilterCheckboxes").live("click", search);

なぜクリック イベントを無効にし、グローバル ロック変数の代わりに無効属性をチェックボックスに追加するのですか? グローバル ロックは多少エラーが発生しやすい可能性がありますが、それ以上に、DOM で重要なグローバル オブジェクトが既に存在します。DOM の状態を変更するだけで、正しい動作が得られ、検索が完了するまでチェックボックスをオンにする必要があることをユーザーに知らせることができます。

とは言っても、読み込み中のスピナーまたは作業中の何かを使用してユーザーに示すことは、あらゆる種類のロック/バインド解除のシナリオでおそらく理にかなっています。

于 2014-08-04T13:18:01.920 に答える
12

ロックパターンを使用できます:

http://jsfiddle.net/RU6gL/

HTML

<input type="checkbox" onclick="fire()" >CB1
<br />
<input type="checkbox" onclick="fire()" >CB2

JS

function_lock = false

fire = function() {
    // First, check the lock isn't already reserved. If it is, leave immediately.
    if (function_lock) return;

    // We got past the lock check, so immediately lock the function to 
    // stop others entering
    function_lock = true;

    console.log("This message will appear once, until the lock is released")

    // Do your work. I use a simple Timeout. It could be an Ajax call.
    window.setTimeout(function() {
        // When the work finishes (eg Ajax onSuccess), release the lock.
        function_lock = false;
    }, 2000);
}

この例では、タイムアウトによって 2 秒後にロックが解除されるまで、チェックボックスが何回クリックされても、関数は 1 回だけ実行されます。

このパターンは、「デバウンス」のような時間間隔に依存するのではなく、ロックを解除するときに操作を制御できるため、非常に優れています。たとえば、Ajax で動作します。チェックボックスがフィルタリングを行うための Ajax 呼び出しをトリガーしている場合は、次のことができます。

  1. 最初のクリックで、ロックを設定します
  2. Ajax エンドポイントを呼び出します。その後のクリックでは、Ajax エンドポイントは呼び出されません。
  3. Ajax 成功関数で、ロックをリセットします。
  4. チェックボックスを再度クリックできるようになりました。

HTML

<input type="checkbox" onclick="doAjax()" >CB2

JS

ajax_lock = false

doAjax: function() {
    // Check the lock.
    if (ajax_lock) return;

    // Acquire the lock.
    ajax_lock = true;

    // Do the work.
    $.get("url to ajax endpoint", function() {
         // This is the success function: release the lock
         ajax_lock = false;
    });   
} 
于 2014-08-04T13:24:07.227 に答える