2012-04-12 8 views
9

У меня есть пользователи, делающие вызов ajax во время набора. Проблема заключается в том, что она делает вызов для каждой буквы набираясь, поэтому я таймаут так:Подождите, пока пользователь перестанет печатать

$(input).live('keyup', function(e){ 

setTimeout(function(){ 

var xx = $(input).val(); 
doSearch(xx); 

}, 400); 

}); 

Это ждать 400мс, но затем выполняет для каждого KeyUp. Как я могу изменить это, чтобы сделать вызов ajax только «один раз» около 400 мс после последней введенной буквы?

(я использовал «задержку» в прошлом, но это не работает на все с моим сценарием ...)

+0

Решение уже представлено в другом вопросе: https://stackoverflow.com/questions/4220126/run-javascript-function-when-user-finishes-typing-instead-of-on-key-up/16324620 # 16324620 –

ответ

18
timer = 0; 
function mySearch(){ 
    var xx = $(input).val(); 
    doSearch(xx); 
} 
$(input).live('keyup', function(e){ 
    if (timer) { 
     clearTimeout(timer); 
    } 
    timer = setTimeout(mySearch, 400); 
}); 

это лучше, чтобы переместить функцию к имени функции и назвать его несколько раз, потому в противном случае вы создаете другую функцию лямбда на каждом KeyUp, которая является ненужной и относительно дорогой

+0

Это работало как шарм :) – Youss

+0

@Youss, и что произойдет, если вы нажмете и отпустите одну клавишу, а затем удерживайте еще одну клавишу? – Alnitak

+0

@ Алнитак, вы правы, и есть другие проблемы с этим, например, когда вы вводите слишком медленно (более 400 мс между двумя клавишами), но в нормальном случае это делает вещи более гладкими – Gavriel

4

Вам нужно сбросить таймер каждый раз, когда новый ключ нажимается, например,

(function() { 
    var timer = null; 

    $(input).live('keyup', function(e) { 
     timer = setTimeout(..., 400); 
    }); 

    $(input).live('keydown', function(e) { 
     clearTimeout(timer); 
    }); 
)(); 

Выражение функция используется для того, чтобы сфера охвата timer переменной ограничивается этими двумя функциями, которые в этом нуждаются.

+0

Возможно, следует использовать '.on ('keyup', ...)' Поскольку jquery 1.7 '.live' устарел. – ZombieCode

+0

@ Екатерина да, возможно, это должно произойти, но это был минимальный набор изменений кода OP. – Alnitak

0

Я думаю, что вы могли бы использовать delay() в этом контексте, пока вы в порядке с добавлением нового временного «чего-то» в микс. Будет ли это работать для вас?

$(input).live('keyup', function(e) { 
    if (!$(input).hasClass("outRunningAJob")) { 
     var xx = $(input).val(); 
     $(input).addClass("outRunningAJob"); 
     doSearch(xx); 
     $(input).delay(400).queue(function() { 
      $(this).removeClass("outRunningAJob"); 
      $(this).dequeue(); 
     }); 
    } 
}); 
+0

Похоже на обходной путь ... Ответ, предоставленный @ Flöcsy, более прямолинейный. ps what is outRunningAJob :) – Youss

+0

Мне лично до сих пор не стало комфортно функционировать 'timeout', поэтому я подумал, что вы были в подобном месте, так как вы спрашиваете об этом. Это обходной путь? Именно так я сейчас подхожу к проблеме. Если вы в настоящее время более знакомы с использованием 'delay', то это может быть лучшим решением (с точки зрения обслуживания). 'outRunningAJob' просто произволен, но самодокументирован. Рад что вам понравилось :-) – veeTrain

0

я нашел следующее проще реализовать:

$(input).on('keyup', function() { 
    delay(function() { 
     if (input).val() !== '' && $(input).val() !== $(input).attr('searchString')) { 
      // make the AJAX call at this time 
      // Store the value sent so we can compare when JSON returns 
      $(input).attr('searchString', $(input).val()); 

      namepicker2_Search_Prep(input); 
     } 
    }, 500); 
}); 

Сохраняя текущую строку, которую вы можете увидеть, что пользователь перестал печатать. Затем вы можете безопасно называть свою функцию, чтобы делать то, что нужно для обработки.

Смежные вопросы