El evento de cambio de Javascript en el elemento de entrada se activa solo al perder el enfoque

84

Tengo un elemento de entrada y quiero seguir verificando la longitud de los contenidos y siempre que la longitud sea igual a un tamaño particular, quiero habilitar el botón de envío, pero estoy enfrentando un problema con el evento onchange de Javascript como evento se activa solo cuando el elemento de entrada sale del alcance y no cuando cambia el contenido.

<input type="text" id="name" onchange="checkLength(this.value)" />

---- onchange no se activa al cambiar el contenido del nombre, sino que solo se activa cuando el nombre se desenfoca.

¿Hay algo que pueda hacer para que este evento funcione en el cambio de contenido? o algún otro evento que pueda usar para esto? Encontré una solución al usar la función onkeyup, pero eso no se activa cuando seleccionamos algún contenido del autocompletado del navegador.

Quiero algo que pueda funcionar cuando el contenido del campo cambie, ya sea con el teclado o con el mouse ... ¿alguna idea?

Sachin Midha
fuente
¿Podrías usar onkeyupy onchange?
James Allardice
1
El único problema que tengo es que la selección del autocompletado del navegador no causaría que ocurriera ninguno de estos eventos.
Sachin Midha
¿Qué tipo de campo de entrada es este?
powtac
oh ... Olvidé agregarlo al código de muestra, es un campo de texto.
Sachin Midha
1
Pensé que este habría sido un problema muy común y mucha gente lo habría enfrentado, pero ahora parece al revés ... :)
Sachin Midha

Respuestas:

120
(function () {
    var oldVal;

    $('#name').on('change textInput input', function () {
        var val = this.value;
        if (val !== oldVal) {
            oldVal = val;
            checkLength(val);
        }
    });
}());

Esto cogerá change, pulsaciones de teclas, paste, textInput, input(cuando esté disponible). Y no disparar más de lo necesario.

http://jsfiddle.net/katspaugh/xqeDj/


Referencias:

textInput- un tipo de evento W3C DOM Nivel 3. http://www.w3.org/TR/DOM-Level-3-Events/#events-textevents

Un agente de usuario debe enviar este evento cuando se hayan ingresado uno o más caracteres. Estos caracteres pueden tener su origen en una variedad de fuentes, por ejemplo, caracteres resultantes de una tecla que se presiona o suelta en un dispositivo de teclado, del procesamiento de un editor de métodos de entrada o de un comando de voz. Cuando una operación de "pegar" genera una secuencia simple de caracteres, es decir, un pasaje de texto sin ninguna estructura o información de estilo, también se debe generar este tipo de evento.

input- un tipo de evento HTML5 .

Se dispara a los controles cuando el usuario cambia el valor

Firefox, Chrome, IE9 y otros navegadores modernos lo admiten.

Este evento ocurre inmediatamente después de la modificación, a diferencia del evento onchange, que ocurre cuando el elemento pierde el foco.

katspaugh
fuente
1
no funciona ... ¿revisaste tu código al final? ¿estaba trabajando en la selección de un autocompletador ...?
Sachin Midha
Revisé textInputChrome 15 y funciona. Comprobé el inputevento en IE9 y también funciona. Firefox debería ser compatible DOMAttrModified, pero no lo tengo instalado. Estos dos eventos son lo mejor que puede esperar, ya que se activan con cualquier tipo de entrada de texto.
katspaugh
1
Impresionante solución ... la entrada funcionó para mí como una bendición ... no se necesita nada más excepto la entrada, eso en sí mismo funciona lo suficiente. funciona en ff4, pero no en 3.x, y tenía 3.6 en mi escritorio y nunca funcionó ...
Sachin Midha
5
En aras de mantener las cosas actualizadas, actualmente esta solución se activa varias veces con un solo cambio de entrada en FF22, no es necesario usar los eventos de pulsación de tecla o entrada de texto, la entrada y el cambio de propiedad deberían ser suficientes
cyber-guard
1
Encontré eso change, keyupy inputera la mejor combinación para cubrir IE9 y Firefox (36.0.4). El keypressevento no pareció funcionar en IE9 porque no capturó cosas como Eliminar y Retroceso, y el inputevento cubre el pegado con el teclado y con el menú contextual.
TLS
9

