如何使用 setTimeout / .delay() 等待字符之间的输入

发布于 2024-09-03 01:04:19 字数 720 浏览 5 评论 0原文

我正在创建一个简单的列表框过滤器,它接受用户输入并通过 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));
    }
}
});

这工作得很好,但是当输入第一个/第二个字符时,由于项目太多,速度会有所减慢。

我认为我可以使用的解决方案是向文本框添加延迟,以防止调用“keyup”事件,直到用户停止键入。问题是,我不确定如何做到这一点,或者这是否是一个好主意。

非常感谢任何建议/帮助。

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 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));
    }
}
});

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

删除会话 2024-09-10 01:04:19

您可以执行如下延迟:

$('#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 中(仍然保留编码等)。根据项目的数量,这也可能会带来不错的性能提升。

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 < 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());
}

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.

暖树树初阳… 2024-09-10 01:04:19

如果命令下拉列表没有改变,我建议执行以下操作(注意我已经放弃了 jQuery,以获得更好的性能和兼容性)。有几项改进:

  • 自上次按键后半秒后延迟更新过滤列表的计时器 预先
  • 缓存命令文本列表
  • 不必要使用 match 替换为 indexOf
  • 使用自 20 世纪 90 年代以来适用于所有可编写脚本的浏览器的快速本机 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);
};

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

  • Timer to delay updating the filtered list once half a second has elapsed since the last keypress
  • List of command 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 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);
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文