2010-03-09 2 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(); 
    } 
}); 
} 

Я хочу, чтобы запретить отправку данных, если пользователь непрерывно печатать. Итак, как я могу дать задержку в 5 секунд?

+0

Я предполагаю, что это в функции, которая передается в 'нажатие клавиши()'? – Jeremy

ответ

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

+1 меньше jQuery для простого решения. – A1rPun

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


    } 

Таким образом, независимо от того, сколько раз вы пинг это, вы никогда не будете искать более чем через каждые 500 миллисекунд.

+5

никогда не передавайте строку в setTimeout! eval is evil (в * большинстве * случаях) :) используйте anoymous функцию вроде: 'setTimeout (function() {needsDelay = false;}, 500); вместо этого. –

+0

Я знаю, что eval - это зло, но я все еще ленив и ставил в своем коде утверждения eval. Мне нужно добавить это к моему списку нацистов. Больше нет. – thaBadDawg

3

Для этого есть хороший плагин. Ответ jQuery Throttle/Debounce

+0

не существует зависимости jQuery для всего? Приходится признаться - имя «Debounce» вызывает циничный смех! В любом случае, хорошая находка. – matrixugly

+0

lodash также имеет [throttle] (https://lodash.com/docs#throttle) и [debounce] (https://lodash.com/docs#debounce) методы –

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) 
     } 
    } 
}); 
Смежные вопросы