javascript - 如何防止用户键入时 keyup 功能滞后

标签 javascript jquery

我正在尝试在 jQuery 中创建一个搜索功能:

$('input').on('keyup', function(){
    var searchTerm = $("input").val().toLowerCase();
    $('.item').each(function(){
        if ($(this).filter('[data-text *= ' + searchTerm + ']').length > 0 || searchTerm.length < 1) {
            $(this).parent().show();
        } else {
            $(this).parent().hide();
        }
    });
});

每次用户输入内容时,都会将其与 .item div 的数据属性值进行比较。如果该元素的数据属性包含搜索查询,则会显示它 - 否则隐藏。

这在 Chrome 中完美运行,但在 Safari 中,由于某种原因,当用户键入时,它确实很滞后。

有办法解决这个问题吗?

大约有 1400 个 div (.item),每个元素的 data-text 属性只有大约 10-20 个字符

编辑,通过删除 .show().hide() 进行修复 - 并替换为原生 Javascript

最佳答案

解决方案

我以前遇到过类似的问题,我想你可能想尝试添加一些名为“debounce”的东西,这基本上会在执行任何过程之前添加延迟。在 keyup 情况下,它将等待用户停止输入任意设定的时间(假设 0.5 秒),然后然后执行该过程(搜索或其他)如果您不使用 debounce,它将在每次用户触发 keyup 事件时进行搜索。

你可以搜索一下如何做debounce的文章,我想有很多。但本质上它利用了JS的setTimeoutclearTimeout函数

这是我找到的第一篇文章:https://levelup.gitconnected.com/debounce-in-javascript-improve-your-applications-performance-5b01855e086

const debounce = (func, wait) => {
let timeout;

  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

如何使用这个功能?简单,只需添加您的实际函数(搜索函数)作为第一个参数,并在第二个参数中添加延迟(微秒),然后使用 .call() 函数(为什么这样做?因为 debounce 会返回一个函数) 。所以我猜是这样的:

$('input').on('keyup', function(){
    var searchTerm = $("input").val().toLowerCase();
    debounce(function(){
        $('.item').each(function(){
            if ($(this).filter('[data-text *= ' + searchTerm + ']').length > 0 || searchTerm.length < 1) {
                $(this).parent().show();
            } else {
                $(this).parent().hide();
            }
        });
    }, 500).call();
});

这就是我要做的,因为这样我就可以在 keyup 事件中添加 debounce 之外的一些东西,但是你可以将 debounce 返回的函数放入一个变量中,然后将其与 keyup 绑定(bind)(就像在文章),或者直接将去抖放在 keyup 中,如下所示:

$('input').on('keyup', debounce(function(){
    ...
},500));

它是如何工作的?

你可以在文章中阅读它们,或者在 StackOverflow 中找到答案,这是我得到的 Can someone explain the "debounce" function in Javascript

但是如果我用我自己的话来说,基本上你首先需要理解的是 setTimeout 在调用函数之前设置一个计时器,并 clearTimeout 取消该计时器。现在,在去抖动中,您可以看到在任何 setTimeout 之前都有一个 clearTimeout。因此,每次触发 keyup 事件时,它基本上都会取消上次设置的超时(如果有),然后设置新的超时。本质上,每次触发事件时,它都会将计时器重置为您设置的值。

例如:

  1. 用户想要搜索“abc”
  2. 他们输入“a” -> 在调用之前,去抖动设置了 500 毫秒的计时器 实际搜索“a”
  3. 在 500 毫秒结束之前,用户输入“b”,因此去抖会取消“a”搜索,并搜索“ab”,同时在执行此操作之前设置 500 毫秒的计时器
  4. 在500ms结束之前,用户输入“c”,因此取消“ab”搜索,添加500ms的定时器来搜索“abc”
  5. 用户停止输入,直到 500 毫秒结束,现在去抖动实际上调用了对“abc”的搜索

这会产生什么结果?对于“abc”,搜索的繁重处理仅执行一次,您也可以在该繁重处理中放置一个加载程序或其他东西,以便对用户来说看起来更好

关于javascript - 如何防止用户键入时 keyup 功能滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65964174/

相关文章:

javascript - 只有源时图像更改样式

javascript - 如何制作具有可滚动内容和最大高度的 Bootstrap 模态?

php - 将 php 响应发送到 ajax

javascript - 我无法从 html 表中获取数据

javascript - 在jquery ajax调用、成功/错误回调或done()/fail()链函数的情况下应该使用哪一个

php - 我需要在服务器端更改什么才能启用 chunkedMode = true?

JQuery 可调整大小向一个方向移动,并删除滚动条

jquery - Fancy Box jquery - 在 php overlay 后面打开

javascript - 将包含 HTML 实体的 JSON 序列化字符串转换为对象

javascript - 每次在同一行内选中复选框时获取具有特定id的td文本