2010-03-09 69 views
29

如何延迟jQuery中的按键动作。例如, ;延迟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秒呢?

+0

我假定这是在传递到'按键()'函数? – Jeremy 2010-03-09 17:10:08

回答

59

您可以使用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的把这个包在一个匿名函数如果你想要的话,只要尽可能地让示例变得干净。

10

所有你需要做的是包装您的功能在被复位超时,当用户按下一个键:

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

然后,只需在您的关键事件调用“包装”。

+0

减少jQuery的简单解决方案。 – A1rPun 2013-09-23 10:30:07

1

我把它包在一个函数像这样:

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毫秒以上。

+5

永不传递一个字符串setTimeout! eval是邪恶的(在*大多数情况下):)使用一个类似于anoymous的函数:'setTimeout(function(){needsDelay = false;},500);'而不是。 – 2010-03-09 17:16:49

+0

我知道eval是邪恶的,但我仍然很懒,并在我的代码中放入了eval语句。我需要将其添加到我的纳粹名单。没有更多的评价。 – thaBadDawg 2010-03-09 18:15:42

3

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

+0

是不是有一个jQuery依赖的一切?不得不承认 - 名字“Debounce”唤起愤世嫉俗的笑声! 无论如何,很好找。 – matrixugly 2015-08-05 21:36:56

+0

lodash也有[throttle](https://lodash.com/docs#throttle)和[debounce](https://lodash.com/docs#debounce)方法 – 2015-08-11 10:37:24

2

尼克的答案是完美的,但如果马上处理第一个事件是关键的话,我认为我们可以做到:

$(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) 
     } 
    } 
});