2011-02-03 17 views
11

Estoy tratando de determinar el flujo de trabajo para ajustar una aplicación web de entrada de datos. Imaginar varias formas de direcciones en una sola página web:jQuery entrega de enfoque y haga clic en un elemento

1. Name___________ 
    Street_________ 
    Phone__________ 

    2. Name___________ 
    Street_________ 
    Phone__________ 

    [...many more...] 

Ahora me gustaría saber si el usuario está utilizando la tecla de tabulación para llegar al segundo campo "Nombre" (o en cualquier lugar dentro de ese registro), o si están usando el mouse para hacer clic en él. (O Shift-Tab para moverse a la inversa.)

He configurado un manejador en el enfoque y haga clic en los campos de entrada:

$('input').click(function() { TabulateClick(this) }); 
$('input').focus(function() { TabulateFocus(this) }); 

Y en el controlador, que determina la dirección que el usuario es trabajando y si hemos "cambiado" los registros de direcciones. (Si la atención se centró en "Teléfono" para la primera dirección y hace clic en el campo "Nombre" en el misma dirección, eso no es realmente cambiar los registros, así que no tabule eso.)

function TabulateClick(field) 
    { 
     var currentAddressRecord = FindAddress(field); 
     if (lastAddressRecord != currentAddressRecord) 
      switchedAddressesWithClick++; 
     lastAddressRecord = currentAddress; 
    } 
    function TabulateFocus(field) 
    { 
     var currentAddress = FindAddress(field); 
     if (lastAddressRecord != currentAddressRecord) 
      switchedAddressesWithTab++; 
     lastAddressRecord = currentAddress; 
    } 

Mi problema es que cuando hago clic con el mouse en el campo, el evento focus se activa tabulando primero un switchedAddressesWithTab falso y cambiando la dirección actual (mala). Cuando se ejecuta el controlador click, el lastAddressRecord está dañado.

¿Hay alguna manera dentro del controlador focus para saber que hay un evento click pendiente en el mismo objeto? ¿O en el controlador click para saber que anteriormente solo lo manejaba focus?

Respuesta

15

Aquí es algo que creo que funciona basado en el hecho de que el mousedown ocurre antes de la concentración. Ver demo.

var lastClick = null; 
$('input').mousedown(function(e) { 
    lastClick = e.target; 
}).focus(function(e){ 
    if (e.target == lastClick) { 
     console.log('click'); 
    } else { 
     console.log('tab');  
    } 
    lastClick = null; 

}); 

Para solucionar el error descubierto por Josiah, cambié mi código a continuación. Ver demo.

var lastFocusedElement = null; 
var isClick = false; 
$('input').mousedown(function(e) {  
    isClick= true; 
}).focus(function(e){ 

    // To prevent focus firing when element already had focus 
    if (lastFocusedElement != e.target) { 
     if (isClick) { 
      console.log('click ----'); 
     } else { 
      console.log('tab -----');  
     } 
     lastFocusedElement = e.target; 
     isClick = false; 
    } 
}); 

$(document.body).focus(function(){ 
    lastFocusedElement = document.body; 
}); 

El único problema es que no obtienes 'clic' o pestaña cuando te alejas de la ventana y vuelves atrás. Obtienes un evento de enfoque en la entrada que tuvo el foco, pero no puedes determinar si es una pestaña o un clic, porque no es ninguno.

Creo que esto es lo más cercano que obtendrá, lo probaría en su página y veré si el comportamiento es lo suficientemente bueno.

+0

@Juan - ya que estamos en control de calidad hoy, cuando recorre todos los campos del cuerpo, haga clic en uno de los registros de la consola haga clic en, pestaña –

+0

@Josiah: Buena captura, no entiendo por qué está sucediendo sin embargo .. Supongo que proporcionamos el OP de dos maneras que funcionan la mayor parte del tiempo, aún invirtiendo otros 2 minutos en esto, aunque –

+0

@Juan-yah, gracias por convencerme de pasar mucho más tiempo de lo que esperaba en esta pregunta;) ¿qué podemos hacer? do, dang desarrolladores. –

0

Simplemente enlace el foco y luego verifique el evento para ver si e.which == 9 // tab.

Mi idea original no funcionó (gracias @Juan). Usar la combinación de eventos debería llevarte a donde quieres estar. Si el usuario hace clic en el cuadro de texto, la última vez que presiona la tecla no será una pestaña. Todas las entradas están mirando y almacenando el último código de tecla para pasar al evento de enfoque. here is the fiddle

var lastKeyCode = 0; 
$('input').focus(function(e) { 
    if(lastKeyCode == 9) 
     // tabbed into field 
    else 
     // clicked into field 
}).keydown(function(e){ 
    if(e.which == 9) // added timeout to clear lastkeypress 
     setTimeout(function(){lastKeyPress = 0}, 50); 
    lastKeyPress = e.which; // store last key code 
}); 
+0

mmm, muy interesante, ¿está probado? –

+0

@Josiah: No creo que esto funcione: en FF me vuelvo indefinido incluso si me meto en el campo. –

+0

No funciona: http://jsfiddle.net/3py9V/. Si sugiere algo que no se ha probado, debe mencionar que su respuesta es una sugerencia no probada –

2

Puede usar el método .on() en jQuery. Aquí hay otra forma de enlazar ambos eventos en el mismo elemento.

var hasClicked = false; 
$('.myinputfield').on('mousedown : click',function(e){ 
    if (e.type == 'mousedown') { 
     // execute code 
     hasClicked = true; 
    } 
    if(e.type == 'focus' && !hasClicked) { 
     //execute code 
     console.log(e.type) 
    } 
    hasClicked = false; 
}); 
Cuestiones relacionadas