最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use setTimeout.delay() to wait for typing between characters - Stack Overflow

programmeradmin0浏览0评论

I am creating a simple listbox filter that takes the user input and returns the matching results in a listbox via javascript/jquery (roughly 5000+ items in listbox). Here is the code snippet:

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

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

Listbox1.children().remove();


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

This works pretty well, but slows down somewhat when the 1st/2nd char's are being typed since there are so many items.

I thought a solution I could use would be to add a delay to the textbox that prevents the 'keyup' event from being called until the user stops typing. The problem is, I'm not sure how to do that, or if its even a good idea or not.

Any suggestions/help is greatly appreciated.

I am creating a simple listbox filter that takes the user input and returns the matching results in a listbox via javascript/jquery (roughly 5000+ items in listbox). Here is the code snippet:

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

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

Listbox1.children().remove();


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

This works pretty well, but slows down somewhat when the 1st/2nd char's are being typed since there are so many items.

I thought a solution I could use would be to add a delay to the textbox that prevents the 'keyup' event from being called until the user stops typing. The problem is, I'm not sure how to do that, or if its even a good idea or not.

Any suggestions/help is greatly appreciated.

Share Improve this question asked May 26, 2010 at 13:43 DarcyDarcy 5,36812 gold badges55 silver badges79 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

You can do a delay like this:

$('#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 < mands.options.length; i++) {
    if (mands.options[i].text.toLowerCase().match($(this).val().toLowerCase())) {
      $('<option></option>', { val: i, html: mands.options[i].text }).appendTo(temp);
    }
  }
  Listbox1.empty().append(temp.children());
}

This stores a timeout on the element you're typing in, if 500ms (adjust as needed) passes between keystrokes, a search executes. Also this appends the elements in a document fragment then into the DOM (still preserving encoding, etc). Depending on the number of items, this may be a decent performance boost as well.

If the mands drop-down isn't changing, I'd suggest the following (note I've dropped jQuery for better performance and patibility). There are several improvements:

  • Timer to delay updating the filtered list once half a second has elapsed since the last keypress
  • List of mand texts is pre-cached
  • Unnecessary use of match replaced with indexOf
  • Uses fast native DOM manipulation that works in all scriptable browsers since the 1990s

A quick test suggests that for a drop-down with 5000 options containing short strings, it's between 10 and 30 times faster than the jQuery equivalent in most browsers.

Code:

var mands = 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 mands drop-down
var mandTexts = [], mandText;
for (var i = 0, len = mands.options.length; i < len; ++i) {
    mandText = mands.options[i].text;
    mandTexts.push({original: mandText, lower: mandText.toLowerCase()});
}

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

filterInput.onkeyup = function() {
    if (timer) {
        window.clearTimeout(timer);
    }
    timer = window.setTimeout(populateFilteredDropDown, 500);
};
发布评论

评论列表(0)

  1. 暂无评论