我正在尝试为我的网站进行即时搜索。一切正常,除此之外。
var timeOut;
$('#search input[name=\'search\']').on('keyup', function(e) {
// If enter - submit the search field
if (e.keyCode == 13) {
$('header input[name=\'search\']').parent().find('button').trigger('click');
}
// Call only when length is at least 2 and the key pressed is alphanumeric
else if ($('#search input[name=\'search\']').val().length>2 && ((e.keyCode>=65 && e.keyCode<=90) || (e.keyCode>=97 && e.keyCode<=122))) {
timeOut = null;
//alert(timeOut);
if (!timeOut) {
timeOut = setTimeout(function() {
$.ajax({
url: 'ajax.php',
type: 'post',
async: false,
data: 'ACTION=SEARCH&search='+$('#search input[name=\'search\']').val(),
dataType: 'json',
beforeSend: function() {
$('#loader-icon').show();
},
complete: function() {
$('#loader-icon').hide();
},
success: function(json) {
//$('.product-list-row').html(json);
$('#search-listing').html(json['html']);
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
timeOut = null;
}, 500);
}
}
});
问题1:我的脚本最终会向服务器发出太多调用,由于某些原因setTimeOut
没有像我预期的那样工作。只有当用户完成打字或类似的操作时才应该进行Ajax调用,而不是在每次按键时都进行。
问题2:出于某种原因,当我快速输入时,输入条不会被编辑。然而,ajax可以工作,但最后一个文本输入。
答案 0 :(得分:2)
您可以使用AJAX返回的 jqXHR
对象中止之前的调用,而不是尝试使用setTimeout
解决此问题。使用它更干净,更简单。同时删除async: false,
。
var timeOut;
var xhr;
$('#search input[name=\'search\']').on('keyup', function(e) {
// If enter - submit the search field
if (e.keyCode == 13) {
$('header input[name=\'search\']').parent().find('button').trigger('click');
}
// Call only when length is at least 2 and the key pressed is alphanumeric
else if ($('#search input[name=\'search\']').val().length>2 && ((e.keyCode>=65 && e.keyCode<=90) || (e.keyCode>=97 && e.keyCode<=122))) {
if(xhr && xhr.readyState != 4){
xhr.abort();
}
xhr = $.ajax({
url: 'ajax.php',
type: 'post',
data: 'ACTION=SEARCH&search='+$('#search input[name=\'search\']').val(),
dataType: 'json',
beforeSend: function() {
$('#loader-icon').show();
},
complete: function() {
$('#loader-icon').hide();
},
success: function(json) {
//$('.product-list-row').html(json);
$('#search-listing').html(json['html']);
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
}
});
答案 1 :(得分:1)
正确的解决方案是两者的结合,中止运行请求,如果应该进行新的请求,还要解决新请求的触发问题。您可以使用下划线库,它具有很好的功能,称为 debounce (请参阅http://underscorejs.org/#debounce),您的代码应如下所示:
// This is your xhr, each request save into this
// variable, in order to be able to abort it if needed
var xhr;
// Wrap your event handler using the debounce function
$("#search").on("keyup", _.debounce(function(e) {
// Abort running request
if(xhr) {
xhr.abort();
xhr = null;
}
// Store the new request
xhr = $.ajax({
// Search for the term $(this).val()
});
},500));
无需触发每个键盘的搜索,但只有当用户停止键入时 - debounce才能为您完成。如果要求提出请求,则无需处理以前的结果。