Como extensión a la respuesta de katspaugh, aquí hay una forma de hacerlo para múltiples elementos usando una clase css.

   $('.myclass').each(function(){
        $(this).attr('oldval',$(this).val());
   });

   $('.myclass').on('change keypress paste focus textInput input',function(){
       var val = $(this).val();
       if(val != $(this).attr('oldval') ){
           $(this).attr('oldval',val); 
           checkLength($(this).val());
        }
    });
SSZero
fuente
4

Me tomó 30 minutos encontrarlo, pero está funcionando en junio de 2019.

<input type="text" id="myInput" oninput="myFunction()">

y si desea agregar un detector de eventos mediante programación en js

inputElement.addEventListener("input", event => {})
franmcod
fuente
3

Hazlo de la manera jQuery:

<input type="text" id="name" name="name"/>


$('#name').keyup(function() {
  alert('Content length has changed to: '+$(this).val().length);
});
Powtac
fuente
1
Esto también solo se disparará cuando el campo pierda focos.
Felix Kling
@Felix Kling, cierto, lo cambió a keyup ();)
powtac
nuevamente el mismo problema con keyup ... Lo he usado y tuve un problema con eso. lee mi pregunta completa.
Sachin Midha
0

Puedes usar onkeyup

<input id="name" onkeyup="checkLength(this.value)" />
Dogbert
fuente
He usado onkeyup ... pero mi problema es cuando el usuario selecciona desde el autocompletado del navegador, entonces este evento no se activa ... Ya escribí esto en mi pregunta en la solución alternativa que usé ...
Sachin Midha
0

Debería usar una combinación de onkeyupy onclick(o onmouseup) si desea aprovechar todas las posibilidades.

<input id="name" onkeyup="checkLength(this.value)" onmouseup="checkLength(this.value)" />
DaveRandom
fuente
Buen intento, pero el problema aquí es que no estoy presionando el mouse en el elemento de entrada, sino en el autocompletar, que no activará este evento ...
Sachin Midha
La única otra cosa en la que puedo pensar, y es desagradable, es en setTimeout verificar periódicamente el valor del campo ... ¿Qué es exactamente lo que quieres hacer?
DaveRandom
Eso es muy desagradable ...: D es algo similar a lo que hace un indicador de seguridad de la contraseña, le indica la seguridad de la contraseña a medida que la ingresa. Quiero habilitar un botón solo cuando la cadena ingresada tiene una longitud de 10; de lo contrario, manténgalo deshabilitado. Espero que lo
hayas entendido
0

Aquí hay otra solución que desarrollo para el mismo problema. Sin embargo, utilizo muchos cuadros de entrada, por lo que mantengo el valor antiguo como un atributo definido por el usuario de los elementos en sí: "valor de datos". Usar jQuery es muy fácil de administrar.

        $(document).delegate('.filterBox', 'keyup', { self: this }, function (e) {
            var self = e.data.self;

            if (e.keyCode == 13) {
                e.preventDefault();
                $(this).attr('data-value', $(this).val());
                self.filterBy(this, true)
            }
            else if (e.keyCode == 27) {
                $(this).val('');
                $(this).attr('data-value', '');
                self.filterBy(this, true)
            }
            else {
                if ($(this).attr('data-value') != $(this).val()) {
                    $(this).attr('data-value', $(this).val());
                    self.filterBy(this);
                }
            }
        });

aquí está, utilicé 5-6 cajas de entrada con clase 'filterBox', hago que el método filterBy se ejecute solo si el valor de datos es diferente a su propio valor.

efirat
fuente