Intrappola il tasto Invio, ma non quando scegli il suggerimento di completamento automatico del browser

StackOverflow https://stackoverflow.com/questions/1648993

  •  22-07-2019
  •  | 
  •  

Domanda

Ho alcune caselle di testo su una pagina e voglio fare clic su un collegamento quando l'utente preme invio in una di esse.

Posso facilmente intercettare il pulsante di invio usando javascript (cercando 13 in event.keyCode e event.which ), ma ho riscontrato un problema quando il completamento automatico del browser entra in funzione e suggerisce ciò che l'utente potrebbe voler digitare. Stiamo trovando che gli utenti spesso premono Invio per accettare il suggerimento del browser, anziché la scheda. Questo confonde gli utenti quando si fa clic immediatamente sul collegamento, mentre intendono comunque inserire il testo in alcuni degli altri campi.

So che sarebbe meglio usare un modulo e un pulsante di invio qui, ma per vari motivi non è pratico.

Sto usando jQuery, quindi sentiti libero di offrire soluzioni jQuery.

È stato utile?

Soluzione

L'utente deve sempre premere il tasto Giù se sceglie di selezionare uno dei testi di completamento automatico a destra, perché non impostare una variabile su qualcosa quando premono il tasto Giù, e quindi se fanno l'invio premere dopo si controlla il variabile. Non dovresti fare la funzione click link se la variabile è impostata, altrimenti fallo normalmente.

Altri suggerimenti

Usando l'idea di tuanvt nella risposta accettata, ho scritto un plugin jQuery che fa il lavoro.

Traccia quando l'utente preme i tasti su, giù, pagina su e pagina giù per dire quando sono nella casella di completamento automatico. Tutte le altre chiavi implicano che l'hanno lasciato.

Mi assicuro di applicare queste regole solo alle caselle di testo: tutti gli altri elementi di input si comportano normalmente.

Opera fa già un ottimo lavoro su ciò che stavo cercando di ottenere, quindi non impongo le mie regole in quel browser, altrimenti l'utente dovrebbe premere Invio due volte.

Testato su IE6, IE7, IE8, Firefox 3.5.5, Google Chrome 3.0, Safari 4.0.4, Opera 10.00.

È disponibile su jquery.com come plugin SafeEnter . Per comodità, il codice per la versione 1.0 è il seguente:

// jQuery plugin: SafeEnter 1.0
// http://plugins.jquery.com/project/SafeEnter
// by teedyay
//
// Fires an event when the user presses Enter, but not whilst they're in the browser's autocomplete suggestions

//codesnippet:2e23681e-c3a9-46ce-be93-48cc3aba2c73
(function($)
{
    $.fn.listenForEnter = function()
    {
        return this.each(function()
        {
            $(this).focus(function()
            {
                $(this).data('safeEnter_InAutocomplete', false);
            });
            $(this).keypress(function(e)
            {
                var key = (e.keyCode ? e.keyCode : e.which);
                switch (key)
                {
                    case 13:
                        // Fire the event if:
                        //   - we're not currently in the browser's Autocomplete, or
                        //   - this isn't a textbox, or
                        //   - this is Opera (which provides its own protection)
                        if (!$(this).data('safeEnter_InAutocomplete') || !$(this).is('input[type=text]') || $.browser.opera)
                        {
                            $(this).trigger('pressedEnter', e);
                        }
                        $(this).data('safeEnter_InAutocomplete', false);
                        break;

                    case 40:
                    case 38:
                    case 34:
                    case 33:
                        // down=40,up=38,pgdn=34,pgup=33
                        $(this).data('safeEnter_InAutocomplete', true);
                        break;

                    default:
                        $(this).data('safeEnter_InAutocomplete', false);
                        break;
                }
            });
        });
    };

    $.fn.clickOnEnter = function(target)
    {
        return this.each(function()
        {
            $(this)
                .listenForEnter()
                .bind('pressedEnter', function()
                {
                    $(target).click();
                });
        });
    };
})(jQuery);

Prova a disattivare il completamento automatico nella casella di controllo, anche se questo non è standard per tutti i browser ma funziona sui browser comuni.

<input type="text" autocomplete="off" />

JQuery è carino e tutto, ma perché non usare JavaScript semplice?

function submit_on_enter(e) {
    var keycode;
    if (window.event) keycode = window.event.keyCode;
    else if (e) keycode = (e.keyCode ? e.keyCode : e.which);
    else return true;

    if (keycode == 13) {
        if (window.previousKeyCode) {
            // down=40,up=38,pgdn=34,pgup=33
            if (window.previousKeyCode == 33 || window.previousKeyCode == 34 ||
                window.previousKeyCode == 39 || window.previousKeyCode == 40) {
                    window.previousKeyCode = keycode;
                    return true;
            }
        }
        submit_form();
        return false;
    } else {
        window.previousKeyCode = keycode;
        return true;
    }
}

rintraccia il tasto invio sull'evento keyup, la selezione è completata dal momento in cui rilevi il tasto invio sull'evento keyup.

il rilevamento del tasto Invio sul keydown e l'operazione interferiscono con la funzionalità di completamento automatico.

Questo funziona per me:

$('input').keypress(function(e) {
    if(e.which == 13) {
        if(this.value)
        {
            $("#submitbutton").click();
        }
    }
});

Se stai usando i nuovi tipi di campi del modulo html5, potresti voler modificare il codice di teedyay come segue:

case 13:
                    // Fire the event if:
                    //   - we're not currently in the browser's Autocomplete, or
                    //   - this isn't a textbox, or
                    //   - this is Opera (which provides its own protection)
                    if (!$(this).data('safeEnter_InAutocomplete') || !$(this).is('input([type=text],[type=email],[type=number],[type=search],[type=tel],[type=url])') || $.browser.opera)
                    {
                        ...

Nota i nuovi tipi di input.

Non sono sicuro se intrappoli le pressioni dei tasti sulla finestra o su elementi DOM specifici. Dovresti fare quest'ultimo (ad es. Sull'elemento form ), quindi nel gestore dell'evento, cerca nell'oggetto evento per determinare quale elemento DOM è stato l'origine dell'evento. Se si trattava di un campo di testo con completamento automatico, restituisce false; .

Dai un'occhiata a .keypress () gestore eventi e event.target proprietà dell'oggetto evento.

Ho affrontato lo stesso problema e, sebbene non perfetto, ho usato un altro approccio che considero più semplice. Durante la creazione del completamento automatico ho impostato l'ora corrente per l'evento select e poi lo ho confrontato prima di intraprendere qualsiasi azione:

$('#completer').autocomplete({
  source: ['First', 'Last'], delay: 0, minLength: 0,
  select: function(ev, ui) {
    $(ev.target).data('lastAutocompleteSelectTimestamp', new Date().getTime())
  }
})

$(document).on('keydown', '#completer', function(ev){
  if (ev.which != 13) return
  var lastAutocompletionTime = $(ev.currentTarget).data('lastAutocompleteSelectTimestamp')
  if (!lastAutocompletionTime || (new Date().getTime() - lastAutocompletionTime) > 100)
    alert('Enter pressed outside autocomplete context')
})
<html>
<head>
  <link href="https://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script src="https://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>
</head>
<body>
  <input id=completer type=text />
</body>
</html>

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top