Problem with settimeout in jQuery with AJAX call
I'm using jQuery AJAX call to dynamically display search results when a user types in a specified set of input boxes. This code works fine and is identical to the doSearch function below, except that it binds directly开发者_开发问答 to the "input.auto" keyup event. But I'm trying to improve it by adding a time delay -- otherwise the call gets fired for each keyup event and some of the calls overlap which leads to very confusing results.
Following this question I came up with this code:
$(document).ready(function() {
var searchTimer = 0;
$('input.auto').keyup(function() {
if (searchTimer != 0) {
clearTimeout(searchTimer);
}
var length = $(this).val().length;
searchTimer = setTimeout(doSearch(length), 250);
});
function doSearch(length) {
var length = $(this).val().length;
// check to see if there are more than three characters in the input field
if (length > 3) {
//when user enters text, checks and retrieves matches
$("#messages").hide();
$("#messages").removeClass().addClass('loading').text('loading suggestions').fadeIn();
var type = $(this).attr('id');
switch (type) {
// depending on type, different target urls are set
}
$.post(url,{ term:$(this).val() } ,function(data) {
// if no suggestions are returned
if (data=='No matches') {
$("#messages").fadeTo(200,0.1,function() {
$(this).removeClass().addClass('failure').fadeTo(900,1).html(data);
});
// if suggestions are returned
} else {
$("#messages").removeClass().addClass('success').html(data).animate({height: '250px', opacity:'1'},{queue:false, duration:1500, easing: 'easeOutBounce'});
}
});
}
});
});
Perhaps there is a very simple thing here that I'm missing and it's demonstrating my hazy knowledge of jquery and javascript, but I would appreciate any pointers. (Also, if somebody could explain what "searchtimer" does in this syntax, that would be great as well.)
the first arg to setTimeout
is a function pointer but you're giving the result of the call to doSearch
, change it to:
setTimeout(doSearch, 250);
and in doSearch
, remove the length
arg, as it's overridden by the local length
var:
function doSearch() {
var length = $(this).val().length;
// check to see if there are more than three characters in the input field
...
searchTimer
is an id
for the timeout you fired. It's used to clear it later:
if (searchTimer != 0) {
clearTimeout(searchTimer);
}
this means that you can fire many timeOuts and keep trac of them one by one.
Update:
$(this)
in var length = $(this).val().length
will refer to the window object
not the curent input
. You have to capture the input element
and then pass it to the doSearch function
:
$('input.auto').keyup(function() {
if (searchTimer != 0) {
clearTimeout(searchTimer);
}
searchTimer = setTimeout(doSearch(this), 250);
});
replace doSearch
by this one (and any use of $(this)
in the function by $(input)
):
function doSearch(input){
return function(){
searchTimer = 0;
var length = $(input).val().length
...
}
}
精彩评论