Eu recomendaria dar uma olhada no widget de preenchimento automático da UI do jQuery. Eles lidaram com a maioria dos casos lá, já que sua base de código é mais madura do que a maioria dos outros por aí.
Abaixo está um link para uma página de demonstração para que você possa verificar se funciona. http://jqueryui.com/demos/autocomplete/#default
Você obterá o maior benefício ao ler a fonte e ver como eles a resolveram. Você pode encontrá-lo aqui: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js .
Basicamente, eles fazem tudo, se vinculam input, keydown, keyup, keypress, focus and blur
. Então eles têm um tratamento especial para todos os tipos de chaves, como page up, page down, up arrow key and down arrow key
. Um cronômetro é usado antes de obter o conteúdo da caixa de texto. Quando um usuário digita uma chave que não corresponde a um comando (tecla para cima, tecla para baixo e assim por diante), existe um timer que explora o conteúdo após cerca de 300 milissegundos. Parece com isso no código:
// switch statement in the
switch( event.keyCode ) {
//...
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
// when menu is open and has focus
if ( this.menu.active ) {
// #6055 - Opera still allows the keypress to occur
// which causes forms to submit
suppressKeyPress = true;
event.preventDefault();
this.menu.select( event );
}
break;
default:
suppressKeyPressRepeat = true;
// search timeout should be triggered before the input value is changed
this._searchTimeout( event );
break;
}
// ...
// ...
_searchTimeout: function( event ) {
clearTimeout( this.searching );
this.searching = this._delay(function() { // * essentially a warpper for a setTimeout call *
// only search if the value has changed
if ( this.term !== this._value() ) { // * _value is a wrapper to get the value *
this.selectedItem = null;
this.search( null, event );
}
}, this.options.delay );
},
O motivo para usar um timer é para que a interface do usuário tenha a chance de ser atualizada. Quando o Javascript está em execução, a interface do usuário não pode ser atualizada; portanto, a chamada para a função de atraso. Isso funciona bem para outras situações, como manter o foco na caixa de texto (usada por esse código).
Portanto, você pode usar o widget ou copiar o código em seu próprio widget se não estiver usando a interface do usuário do jQuery (ou, no meu caso, desenvolvendo um widget personalizado).