0

I have the following kludgey code;

HTML

<input type="search" id="search_box" />
<div id="search_results"></div>

JS

var search_timeout,
    search_xhr;
$("#search_box").bind("textchange", function(){
    clearTimeout(search_timeout); search_xhr.abort();
    search_term = $(this).val();
    search_results = $("#search_results");

    if(search_term == "") {
        if(search_results.is(":visible"))
            search_results.stop().hide("blind", 200);
    } else {
        if(search_results.is(":hidden"))
            search_results.stop().show("blind", 200);
    }

    search_timeout = setTimeout(function () {
        search_xhr = $.post("search.php", {
            q: search_term
        }, function(data){
            search_results.html(data);
        });
    }, 100);
});

(uses the textchange plugin by Zurb)

The problem I had with my original more simple code was that it was horribly unresponsive. Results would appear seconds later, especially when typed slower, or when Backspace was used, etc.

I made all this, and the situation isn't much better. Requests pile up.

My original intention is to use .abort() to cancel out whatever previous request is still running as the textchange event is fired again (as per 446594). This doesn't work, as I get repeated errors like this in console;

Uncaught TypeError: Cannot call method 'abort' of undefined

How can I make .abort() work in my case?

Furthermore, is this approach the best way to fetch 'realtime' search results? Much like Facebook's search bar, which gives results as the user types, and seems to be very quick on its feet.

Community
  • 1
  • 1
Emphram Stavanger
  • 4,158
  • 9
  • 35
  • 63

1 Answers1

1

You'd do well to put a small delay in before sending the request. If the user hits another key within 100ms (or some other time of your choosing) of the last there is no need to send the request in the first place.

When actually sending the request you should check to see if one is already if active. If it is, cancel it.

e.g.

if (search_xhr) {
   search_xhr.abort();
}

don't forget to reset that var on a successful retrieval. e.g. delete search_xhr;

Programming Guy
  • 7,259
  • 11
  • 50
  • 59