2011-04-13 17 views
16

Estoy usando el autocompletado de jquery ui y quiero descifrar entre los eventos de foco desencadenados por la interacción del teclado y la interacción del mouse. ¿Cómo voy a hacer esto?Diferenciar entre evento de foco activado por teclado/mouse

$('input').autocomplete({ 
    source: function(request, response) { 
     ... 
    }, 
    focus: function(event, ui) { 
     // If focus triggered by keyboard interaction 
      alert('do something'); 
     // If focus event triggered by mouse interaction 
      alert('do something else'); 
    } 
}); 

Gracias

+1

Bueno, la única manera que conozco de enfocarme con un mouse es el evento 'click', pero cómo reconocer el foco del teclado: buena pregunta. Asumo que verificar la tecla presionada (¿TAB solamente?) Sería la idea correcta, pero no estoy muy seguro. Tal vez comprobar si 'clic' se activó en' focus() '? No estoy seguro de cómo hacer esto en la parte superior de mi cabeza, pero tal vez esto ayudará a alguien que quiera dar un vistazo a esto. –

+0

Las dos cosas que trato de segregar son, en realidad, utilizar las teclas de flecha para mover hacia abajo/arriba la lista de autocompletar, y pasar el mouse sobre los elementos de la lista de autocompletar. La autocompleta de UI maneja los clics del mouse seleccionando el elemento y cerrando el autocompletado, tomando un parámetro de selección por separado. –

Respuesta

4

La única manera que puedo pensar en hacer esto es tener un manejador de escuchar la keypress y click eventos, y alternar un indicador booleano de encendido/apagado. Luego, en el controlador focus de su entrada, puede verificar cuál es el valor de su bandera e ir desde allí.

Probablemente algo así como

var isClick; 
$(document).bind('click', function() { isClick = true; }) 
      .bind('keypress', function() { isClick = false; }) 
      ; 

var focusHandler = function() { 
    if (isClick) { 
     // clicky! 
    } else { 
     // tabby! 
    } 
} 

$('input').focus(function() { 
    // we set a small timeout to let the click/keypress event to trigger 
    // and update our boolean 
    setTimeout(focusHandler,100); 
}); 

Instigó un pequeño prototipo de trabajo en jsFiddle (no te encanta este sitio?). Check it out if you want.

Por supuesto, todo esto es corriendo un evento focus en una <input>, pero el manejador focus en el autocompletar funciona de la misma manera.

El setTimeout introducirá un poco de retraso, pero en 100 ms, podría ser insignificante, en función de sus necesidades.

+0

También es una gran idea, pero en realidad no estoy buscando clics, sino para el vuelo estacionario:) –

+0

En ese caso, no debería ser demasiado difícil cambiar el controlador 'click' para un' hover' (o mejor aún) Creo, un controlador 'mousein'). Déjame ver si puedo avivar algo por un tiempo. : D –

+0

setTimeout para el controlador de enfoque. Gran idea. –

0

La primera cosa que viene a la mente es que se puede encontrar la posición del ratón y comprobar para ver si su uso dentro de la posición del elemento

esto para almacenar el posición del elemento:

var input = $('#your_autocompleted_element_id'), 
    offset = input.offset(), 
    input_x = offset.top, 
    input_y = offset.left, 
    input_w = input.outerWidth(), 
    input_h = input.outerHeight(); 

a continuación, utilice esto para encontrar la posición absoluta del ratón dentro de la ventana:

var cur_mx, cur_my; 
$(document).mousemove(function(e){ 
    cur_mx = e.pageX; 
    cur_my = e.pageY; 
}); 

Luego, en la configuración de su autcomplete:

focus: function(event, ui) { 
    // mouse is doing the focus when... 
    // mouse x is greater than input x and less than input x + input width 
    // and y is greater than input y and less than input y + input height 
    if (cur_mx >= input_x && cur_mx <= input_x + input_w && cur_my >= input_y && cur_my <= input_y + input_h) { 
     // do your silly mouse focus witchcraft here 
    } else { 
     // keyboard time! 
    } 
} 
+1

... pero siempre existe la posibilidad de que el cursor del mouse esté sobre el elemento simplemente enfocado durante una pulsación de tecla tab. : p –

+0

Sí, esta es una gran idea. Pero como RIchard señala, no funcionaría si el mouse se ubicara sobre el área de autocompletar. +1 por esfuerzo! –

4

Debería poder determinar esto desde el evento-Objeto que se pasa al evento de foco. Dependiendo de la estructura de su código, esto podría ser diferente, pero generalmente hay una propiedad llamada originalEvent, que podría estar anidada a cierta profundidad. Examine el event -objeto más de cerca para determinar la sintaxis correcta. Luego prueba en mousenter o keydown a través de la expresión regular. Algo como esto:

focus: function(event, ui){ 
    if(/^key/.test(event.originalEvent.originalEvent.type)){ 
    //code for keydown 
    }else{ 
    //code for mouseenter and any other event 
    } 
} 
+2

'event.originalEvent.originalEvent.type' me da' No se puede leer la propiedad 'tipo' de indefinido' en Chrome v34 – poshest

+1

El problema es que '' 'originalEvent''' no está normalizado en todos los navegadores AFAIK – Andrey

2

La forma más fácil y más elegante que he encontrado de lograr esto es utilizar la biblioteca "What Input?". Es pequeño (~ 2K minified), y le da acceso al tipo de evento tanto en las secuencias de comandos:

if (whatInput.ask() === 'mouse') { 
    // do something 
} 

... y también (a través de un único atributo dato que se suma a los documentos body) estilos:

[data-whatinput="mouse"] :focus, 
[data-whatinput="touch"] :focus { 
    // focus styles for mouse and touch only 
} 

Me gusta especialmente el hecho de que si solo desea un comportamiento visual diferente para mouse/teclado, puede hacerlo en la hoja de estilo (donde realmente pertenece) en lugar de hacerlo mediante algún jacky de JavaScript (aunque, por supuesto, si necesita hacer algo que no sea puramente visual, el enfoque anterior le permite manejarlo en Javascript en su lugar).

Cuestiones relacionadas