(jquery/js) - получить текст из поля на keyup, но с задержкой для дальнейшего ввода
Привет всем. У меня есть форма, которая отправляется удаленно, когда различные элементы меняются. В поле поиска, в частности, я использую keyup для обнаружения, когда текст в поле изменяется. Проблема с этим заключается в том, что когда кто-то набирает "курица", то форма представляется семь раз, причем только последний подсчет.
что было бы лучше, если бы что-то вроде этого
обнаружен keyup-начало ожидания (для одного секунду)
обнаружен еще один ключ-перезапустить время ожидания
ожидание заканчивается-получить значение и отправить форму
прежде чем я уйду и закодирую свою собственную версию этого (я действительно бэкэнд-парень с небольшим js, я использую jquery для всего), есть ли уже существующее решение для этого? Кажется, это было бы общим требованием. Может быть, плагин jquery? если нет, то какой самый простой и лучший способ кодирования это?
спасибо, Макс
UPDATE-текущий код добавлен для Dan (ниже)
Dan - это может быть актуально. Один из плагинов jquery, который я использую на странице (tablesorter), требует этого файла - "tablesorter/jquery-latest.js", что, если включено, приводит к той же ошибке с вашим кодом, что и раньше:
jQuery ("input#search").данные ("timeout", null) не определены http://192.168.0.234/javascripts/main.Яш?1264084467 Линия 11
может быть, существует какой-то конфликт между различными определениями jquery? (или что-то)
$(document).ready(function() {
//initiate the shadowbox player
// Shadowbox.init({
// players: ['html', 'iframe']
// });
});
jQuery(function(){
jQuery('input#search')
.data('timeout', null)
.keyup(function(){
jQuery(this).data('timeout', setTimeout(function(){
var mytext = jQuery('input#search').val();
submitQuizForm();
jQuery('input#search').next().html(mytext);
}, 2000)
)
.keydown(function(){
clearTimeout(jQuery(this).data('timeout'));
});
});
});
function submitQuizForm(){
form = jQuery("#searchQuizzes");
jQuery.ajax({
async:true,
data:jQuery.param(form.serializeArray()),
dataType:'script',
type:'get',
url:'/millionaire/millionaire_quizzes',
success: function(msg){
// $("#chooseQuizMainTable").trigger("update");
}
});
return true;
}
5 ответов
Извините, я не тестировал это, и это немного с моей головы, но что-то в этом роде, надеюсь, сделает трюк. Измените 2000 на сколько миллисекунд вам нужно между сообщениями сервера
<input type="text" id="mytextbox" style="border: 1px solid" />
<span></span>
<script language="javascript" type="text/javascript">
jQuery(function(){
jQuery('#mytextbox')
.data('timeout', null)
.keyup(function(){
clearTimeout(jQuery(this).data('timeout'));
jQuery(this).data('timeout', setTimeout(submitQuizForm, 2000));
});
});
</script>
вот ваше необычное расширение jquery:
(function($){
$.widget("ui.onDelayedKeyup", {
_init : function() {
var self = this;
$(this.element).keyup(function() {
if(typeof(window['inputTimeout']) != "undefined"){
window.clearTimeout(inputTimeout);
}
var handler = self.options.handler;
window['inputTimeout'] = window.setTimeout(function() {
handler.call(self.element) }, self.options.delay);
});
},
options: {
handler: $.noop(),
delay: 500
}
});
})(jQuery);
используйте его так:
$("input.filterField").onDelayedKeyup({
handler: function() {
if ($.trim($(this).val()).length > 0) {
//reload my data store using the filter string.
}
}
});
делает задержку по умолчанию.
в качестве обновления, я закончил с этим, который, кажется, работает хорошо:
function afterDelayedKeyup(selector, action, delay){
jQuery(selector).keyup(function(){
if(typeof(window['inputTimeout']) != "undefined"){
clearTimeout(inputTimeout);
}
inputTimeout = setTimeout(action, delay);
});
}
затем я вызываю это со страницы в документе вопроса.готовый блок с
afterDelayedKeyup('input#search',"submitQuizForm()",500)
было бы неплохо сделать новое событие jquery, которое использует эту логику, например .delayedKeyup идти рядом .keyup, поэтому я мог бы просто сказать что-то вроде этого для документа отдельной страницы.готовый блок.
jQuery('input#search').delayedKeyup(function(){
submitQuizForm();
});
но я не знаю, как настроить jquery таким образом. Это хорошо. хотя домашнее задание.
хорошая работа, Макс, это было очень полезно для меня! Я сделал небольшое улучшение вашей функции, сделав ее более общей:
function afterDelayedEvent(eventtype, selector, action, delay) {
$(selector).bind(eventtype, function() {
if (typeof(window['inputTimeout']) != "undefined") {
clearTimeout(inputTimeout);
}
inputTimeout = setTimeout(action, delay);
});
}
таким образом, вы можете использовать его для любого типа событий, хотя keyup, вероятно, наиболее полезен здесь.
Я знаю, что это старый, но это был один из первых результатов, когда я искал, как сделать что-то подобное и я хотел поделиться своим решением. Я использовал комбинацию предоставленных ответов, чтобы получить то, что мне нужно.
Я хотел пользовательское событие, которое работало так же, как существующие события jQuery, и ему нужно было работать с keypress
+ delete, backspace и enter.
вот мой плагин jQuery:
$.fn.typePause = function (dataObject, eventFunc)
{
if(typeof dataObject === 'function')
{
eventFunc = dataObject;
dataObject = {};
}
if(typeof dataObject.milliseconds === 'undefined')
dataObject.milliseconds = 500;
$(this).data('timeout', null)
.keypress(dataObject, function(e)
{
clearTimeout($(this).data('timeout'));
$(this).data('timeout', setTimeout($.proxy(eventFunc, this, e), dataObject.milliseconds));
})
.keyup(dataObject, function(e)
{
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 8 || code == 46 || code == 13)
$(this).triggerHandler('keypress',dataObject);
});
}
Я $.proxy()
сохранить контекст в этом случае, хотя может быть лучший способ сделать это, с точки зрения производительности.
чтобы использовать этот плагин, просто сделать:
$('#myElement').typePause(function(e){ /* do stuff */ });
или
$('#myElement').typePause({milliseconds: 500, [other data to pass to event]},function(e){ /* do stuff */ });