2011-05-23 11 views
5

Tengo un código jQuery que crea una matriz de elementos enfocables y enlaza .keydown para las flechas izquierda y derecha para desplazarse por ellos. En Chrome, IE y Safari comenzando con preventDefault() o terminando con un retorno falso (que técnicamente no quiero usar porque no necesito stopPropagation()) previene el evento predeterminado de las flechas, pero en Firefox no lo hace.Prevenir el evento predeterminado para la combinación de teclas de jQuery en Firefox

¿Cómo puedo evitar la acción predeterminada en Firefox también?

Aquí está el código, que funciona como se esperaba, excepto en Firefox, donde el evento predeterminado se dispara además de mi devolución de llamada.

$(function() { 
    var focusables = $(":focusable"); 
    focusables.eq(0).focus(); 
    focusables.eq(0).select(); 
    focusables.each(function() { 
     $(this).keydown(function (e) { 
      if (e.which == '37') { // left-arrow 
       e.preventDefault(); 
       var current = focusables.index(this), 
        next = focusables.eq(current - 1).length ? focusables.eq(current - 1) : focusables.eq(0); 
       next.focus(); 
       next.select(); 
      } 
      if (e.which == '39') { // right-arrow 
       e.preventDefault(); 
       var current = focusables.index(this), 
        next = focusables.eq(current + 1).length ? focusables.eq(current + 1) : focusables.eq(0); 
       next.focus(); 
       next.select(); 
      } 
     }); 
    }); 
}); 

Respuesta

7

El evento de pulsación de tecla es el que debería cancelarse, pero Firefox ignora preventDefault() en este escenario. Así que la solución es difuminar el menú desplegable actual, dejar que el evento de pulsación de tecla se active en el documento y establecer el foco en el nuevo menú desplegable a través del tiempo de espera.

var focusables = $(":focusable"); 
focusables.eq(0).focus().select(); 
focusables.each(function() { 
    $(this).keydown(function (e) { 
     if (e.which == '37') { // left-arrow 
      e.preventDefault(); 
      var current = focusables.index(this), 
       next = focusables.eq(current - 1).length ? focusables.eq(current - 1) : focusables.eq(0); 
      this.blur(); 
      setTimeout(function() { next.focus().select(); }, 50); 
     } 
     if (e.which == '39') { // right-arrow 
      e.preventDefault(); 
      var current = focusables.index(this), 
       next = focusables.eq(current + 1).length ? focusables.eq(current + 1) : focusables.eq(0); 
      this.blur(); 
      setTimeout(function() { next.focus().select(); }, 50); 
     } 
    }); 
}); 

demo en http://jsfiddle.net/roberkules/3vA53/

+0

Esto no funciona para mí. Quizás la razón por la que esto está funcionando para tu código es porque eres usando cuadros de texto de entrada, mientras que principalmente navego por los cuadros desplegables. Cuando navego al siguiente cuadro desplegable, el valor de la lista recién enfocada cambia al siguiente valor. – Brandon

+0

Veo, una vez que jsfiddle está de vuelta en línea voy a echar un vistazo. – roberkules

+0

He añadido mi código en el OP. – Brandon

0

Has probado esto?

$(selector).click(function(event) { 
    event.preventDefault(); 
}); 
+2

Sí, no funciona para Firefox. :( – Brandon

+0

@Brandon [mira esto] (http://stackoverflow.com/a/31206759/1185136) para soporte de Firefox. –

Cuestiones relacionadas