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

#javascript #jquery #ajax

#javascript #jquery #ajax

Вопрос:

предыстория

У меня есть несколько выпадающих списков на странице. Если вы измените первый, остальные выпадающие списки обновляются в соответствии с тем, что вы выбрали.

В нашем случае мы имеем дело с данными фонда. Итак, первый выпадающий список — «Все типы фондов». Вы выбираете «Хедж-фонды», и следующий выпадающий список фильтруется параметрами, которые применимы только к хедж-фондам.

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

Итак, если они введут «USD», второй выпадающий список будет содержать только варианты, в названии которых указаны средства с «USD».

проблема

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

 $('#Search').keypress(function () {
    // trigger the updating process
});
  

Это запускает поиск при каждом нажатии клавиши. Итак, когда я набираю «USD», я получаю сразу 3 запроса — один для «U», один для «US» и один для «USD».

Я попытался установить тайм-аут с помощью этого:

 $('#Search').keypress(function () { 
    // I figure 2 seconds is enough to type something meaningful
    setTimeout(getFilteredResultCount(), 2000);
});
  

но все, что нужно, это подождать 2 секунды, прежде чем делать то, что я описал.

Я уверен, что эта проблема была решена раньше. Может кто-нибудь подсказать, как решить эту проблему?

Комментарии:

1. Вы уверены, что хотите передать возвращаемое значение getFilteredResultCount в setTimeout , а не саму функцию?

2. То, что вы хотите, называется отменой события . Для jQuery есть плагины

3. Это выглядит очень интересно, но в этот час в пятницу и с таким количеством текста — это подождет до понедельника!! 🙂 хороший момент по поводу возвращаемого значения getFilteredResultCount . К счастью, мне не нужно, чтобы она что-либо возвращала, но это полезно иметь в виду

4. Так что вы, вероятно, хотите setTimeout(getFilteredResultCount, 2000); . Если вы добавляете скобки, вы немедленно вызываете функцию.

Ответ №1:

Способ, которым я делал это раньше, — установить тайм-аут, но очищать существующий тайм-аут при каждом нажатии новой клавиши. Таким образом, вы должны получать запрос, отправляемый только тогда, когда пользователь перестал печатать.

 var timeoutId = 0;
$('#Search').keypress(function () { 
    clearTimeout(timeoutId); // doesn't matter if it's 0
    timeoutId = setTimeout(getFilteredResultCount, 500);
    // Note: when passing a function to setTimeout, just pass the function name.
    // If you call the function, like: getFilteredResultCount(), it will execute immediately.
});
  

(Я бы выбрал тайм-аут около 500 мс.)

Комментарии:

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

2. Я попробовал это, и это делает точно так же, как моя первоначальная проблема.. Я все еще отправляю 3 запроса для U, S amp; D. Я посмотрю поближе и посмотрю, смогу ли я что-нибудь сделать

3. Очевидно, что если вы оставляете более 500 мс между каждым нажатием клавиши, вы получите три запроса. Но вы это знаете, верно?

4. @Dave: Проблема здесь в том, что setTimeout(getFilteredResultCount(), 500); функция выполняется немедленно. Не передавайте строку, просто передайте саму функцию: setTimeout(getFilteredResultCount, 500); (без () ) (Я знаю, что сказал то же самое выше, но я хотел, чтобы @Tim тоже знал).

5. К вашему сведению, если вам нужно передать параметр, вы можете обернуть вызов вашей функции в другую функцию, вот так: setTimeout( function() { getFilteredResultCount(someParameterOfMine) }, 500);