¿Por qué el evento de cambio de jquery no se activa cuando establezco el valor de un select usando val()?


La lógica en el controlador de eventos change() no se ejecuta cuando el valor es establecido por val(), pero se ejecuta cuando el usuario selecciona un valor con su ratón. ¿Por qué es esto?

<select id="single">
    <option>Single</option>
    <option>Single2</option>
</select>

<script>
    $(function() {
        $(":input#single").change(function() {
           /* Logic here does not execute when val() is used */
        });
    });

    $("#single").val("Single2");
</script>
Author: jnuK, 2011-01-12

9 answers

Porque el evento change requiere un evento de navegador real iniciado por el usuario en lugar de a través de código javascript.

Haga esto en su lugar:

$("#single").val("Single2").trigger('change');

O

$("#single").val("Single2").change();
 549
Author: user113716,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-16 05:01:57

Creo que puede activar manualmente el evento de cambio con trigger():

$("#single").val("Single2").trigger('change');

Aunque por qué no se dispara automáticamente, no tengo idea.

 43
Author: David Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-12 18:32:04

Por lo que puedo leer en las API. El evento solo se dispara cuando el usuario hace clic en una opción.

Http://api.jquery.com/change/

Para seleccionar casillas, casillas de verificación y botones de radio, el evento se dispara inmediatamente cuando el usuario realiza una selección con el ratón, pero para el otros tipos de elementos es el evento diferido hasta que el elemento pierde centrar.

 8
Author: Marnix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-12 18:34:15

Agregar este fragmento de código después de val () parece funcionar:

$(":input#single").trigger('change');
 8
Author: Eric Belair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-12 18:38:19

Para hacerlo más fácil agregue una función personalizada y llámela cuando quiera que cambie el valor también active change

$.fn.valAndTrigger = function (element) {
    return $(this).val(element).trigger('change');
}

Y

$("#sample").valAndTirgger("NewValue");

O puede anular la función val para llamar siempre al cambio cuando se llama al val

(function ($) {
    var originalVal = $.fn.val;
    $.fn.val = function (value) {
        this.trigger("change");
        return originalVal.call(this, value);
    };
})(jQuery);

Muestra en http://jsfiddle.net/r60bfkub/

 6
Author: Alireza Fattahi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-29 05:57:30

En caso de que no desee confundirse con el evento de cambio predeterminado, puede proporcionar su evento personalizado

$('input.test').on('value_changed', function(e){
    console.log('value changed to '+$(this).val());
});

Para activar el evento en el valor establecido, puede hacer

$('input.test').val('I am a new value').trigger('value_changed');
 3
Author: codingrhythm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-13 22:57:33

Me encontré con el mismo problema mientras usaba CMB2 con Wordpress y quería engancharme al evento de cambio de un metabox de carga de archivos.

Así que en caso de que no pueda modificar el código que invoca el cambio (en este caso el script CMB2), use el código a continuación. El desencadenador se invoca DESPUÉS de que se establece el valor, de lo contrario su controlador de eventos de cambio funcionará, pero el valor será el anterior, no el que se establece.

Aquí está el código que uso:

(function ($) {
    var originalVal = $.fn.val;
    $.fn.val = function (value) {
        if (arguments.length >= 1) {
            // setter invoked, do processing
            return originalVal.call(this, value).trigger('change');
        }
        //getter invoked do processing
        return originalVal.call(this);
    };
})(jQuery);
 2
Author: user2075039,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-01 10:24:00
$(":input#single").trigger('change');

Esto funcionó para mi guión. Tengo 3 combos y enlace con el evento chainSelect, necesito pasar 3 valores por url y seleccionar por defecto todo desplegable. Usé este

$('#machineMake').val('<?php echo $_GET['headMake']; ?>').trigger('change');

Y el primer evento funcionó.

 1
Author: Prashant Patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-27 16:48:51

Si acaba de agregar la opción seleccionar a un formulario y desea activar el evento de cambio, he encontrado que se requiere un setTimeout de lo contrario jQuery no recoge el cuadro de selección recién agregado:

window.setTimeout(function() { jQuery('.languagedisplay').change();}, 1);
 0
Author: Dave Hilditch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-24 12:18:59