Recomendaría echar un vistazo al widget de autocompletar jQuery UI. Manejaron la mayoría de los casos allí, ya que su base de código es más madura que la mayoría de los existentes.
A continuación hay un enlace a una página de demostración para que pueda verificar que funciona. http://jqueryui.com/demos/autocomplete/#default
Obtendrá el mayor beneficio al leer la fuente y ver cómo la resolvieron. Puede encontrarlo aquí: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js .
Básicamente lo hacen todo, se unen input, keydown, keyup, keypress, focus and blur
. Luego tienen un manejo especial para todo tipo de claves como page up, page down, up arrow key and down arrow key
. Se usa un temporizador antes de obtener el contenido del cuadro de texto. Cuando un usuario escribe una tecla que no corresponde a un comando (tecla arriba, tecla abajo, etc.) hay un temporizador que explora el contenido después de aproximadamente 300 milisegundos. Se ve así en el 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 );
},
La razón para usar un temporizador es para que la IU tenga la oportunidad de actualizarse. Cuando se ejecuta Javascript, la IU no se puede actualizar, por lo tanto, la llamada a la función de retraso. Esto funciona bien para otras situaciones, como mantener el foco en el cuadro de texto (utilizado por ese código).
Por lo tanto, puede usar el widget o copiar el código en su propio widget si no está utilizando jQuery UI (o en mi caso, desarrollando un widget personalizado).