Pregunta

Tengo algunos cuadros de texto en una página y quiero hacer clic en un enlace cuando el usuario presiona Enter en cualquiera de ellos.

Puedo atrapar fácilmente el botón enter usando javascript (buscando 13 en event.keyCode y event.which ), pero encontré un problema cuando el navegador se completa automáticamente la función se activa y sugiere lo que el usuario podría escribir. Estamos descubriendo que los usuarios a menudo presionan Intro para aceptar la sugerencia del navegador, en lugar de la pestaña. Esto confunde a los usuarios cuando se hace clic en el enlace de inmediato, mientras que todavía tenían la intención de ingresar texto en algunos de los otros campos.

Sé que sería mejor usar un formulario y un botón de enviar aquí, pero por varias razones eso no es práctico.

Estoy usando jQuery, así que siéntete libre de ofrecer soluciones jQuery.

¿Fue útil?

Solución

El usuario siempre tiene que presionar la tecla hacia abajo si elige seleccionar uno de los textos de autocompletar a la derecha, ¿por qué no establecer una variable en algo cuando presiona la tecla hacia abajo? variable. No debe hacer la función de hacer clic en el enlace si la variable está configurada; de lo contrario, hágalo normalmente.

Otros consejos

Utilizando la idea de tuanvt en la respuesta aceptada, escribí un complemento jQuery que hace el trabajo.

Rastreo cuando el usuario presiona las teclas arriba, abajo, página arriba y página abajo para saber cuándo están en el cuadro de autocompletar. Todas las demás claves implican que lo han dejado.

Me aseguro de que solo apliquemos estas reglas a los cuadros de texto: todos los demás elementos de entrada se comportan normalmente.

Opera ya hace un trabajo bastante bueno de lo que estaba tratando de lograr, por lo que no hago cumplir mis reglas en ese navegador; de lo contrario, el usuario tendría que presionar enter dos veces.

Probado en IE6, IE7, IE8, Firefox 3.5.5, Google Chrome 3.0, Safari 4.0.4, Opera 10.00.

Está disponible en jquery.com como complemento SafeEnter . Para su comodidad, el código para la versión 1.0 es el siguiente:

// 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);

Intente desactivar el autocompletado en su casilla de verificación, aunque esto no es estándar para todos los navegadores, pero funciona en los navegadores comunes.

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

JQuery es agradable y todo pero ¿por qué no usar JavaScript simple?

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;
    }
}

rastrea la tecla enter en el evento keyup, la selección se completa cuando detecta la tecla enter en el evento keyup.

detectar la tecla enter al presionar la tecla y hacer que la operación interfiera con la funcionalidad de autocompletar.

Esto funciona para mí:

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

Si está utilizando los nuevos tipos de campo de formulario html5, puede modificar el código de teedyay de la siguiente manera:

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)
                    {
                        ...

Tenga en cuenta los nuevos tipos de entrada.

No estoy seguro de si está presionando teclas en la ventana o en elementos DOM específicos. Debe hacer lo último (por ejemplo, en el elemento form ), luego, en su controlador de eventos, mire el objeto del evento para determinar qué elemento DOM fue el origen del evento. Si este fue un campo de texto con autocompletar, entonces return false; .

Eche un vistazo a .keypress () controlador de eventos y el event.target propiedad del objeto de evento.

Me enfrenté al mismo problema y, aunque no era perfecto, utilicé otro enfoque que considero más simple. Al crear el autocompletado, configuro la hora actual para el evento seleccionado y luego lo comparo antes de realizar cualquier acción:

$('#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>

Otro enfoque (más seguro) es utilizar los eventos keyup y keydown para detectar cambios de valor.

Autocompletar establece el valor después de el evento keyDown . Cuando se observan ambos eventos, lo siguiente es mucho más confiable que las otras soluciones:

var tempValue;
// fire when enter is 1. pressed and 2. released
function handlerEnter(type){
     // save the value for comparison
     if(type == 'keyDown'){
         tempValue = document.activeElement.value;
         return null; // quit
     }

     // quit when the value changed in between keyDown & keyUp
     if(type == 'keyUp' && tempValue != document.activeElement.value){
         return null;
     }

     // autocomplete wasn't used
     doStuff();
}

Es posible que desee comprobar si document.activeElement es una entrada. Siéntase libre de usar mi extensión de prototipo malvado .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top