3

ユーザー入力を受け取り、一致する結果をjavascript/jqueryを介してリストボックスに返す単純なリストボックスフィルタを作成しています(リストボックスの約5000以上のアイテム)。コード スニペットは次のとおりです。

var Listbox1 = $('#Listbox1');
var commands = document.getElementById('DatabaseCommandsHidden'); //using js for speed

$('#CommandsFilter').bind('keyup', function() {

Listbox1.children().remove();


for (var i = 0; i < commands.options.length; i++) {
    if (commands.options[i].text.toLowerCase().match($(this).val().toLowerCase())) {
        Listbox1.append($('<option></option>').val(i).html(commands.options[i].text));
    }
}
});

これは非常にうまく機能しますが、項目が非常に多いため、1 番目と 2 番目の文字が入力されているときは多少遅くなります。

私が使用できる解決策は、テキストボックスに遅延を追加して、ユーザーが入力を停止するまで「keyup」イベントが呼び出されないようにすることだと思いました。問題は、それを行う方法がわからない、またはそれが良いアイデアであるかどうかわからないことです。

提案/ヘルプは大歓迎です。

4

2 に答える 2

6

次のような遅延を行うことができます。

$('#CommandsFilter').keyup(function() {
  clearTimeout($.data(this, 'timer'));
  var wait = setTimeout(search, 500);
  $(this).data('timer', wait);
});

function search() {
  var temp = $("<select />");
  for (var i = 0; i < commands.options.length; i++) {
    if (commands.options[i].text.toLowerCase().match($(this).val().toLowerCase())) {
      $('<option></option>', { val: i, html: commands.options[i].text }).appendTo(temp);
    }
  }
  Listbox1.empty().append(temp.children());
}

これにより、入力している要素にタイムアウトが保存されます。キーストロークの間に 500 ミリ秒 (必要に応じて調整) が経過すると、検索が実行されます。また、これにより、ドキュメント フラグメント内の要素が DOM に追加されます (エンコーディングは保持されます)。アイテムの数にもよりますが、これはかなりのパフォーマンスの向上にもなります。

于 2010-05-26T13:57:52.583 に答える
2

コマンドのドロップダウンが変わらない場合は、次のことをお勧めします (パフォーマンスと互換性を向上させるために jQuery を削除したことに注意してください)。いくつかの改良点があります:

  • 最後にキーを押してから 0.5 秒が経過すると、フィルタリングされたリストの更新を遅らせるタイマー
  • コマンド テキストのリストは事前にキャッシュされます
  • match置換の不必要な使用indexOf
  • 1990 年代以降、すべてのスクリプト可能なブラウザーで動作する高速なネイティブ DOM 操作を使用します

簡単なテストでは、短い文字列を含む 5000 個のオプションを含むドロップダウンの場合、ほとんどのブラウザーで同等の jQuery よりも 10 倍から 30 倍高速であることが示唆されています。

コード:

var commands = document.getElementById("DatabaseCommandsHidden");
var filteredDropDown = document.getElementById("Listbox1");
var filterInput = document.getElementById("CommandsFilter");
var timer;

// Create a cached list of the lower case text of the commands drop-down
var commandTexts = [], commandText;
for (var i = 0, len = commands.options.length; i < len; ++i) {
    commandText = commands.options[i].text;
    commandTexts.push({original: commandText, lower: commandText.toLowerCase()});
}

function populateFilteredDropDown() {
    timer = null;
    var val = filterInput.value.toLowerCase(), commandText;
    var opts = filteredDropDown.options;
    filteredDropDown.length = 0;
    for (var i = 0, len = commandTexts.length; i < len; ++i) {
        commandText = commandTexts[i];
        if (commandText.lower.indexOf(val) > -1) {
            opts[opts.length] = new Option(commandText.original);
        }
    }
}

filterInput.onkeyup = function() {
    if (timer) {
        window.clearTimeout(timer);
    }
    timer = window.setTimeout(populateFilteredDropDown, 500);
};
于 2010-05-26T14:41:37.550 に答える