【问题标题】:Idiomatic jQuery delayed event (only after a short pause in typing)? (aka timewatch/typewatch/keywatch)惯用的 jQuery 延迟事件(仅在输入短暂暂停后)? (又名计时器/打字机/键盘表)
【发布时间】:2011-01-14 06:20:20
【问题描述】:

这里有一些用于搜索框的 jQuery,我认为它实际上是一种反模式,并且我确信有一个更好的解决方案,我很乐意指出:

我会用 cmets 来描述,然后就给出代码,因为 cmets 可能比代码更清晰和简单:

  • //在按键上设置函数调用。
  • // 函数调用在主事件发生之前有一个延迟。
  • // 当按键功能被调用时,清除所有之前排队的事件,并以标准延迟率创建一个新事件。
  • //使用全局来存储setTimeout指针。
  • // clearTimeout 任何预先存在的指针。
  • // 开始新的延迟。

代码:

                // set up a filter function call on keypress.
                $('#supplier-select-filter').keypress(function (){
                    // Currently, resets a delay on an eventual filtering action every keypress.
                    filterSuppliers(.3, this);
                });

                // Delayed filter that kills all previous filter request.
                function filterSuppliers(delay, inputbox){
                    if(undefined != typeof(document.global_filter_trigger)){
                        clearTimeout(document.global_filter_trigger);
                        // clearTimeout any pre-existing pointers.
                    }
                    // Use a global to store the setTimeout pointer.
                    document.global_filter_trigger = setTimeout(function (){
                        var mask = $(inputbox).val();
                        $('#user_id').load("supplier.php?action=ajax_getsuppliers_html&mask="+escape(mask)); 
                    }, 1000*delay); 
                    // Finally, after delay is reached, display the filter results.             
                }

问题:

在一个搜索词可能平均由 10 个字符组成的输入框中,即在半秒内调用了 10 次 setTimeout,这似乎是处理器的负担,并且在我的测试中会导致一些明显的性能问题,所以希望有更清洁的选择吗?

.load() 比接受 JSON 然后从 json 生成 html 更简单,但也许有更好的工具?

.keypress() 似乎并不总是触发退格删除和其他必需品,所以也许在这个输入框上使用 keypress() 不是理想的?

【问题讨论】:

  • 小评论——“10 次调用 setTimeout 在半秒内”并不是真正的性能问题,我一点也不担心。

标签: jquery events delay


【解决方案1】:

我经常使用以下方法,一个简单的函数在用户停止输入指定的时间后执行回调::

$(selector).keyup(function () {
  typewatch(function () {
    // executed only 500 ms after the last keyup event.
  }, 500);
});

实施:

var typewatch = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

我觉得这个方法很简单,不涉及任何全局变量。

如需更复杂的用法,请查看 jQuery TypeWatch Plugin

【讨论】:

  • 我还建议在通过 AJAX 获取新数据之前检查回调函数中是否 current_value !== previous_value。可能是用户只是使用箭头键等。
  • 嗯。看起来很干净,虽然我真的不明白 setTimeout 指针是如何成为非全局的,但后来仍然像 php 中的静态变量一样访问,但我确信它可以工作。什么叫允许这样做?
  • @Tchalvak:即使第一个函数已经完成执行,变量仍然在返回函数的范围内,因为创建了一个 closure,这是最JavaScript 的强大功能……看看这篇文章:jibbering.com/faq/faq_notes/closures.html
  • 我回到这个答案太多了(基本上我想在几乎所有 javascript 上使用 typewatch),我必须在这里给予赏金。
  • 就像 CMS 所做的那样,我确实建议翻转到 keyup 而不是 keypress。出于某种原因,SO 上有很多关于它在浏览器中更干净地工作的讨论。
【解决方案2】:

看看来自 Zurb 的优秀 Text Change Event 插件,它是最优质 jQuery 商品的供应商。

【讨论】:

  • OP 想要在输入暂停后进行回调,这不是 Text Change Event 插件所做的。
  • 可以帮助 OP 实现他想要的功能。它确实提供了一个更好的事件来触发延迟回调。我不是这个页面上唯一一个建议如果输入的内容没有改变则可能不应该调用回调的人。
【解决方案3】:

这是一种更好的方法,无需使用插件:

var timeout;
$('input[type=text]').keypress(function() {
if(timeout) {
    clearTimeout(timeout);
    timeout = null;
}

timeout = setTimeout(myFunction, 5000)
})

【讨论】:

    猜你喜欢
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多