【问题标题】:delaying actions between keypress in jQuery延迟jQuery中按键之间的动作
【发布时间】:2011-01-25 12:56:27
【问题描述】:

如何在 jQuery 中延迟按键之间的操作。 例如;

我有这样的事情

 if($(this).val().length > 1){
   $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){
    if(data.length > 0) {
      $('#suggestions').show();
      $('#autoSuggestionsList').html(data);
    }else{
      $('#suggestions').hide();
    }
 });
}

如果用户不断输入,我想阻止发布数据。那么如何才能延迟 0.5 秒呢?

【问题讨论】:

  • 我假设这是在传递给keypress()的函数中?

标签: jquery ajax delay


【解决方案1】:

尼克的回答很完美,但如果立即处理第一个事件很关键,那么我认为我们可以这样做:

$(selector).keyup(function(e){ //or another event

    if($(this).val().length > 1){
        if !($.data(this, 'bouncing-locked')) {

            $.data(this, 'bouncing-locked', true)

            $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){
                if(data.length > 0) {
                    $('#suggestions').show();
                    $('#autoSuggestionsList').html(data);
                }else{
                    $('#suggestions').hide();
                }
           });

            self = this
            setTimeout(function() {
                $.data(self, 'bouncing-locked', false);

                //in case the last event matters, be sure not to miss it
                $(this).trigger("keyup"); // call again the source event
            }, 500)
        }
    }
});

【讨论】:

    【解决方案2】:

    有一个很好的插件来处理这个问题。 jQuery Throttle / Debounce

    【讨论】:

    • 不是所有东西都依赖 jQuery 吗?不得不承认——“Debounce”这个名字引起了愤世嫉俗的笑声!无论如何,很好的发现。
    • lodash 还有throttledebounce 方法
    【解决方案3】:

    我会将它包装在这样的函数中:

      var needsDelay = false;
    
      function getSuggestions(var search)
      {
        if(!needsDelay)
        {
            needsDelay = true;
            setTimeout("needsDelay = false", 500);
    
            if($(this).val().length > 1){
                $.post("stuff.php", {nStr: "" + search + ""}, function(data){
                    if(data.length > 0) {
                        $('#suggestions').show();
                        $('#autoSuggestionsList').html(data);
                    }else{
                        $('#suggestions').hide();
                    }
                });
            }
        }
    
    
      }
    

    这样,无论您 ping 多少次,您的搜索时间都不会超过每 500 毫秒。

    【讨论】:

    • 永远不要将字符串传递给 setTimeout! eval 是邪恶的(在 大多数 情况下):) 使用匿名函数,例如:setTimeout(function() { needsDelay = false; }, 500);
    • 我知道 eval 是邪恶的,但我仍然很懒,在我的代码中添加了 eval 语句。我需要将其添加到我的纳粹名单中。没有更多的评估。
    【解决方案4】:

    您需要做的就是将您的函数包装在一个超时中,当用户按下一个键时该超时会被重置:

    var ref;
    var myfunc = function(){
       ref = null;
       //your code goes here
    };
    var wrapper = function(){
        window.clearTimeout(ref);
        ref = window.setTimeout(myfunc, 500);
    }
    

    然后在您的关键事件中简单地调用“包装器”。

    【讨论】:

      【解决方案5】:

      您可以使用 jQuery 的数据功能来执行此操作,如下所示:

      $('#mySearch').keyup(function() {
        clearTimeout($.data(this, 'timer'));
        var wait = setTimeout(search, 500);
        $(this).data('timer', wait);
      });
      
      function search() {
        $.post("stuff.php", {nStr: "" + $('#mySearch').val() + ""}, function(data){
          if(data.length > 0) {
            $('#suggestions').show();
            $('#autoSuggestionsList').html(data);
          }else{
            $('#suggestions').hide();
          }
        });
      }
      

      这里的主要优点是没有全局变量,如果你愿意,你可以将它包装在 setTimeout 中的匿名函数中,只是试图使示例尽可能干净。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-19
        • 2018-01-23
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        • 2012-07-18
        相关资源
        最近更新 更多