(jquery / js) – 在keyup上从字段获取文本,但是有进一步输入的延迟

大家好。 我有一个表单,当各种元素发生变化时,它会被远程提交。 特别是在搜索字段上,我使用键盘来检测字段中的文本何时发生变化。 这个问题是,当有人输入“鸡”时,表单会被提交七次,只有最后一次计数。

更好的是这样的事情

  • 检测到密钥 – 开始等待(一秒钟)

  • 检测到另一个密钥 – 重启等待时间

  • 等待完成 – 获得价值并提交表格

在我离开并编写我自己的版本之前(我真的是一个只有一点js的后端人,我用jquery来处理所有事情),是否已有现有的解决方案? 这似乎是一个普遍的要求。 一个jquery插件可能吗? 如果没有,最简单,最好的方法是什么?

谢谢,最大

更新 – 为Dan添加的当前代码(下)

丹 – 这可能是相关的。 我正在页面上使用的一个jquery插件(tablesorter)需要这个文件 – “tablesorter / jquery-latest.js”,如果包含它,会导致与您之前的代码相同的错误:

jQuery(“input #search”)。data(“timeout”,null)未定义http://192.168.0.234/javascripts/main.js?1264084467第11行

也许在不同的jquery定义之间存在某种冲突? (或者其他的东西)

$(document).ready(function() { //initiate the shadowbox player // Shadowbox.init({ // players: ['html', 'iframe'] // }); }); jQuery(function(){ jQuery('input#search') .data('timeout', null) .keyup(function(){ jQuery(this).data('timeout', setTimeout(function(){ var mytext = jQuery('input#search').val(); submitQuizForm(); jQuery('input#search').next().html(mytext); }, 2000) ) .keydown(function(){ clearTimeout(jQuery(this).data('timeout')); }); }); }); function submitQuizForm(){ form = jQuery("#searchQuizzes"); jQuery.ajax({ async:true, data:jQuery.param(form.serializeArray()), dataType:'script', type:'get', url:'/millionaire/millionaire_quizzes', success: function(msg){ // $("#chooseQuizMainTable").trigger("update"); } }); return true; } 

对不起,我没有对此进行测试,这有点偏离我的脑海,但是这些方面的内容应该有所帮助。 将服务器post之间的2000更改为您需要的毫秒数

    

这是你喜欢的jquery扩展:

 (function($){ $.widget("ui.onDelayedKeyup", { _init : function() { var self = this; $(this.element).keyup(function() { if(typeof(window['inputTimeout']) != "undefined"){ window.clearTimeout(inputTimeout); } var handler = self.options.handler; window['inputTimeout'] = window.setTimeout(function() { handler.call(self.element) }, self.options.delay); }); }, options: { handler: $.noop(), delay: 500 } }); })(jQuery); 

像这样使用它:

  $("input.filterField").onDelayedKeyup({ handler: function() { if ($.trim($(this).val()).length > 0) { //reload my data store using the filter string. } } }); 

默认情况下会延迟半秒。

作为更新,我最终得到了这似乎运作良好:

 function afterDelayedKeyup(selector, action, delay){ jQuery(selector).keyup(function(){ if(typeof(window['inputTimeout']) != "undefined"){ clearTimeout(inputTimeout); } inputTimeout = setTimeout(action, delay); }); } 

然后我从问题的document.ready块中调用它

  afterDelayedKeyup('input#search',"submitQuizForm()",500) 

最好的做法是使用这个逻辑创建一个新的jquery事件,例如.delayedKeyup与.keyup一起使用,所以我可以对单个页面的document.ready块说出类似的内容。

  jQuery('input#search').delayedKeyup(function(){ submitQuizForm(); }); 

但是,我不知道如何以这种方式自定义jquery。 不过,这是一项不错的家庭作业。

干得好,马克斯,这对我很有帮助! 通过使它更通用,我对你的function略有改进:

 function afterDelayedEvent(eventtype, selector, action, delay) { $(selector).bind(eventtype, function() { if (typeof(window['inputTimeout']) != "undefined") { clearTimeout(inputTimeout); } inputTimeout = setTimeout(action, delay); }); } 

这样你可以将它用于任何类型的事件,虽然keyup可能是最有用的。

我知道这是旧的,但这是我在寻找如何做这样的事情时的第一个结果之一,所以我会分享我的解决方案。 我使用了所提供答案的组合来获得我需要的东西。

我想要一个像现有jQuery事件一样工作的自定义事件,它需要使用keypress + delete,backspace和enter。

这是我的jQuery插件:

 $.fn.typePause = function (dataObject, eventFunc) { if(typeof dataObject === 'function') { eventFunc = dataObject; dataObject = {}; } if(typeof dataObject.milliseconds === 'undefined') dataObject.milliseconds = 500; $(this).data('timeout', null) .keypress(dataObject, function(e) { clearTimeout($(this).data('timeout')); $(this).data('timeout', setTimeout($.proxy(eventFunc, this, e), dataObject.milliseconds)); }) .keyup(dataObject, function(e) { var code = (e.keyCode ? e.keyCode : e.which); if(code == 8 || code == 46 || code == 13) $(this).triggerHandler('keypress',dataObject); }); } 

我使用$.proxy()来保存事件中的上下文,尽管可能有更好的方法来执行此操作,性能方面。

要使用此插件,只需执行以下操作:

 $('#myElement').typePause(function(e){ /* do stuff */ }); 

要么

 $('#myElement').typePause({milliseconds: 500, [other data to pass to event]},function(e){ /* do stuff */ });