Perché l'evento di modifica jQuery non si attiva quando imposto il valore di una selezione utilizzando val ()?


Answers

Credo che tu possa attivare manualmente l'evento change con trigger() :

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

Anche se il motivo per cui non si attiva automaticamente, non ne ho idea.

Question

La logica nel gestore di eventi change() non viene eseguita quando il valore è impostato da val() , ma viene eseguito quando l'utente seleziona un valore con il mouse. Perchè è questo?

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



Mi sono imbattuto nello stesso problema durante l'utilizzo di CMB2 con Wordpress e volevo collegarmi all'evento di modifica di un metabox di caricamento file.

Quindi, se non sei in grado di modificare il codice che invoca la modifica (in questo caso lo script CMB2), utilizza il codice seguente. Il trigger viene richiamato DOPO aver impostato il valore, altrimenti la modifica eventHandler funzionerà, ma il valore sarà il precedente, non quello impostato.

Ecco il codice che 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);



Nel caso in cui non si desideri confondere l'evento di modifica predefinito, è possibile fornire il proprio evento personalizzato

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

per attivare l'evento sul set di valori, puoi farlo

$('input.test').val('I am a new value').trigger('value_changed');



Aggiungere questo pezzo di codice dopo il val () sembra funzionare:

$(":input#single").trigger('change');