【问题标题】:Debounce search only if search term changes [duplicate]仅当搜索词更改时才反跳搜索[重复]
【发布时间】:2017-10-28 12:34:04
【问题描述】:

我正在开发一个实时 ajax 搜索字段。所以我们有:

<input type="search" id="search">

我想在用户停止输入 500 毫秒后触发搜索。

我是这样工作的:

function throttle(f, delay){
    var timer = null;
    return function(){
        var context = this, args = arguments;
        clearTimeout(timer);
        timer = window.setTimeout(function(){
            f.apply(context, args);
        },
        delay || 500);
    };
}

$('#search').keyup(throttle(function(){
    // do ajax
}));

问题是:如果用户按住shift键并松开它,搜索就会触发。因此没有添加新键,并且提交了相同的搜索词。

我怎样才能使它仅在添加/删除新角色时触发?

【问题讨论】:

  • change 事件而不是 keyup 怎么样?
  • @MartinAdámek 你能发布答案吗?

标签: javascript jquery ajax


【解决方案1】:

只需跟踪状态:

var currentSearch = "";

然后每当按键发生时,检查输入是否改变,如果没有停止更新:

if($("#search").val() === currentSearch) return;
//updated so:
currentSearch = $("#search").val();

旁注:由于 DOM 查找是时间密集型的,您可以缓存 $("#search") ...

【讨论】:

  • 只是测试你的代码。你的答案比另一个更好吗?
  • @henrik 在性能方面可能并不好,但我认为差异不可衡量/相关。然而,它允许更多的自定义......
  • 您能否详细说明cache $("#search") ... -- 我需要执行哪些步骤才能做到这一点?
  • @henrik 在上述范围内做var search = $("#search"),然后使用search.val() ...
  • 我不会为缓存id 选择器而烦恼,因为它们的性能非常好。那个被翻译成document.getElementById call。
【解决方案2】:

您还可以使用 keyup 事件,并检查键码是否与您要操作的键匹配。请参考this answer

根据您的情况调整答案:

$('#search').keyup(
    function(event) {
    var isWordCharacter = event.key.length === 1;
    var isBackspaceOrDelete = (event.keyCode == 8 || event.keyCode == 46);

    if (isWordCharacter || isBackspaceOrDelete) {
        (throttle(function(){
            // do ajax
        })))();
    }
})

【讨论】:

    【解决方案3】:

    您应该使用input 事件而不是keyup,它只会在值发生变化时触发。

    $('#search').on('input', throttle(function(){
        // do ajax
    }));
    

    &lt;input&gt;&lt;select&gt;&lt;textarea&gt; 元素的值发生更改时,DOM 输入事件会同步触发。 (对于 type=checkbox 或 type=radio 的 input 元素,当用户点击控件时不会触发 input 事件,因为 value 属性不会改变。)

    但请注意,该事件在 IE9/10/11 中存在一些问题(并且在之前的 IE 版本中根本不支持):

    [2] 当用户从输入中删除字符时(例如,通过按 Backspace 或 Delete,或使用“剪切”操作),IE 9 不会触发输入事件。

    [3] IE 10 和 11 有一个错误,输入事件会在占位符属性更改时触发。

    不过IE10/11的问题还好,看你是否需要支持IE9。

    https://developer.mozilla.org/en-US/docs/Web/Events/input

    编辑:不幸的是,change 不是一个合适的解决方案,因为它仅在blur 之后发生(失去输入的焦点)。正确的解决方案是使用input事件。

    【讨论】:

    • 没有意义。为什么需要限制更改事件?这显然不是 OP 正在寻找的行为
    • input() 比 Jonas 发布的方法更好吗?感谢您的回答。
    • 你说得对,我认为change 事件会在每次更改时触发。 input event 是要使用的。
    • @HenrikPetterson 确保检查链接参考页面上的浏览器兼容性表。看起来 IE 对此有一些怪癖(惊喜!)
    • 是的,将添加有关浏览器兼容性的注释。幸运的是,我不再需要在工作中支持 IE9 了:]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    相关资源
    最近更新 更多