title: Jquery: delay 2 seconds before sending json request
body: <p>Below is my script. It's a autosuggestion search script. The problem is that it penetrates the server with a huge amount of requests (it sends a request after each inserted character).</p>
  
  <p>I need to change the script so that it waits 2 seconds after user has finished typing (and has inserted at least 3 characters) and only then sends request to the php file.</p>
  
  <pre><code>(function($){
  $.fn.fsearch = function(){
    var $searchInput = $(this);
    $searchInput.after('&lt;div id="divResult"&gt;&lt;/div&gt;');
    $resultDiv = $('#divResult');
    $searchInput.focus();
    $searchInput.addClass('searchi');
    $resultDiv.html("&lt;ul&gt;&lt;/ul&gt;&lt;div id='search-footer' class='searchf'&gt;&lt;/div&gt;");
    $searchInput.keyup(function(e) {
    var q=$(this).val();
  if(q.length&gt;2&amp;&amp;q.length&lt;30){ 
        var current_index = $('.selected').index(),
        $options = $resultDiv.find('.option'),
        items_total = $options.length;
        $resultDiv.fadeIn();
        $resultDiv.find('#search-footer').html("&lt;img src='img/loader.gif' alt='Searching...'/&gt;");
  
        $.getJSON("/search.php",{searchword: q},function(jsonResult) { 
          var str='';
          for(var i=0; i&lt;jsonResult.length;i++)
            {
              str += '&lt;li id=' + jsonResult[i].uid + ' class="option"&gt;&lt;img class="profile_image" src="photos/'+jsonResult[i].media+'" alt="'+jsonResult[i].username+'"/&gt;&lt;span class="name"&gt;' + jsonResult[i].username + '&lt;/span&gt;&lt;br/&gt;'+jsonResult[i].country+'&lt;/li&gt;';
            }
            $resultDiv.find('ul').empty().prepend(str);
            $resultDiv.find('div#search-footer').text(jsonResult.length + " results found...");
            $resultDiv.find('ul li').first().addClass('selected');
        }); 
  
          $resultDiv.find('ul li').live('mouseover',function(e){
          current_index = $resultDiv.find('ul li').index(this);
          $options = $resultDiv.find('.option');
          change_selection($options,current_index);
        });
  
  
        function change_selection($options,current_index){
          $options.removeClass('selected');
          $options.eq(current_index).addClass('selected');
          }
  
      } else{
  
        $resultDiv.hide();
      }
    });    
  
    jQuery(document).live("click", function(e) { 
      var $clicked = $(e.target);
      if ($clicked.hasClass("searchi") || $clicked.hasClass("searchf")){
      }
      else{
        $resultDiv.fadeOut(); 
      }
    });
  
    $searchInput.click(function(){
      var q=$(this).val();
      if(q.length&gt;2&amp;&amp;q.length&lt;30) { 
        $resultDiv.fadeIn();
      }
    });
  
    $resultDiv.find('li').live("click",function(e){ 
      var id = $(this).attr('id');
      var name = ($(this).find('.name').text());
      $searchInput.val(name);
    });
  
    };
  })(jQuery);
  </code></pre>
  
  <p>After reading <a href="https://stackoverflow.com/questions/4220126/run-javascript-function-when-user-finishes-typing-instead-of-on-key-up">this question</a> I added the following solution to my script:</p>
  
  <pre><code>var timer;
  var x;
  
  $(".some-input").keyup(function () {
      if (x) { x.abort() } // If there is an existing XHR, abort it.
      clearTimeout(timer); // Clear the timer so we don't end up with dupes.
      timer = setTimeout(function() { // assign timer a new timeout 
          x = $.getJSON(...); // run ajax request and store in x variable (so we can cancel)
      }, 2000); // 2000ms delay, tweak for faster/slower
  });
  </code></pre>
  
  <p>unfortunately, it does not work:</p>
  
  <pre><code>TypeError: e.nodeName is undefined jquery-1.11.0.min.js:4:9004
  </code></pre>