2011-05-23 10 views
5

Ho il codice jQuery che crea una serie di elementi focalizzabili e associa .keydown per le frecce sinistra e destra per sfogliarli. In Chrome, IE e Safari che iniziano con preventDefault() o terminano con un falso return (che tecnicamente non desidero utilizzare perché non ho bisogno di stopPropagation()) impedisce l'evento predefinito delle frecce, ma in Firefox no.Previene l'evento di default per il keydown jQuery in Firefox

Come è possibile impedire l'azione predefinita anche in Firefox?

Ecco il codice, che funziona come previsto, tranne in Firefox, in cui viene attivato l'evento predefinito oltre alla mia richiamata.

$(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(); 
      } 
     }); 
    }); 
}); 

risposta

7

L'evento keypress è quello che dovrebbe essere annullato, ma Firefox ignora preventDefault() in questo scenario. Quindi la soluzione è sfocare il menu a discesa corrente, lasciare che l'evento keypress venga attivato sul documento e impostare lo stato attivo sul nuovo menu a discesa tramite timeout.

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 a http://jsfiddle.net/roberkules/3vA53/

+0

Questo non funziona per me Forse il motivo per cui questo funziona per il tuo codice è perché sei utilizzando le caselle di testo di input, mentre sto navigando principalmente nelle caselle di riepilogo verso il basso.Quando si passa alla casella a discesa successiva, il valore dell'elenco appena attivato si modifica al valore successivo. – Brandon

+0

Vedo, una volta che jsfiddle è tornato online Dare un'occhiata – roberkules

+0

Ho aggiunto il mio codice nell'OP – Brandon

0

Hai provato questo?

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

Sì, non funziona per Firefox. :( – Brandon

+0

@Brandon [vedi questo] (http://stackoverflow.com/a/31206759/1185136) per il supporto di Firefox –

Problemi correlati