There is code written by me that works, but does not perform one function correctly. Help me figure out why.

Code:

$(document).ready(function(){ var timer = null; $('#searchword').keydown(function(e){ if( e.keyCode ==38 ){ if( $('#search_suggestion_holder').is(':visible') ){ if( ! $('.selected').is(':visible') ){ $('#search_suggestion_holder li').last().addClass('selected'); }else{ var i = $('#search_suggestion_holder li').index($('#search_suggestion_holder li.selected')) ; $('#search_suggestion_holder li.selected').removeClass('selected'); i--; $('#search_suggestion_holder li:eq('+i+')').addClass('selected'); } } }else if(e.keyCode ==40){ if( $('#search_suggestion_holder').is(':visible') ){ if( ! $('.selected').is(':visible') ){ $('#search_suggestion_holder li').first().addClass('selected'); }else{ var i = $('#search_suggestion_holder li').index($('#search_suggestion_holder li.selected')) ; $('#search_suggestion_holder li.selected').removeClass('selected'); i++; $('#search_suggestion_holder li:eq('+i+')').addClass('selected'); } } }else if(e.keyCode ==13){ if( $('.selected').is(':visible') ){ var value = $('.selected').text(); $('#searchword').val(value); $('#search_suggestion_holder').hide(); $('#search_suggestion_holder li').detach(); $('div.ui-tooltip').detach(); sendsearch() } } }); $('#searchword').bind('textchange', function (event, numberkey) { var keyword = $(this).val() //console.log("это:" + keyword) if(keyword.length > 3) { $('#loader').show(); setTimeout( function(){ var d = [] $('#search_suggestion_holder li').detach(); $('div.ui-tooltip').detach(); $.ajax({ url:'auto-complete.php', data:'keyword='+keyword, dataType:'json', error: function(jqXHR, textStatus, errorThrown) { alert('ошибка, F12'); console.log('jqXHR:'); console.log(jqXHR); console.log('статус:'); console.log(textStatus); console.log('ошибка:'); console.log(errorThrown); }, success: function(d){ //console.log($.isEmptyObject(d)); if (!! $.isEmptyObject(d)){ //console.log("1") var nafin = '<li class="hover-img">Нечего не найдено</li>' $("#search_suggestion_holder").html(nafin) $('#search_suggestion_holder').show(); $('#loader').hide(); } else { //console.log("2") $.each(d, function(i, val) { //console.log(val.icon + val.value); //console.log(i); var descrmin = val.descr.substr(0, 150); //console.log(descrmin) var hoverimg = "img-hover=\"<img src=/shop/medium/" + val.icon+"> <br> "+ descrmin + "\"" var resultat = '<li class="hover-img" title ' + hoverimg + '><img src="/shop/32x32/' + val.icon + '">' + val.value + '</li>' //console.log(resultat) $('#loader').hide(); $(resultat).appendTo("#search_suggestion_holder") //console.log($("#search_suggestion_holder").html()); $('#search_suggestion_holder').show(); $(".hover-img").tooltip({ content: function (event, ui) { return $(this).attr('img-hover'); }, track: true, }); }) } } }); },1500); } else if(keyword.length < 1){ $('#search_suggestion_holder li').detach(); $('div.ui-tooltip').detach(); $('#search_suggestion_holder').hide(); var newwrite = '<li class="hover-img">начните вводить</li>' //console.log(newwrite) $("#search_suggestion_holder").html(newwrite) $('#search_suggestion_holder').show(); $('#loader').hide(); } else if(1 > keyword.length < 3){ $('#loader').show(); $('#search_suggestion_holder li').detach(); $('div.ui-tooltip').detach(); $('#search_suggestion_holder').hide(); var min3 = '<li class="hover-img">Введите больше 3 символов</li>' //console.log(min3) $("#search_suggestion_holder").html(min3) $('#search_suggestion_holder').show(); $('#loader').hide(); //console.log($("#search_suggestion_holder").html()); } }) $('#search_suggestion_holder').on('click','li',function(){ var value = $(this).text(); $('#searchword').val(value); $('#search_suggestion_holder').hide(); $('#search_suggestion_holder li').detach(); $('div.ui-tooltip').detach(); sendsearch() }) function sendsearch() { $("#searchnow").click(); } }); 

It has setTimeout( function(){ , which logically wraps the entire function of a request to a PHP script and slows down its execution by 1500 мс . The logic is that if a person types quickly, it will not be called, but in fact it works every time change of letters and then overfilled many times after the word was quickly typed. What is wrong?

  • I advise you to assign $('#search_suggestion_holder') variable at the very beginning of the code and rewrite the code using it. "gossiness" will noticeably decrease :) - tutankhamun

1 answer 1

If setTimeout has already been called, but has not yet fired, do not call it. Well, get the keyword again inside the function submitted to setTimeout .

 var timeout = null; $('#searchword').bind('textchange', function (event, numberkey) { var keyword = $(this).val(); if (keyword.length > 3 && timeout == null) { $('#loader').show(); timeout = setTimeout(function() { timeout = null; var keyword1 = $('#searchword').val(); ... $.ajax({ url:'auto-complete.php', data:'keyword='+keyword1, ... 
  • damn something is not at all unclear, where did keyword1 come from and why? is it possible to describe the answer in more detail - Alexey Vasilyev
  • keyword1 is a local variable inside an anonymous function given in setTimeout and reflecting the value of $('#searchword').val() at the time of shooting setTimeout . If they type quickly, keyword and keyword1 may be different. - Igor
  • You can please fully see an example, but I cannot understand for sure that everything is just a keyword or only keyword1 - Alexey Vasilyev
  • Sorry, I will not copy all your code. Let's tense up. The keyword variable contains the text from '#searchword' at the time the textchange event handler is executed (this is not a standard jQuery event, do you use some kind of plugin?). The keyword1 variable contains the text from '#searchword' at the time the timeout event handler is executed. These two values ​​may be different. What exactly is incomprehensible to you? - Igor
  • You correctly understood, there is a plugin, since standard jquery tools cannot track input changes directly but only by blur , the plugin solves it, But I don’t understand why functionout first goes to the variable timeout = setTimeout(function() { and then cancels it timeout = null; - Alexey Vasilyev