代码之家  ›  专栏  ›  技术社区  ›  Max Williams

(jquery/js)-从keyup上的字段中获取文本,但会延迟进一步键入

  •  14
  • Max Williams  · 技术社区  · 16 年前

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

    最好是这样的

    • 检测到键控-开始等待(一秒钟)

    • 检测到另一个键控-重新启动等待时间

    • 等待完成-获取值并提交表单

    在我开始编写自己版本的代码之前(我真的是一个只有一点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 Line 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;
    }
    
    5 回复  |  直到 12 年前
        1
  •  24
  •   dan richardson    16 年前

    抱歉,我还没有测试过这个,它有点超出我的头,但沿着这些线的东西应该有希望做到这一点。将2000更改为服务器发布之间所需的毫秒数

    <input type="text" id="mytextbox" style="border: 1px solid" />
    <span></span>
    
    <script language="javascript" type="text/javascript">
        jQuery(function(){
          jQuery('#mytextbox')
            .data('timeout', null)
            .keyup(function(){
                clearTimeout(jQuery(this).data('timeout'));
                jQuery(this).data('timeout', setTimeout(submitQuizForm, 2000));
            });
        });
    </script>
    
        2
  •  7
  •   Sam Dutton    13 年前

    这是您喜欢的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.
                }
            }
        });
    

    默认情况下会延迟半秒。

        3
  •  4
  •   Max Williams    16 年前

    作为一个更新,我最终得到的结果似乎很好:

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

    然后我从相关文档的页面调用此函数。ready block with

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

    最好是创建一个使用此逻辑的新jquery事件,例如delayedkeyup与.keyup并排,这样我就可以对单个页面的document.ready块说类似的话。

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

    但是,我不知道如何用这种方式定制jquery。不过,这是一个很好的家庭作业。

        4
  •  3
  •   Nicolas Connault    15 年前

    干得好,麦克斯,这对我很有帮助!我对你的功能做了一点小小的改进,使其更加通用:

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

    通过这种方式,您可以将它用于任何类型的事件,尽管keyup在这里可能是最有用的。

        5
  •  0
  •   Kyro    12 年前

    我知道这很古老,但当我在寻找如何做类似的事情时,它是第一个结果之一,所以我想我会分享我的解决方案。我把提供的答案结合起来,从中得到我需要的东西。

    我想要一个定制的事件,就像现有的jquery事件一样工作,它需要与 keypress +删除、退格和回车。

    这是我的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 */ });