val () non attiva change () in jQuery


343

Sto cercando di attivare l' changeevento su una casella di testo quando cambio il suo valore con un pulsante, ma non funziona. Controlla questo violino .

Se si digita qualcosa nelle caselle di testo e si fa clic da qualche altra parte, changeviene attivato. Tuttavia, se si fa clic sul pulsante, il valore della casella di testo viene modificato, ma changenon si attiva. Perché?



Il titolo stesso ha risposto alla mia domanda. Confermato con .change () giallo "Nota: la modifica del valore di un elemento di input utilizzando JavaScript, ad esempio utilizzando .val (), non genererà l'evento."
Bob Stein,

Vorrei che avessi trovato stackoverflow.com/questions/11873721/… prima, spero che sia di aiuto.
JeopardyTempest il

Risposte:


454

onchange si attiva solo quando l'utente digita nell'input e quindi l'input perde lo stato attivo.

Puoi chiamare manualmente l' onchangeevento usando dopo aver impostato il valore:

$("#mytext").change(); // someObject.onchange(); in standard JS

In alternativa, puoi attivare l'evento usando:

$("#mytext").trigger("change");

18
sentiti libero di estendere jquery e aggiungere una funzione dire valWithChange che farà quello che vuoi. Non può essere l'azione predefinita quante volte non si desidera che l'evento venga attivato da una modifica automatica del valore, solo quando un utente interagisce con l'elemento
redsquare

8
Vorrei vedere questa risposta modificata per affrontare la possibilità di concatenare .change()il .val()metodo.
Snekse,

19
Il motivo potrebbe essere che alcuni chiamano .val()in .change()causa fanno convalida dell'input. Trigger .change()su .val()causerebbe un ciclo infinito.
gridò il

7
Solo se avessero cambiato il valore in qualcosa che avrebbe fallito la propria convalida, che sarebbe stata sciocca.
Leng

3
Ho finito per impegnarmi per blurrealizzare qualcosa di simile:$('#mytext').focus().val('New text').blur();
Wes Johnson,

63

Dall'eccellente suggerimento di redsquare, funziona perfettamente:

$.fn.changeVal = function (v) {
    return this.val(v).trigger("change");
}

$("#my-input").changeVal("Tyrannosaurus Rex");

5
Non è necessario avvolgere this:return this.val(v).trigger("change");
Mr. Polywhirl il

27

Puoi facilmente sostituire la valfunzione per attivare la modifica sostituendola con un proxy alla valfunzione originale .

aggiungi questo codice da qualche parte nel tuo documento (dopo aver caricato jQuery)

(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0)
            $(this).change(); // OR with custom event $(this).trigger('value-changed');
        return result;
    };
})(jQuery);

Un esempio funzionante: qui

(Si noti che questo si attiverà sempre changequando val(new_val)viene chiamato anche se il valore non è stato effettivamente modificato.)

Se si desidera attivare la modifica SOLO quando il valore è stato effettivamente modificato, utilizzare questo:

//This will trigger "change" event when "val(new_val)" called 
//with value different than the current one
(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var prev;
        if(arguments.length>0){
            prev = originalVal.apply(this,[]);
        }
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0 && prev!=originalVal.apply(this,[]))
            $(this).change();  // OR with custom event $(this).trigger('value-changed')
        return result;
    };
})(jQuery);

Esempio live per quello: http://jsfiddle.net/5fSmx/1/


4
Hmm, patching anatra inutili, penso :-p. Potrebbe essere meglio, come commentato da redsquare , assegnare a tale funzione un nome diverso da .val().
binki,

1
Se lo rinomini dovresti cambiare il tuo codice esistente - in questo modo il tuo codice esistente continuerà a funzionare
Yaron U.

4
Ma poi tutto il codice che è stato scritto con la definizione corretta .val()in mente inizierebbe improvvisamente a produrre effetti collaterali :-p.
binki,

2
Ciò causerà anche il malfunzionamento dei plug-in, che potrebbe non essere facilmente risolvibile
SoWhat

1
Al fine di evitare effetti collaterali, ho modificato la funzione val come sopra, ma sto attivando un evento diverso ("val"), che mi consente di conservare il codice esistente ma di gestirlo facilmente ogni volta che devo: $ (... ) .on ('change val', ...)
ulu


14

No, potrebbe essere necessario attivarlo manualmente dopo aver impostato il valore:

$('#mytext').change();

o:

$('#mytext').trigger('change');

8

Sembra che gli eventi non stiano ribollendo. Prova questo:

$("#mybutton").click(function(){
  var oldval=$("#mytext").val();
  $("#mytext").val('Changed by button');
  var newval=$("#mytext").val();
  if (newval != oldval) {
    $("#mytext").trigger('change');
  }
});

Spero che aiuti.

Ho provato solo un vecchio $("#mytext").trigger('change')senza salvare il vecchio valore, e gli .changeincendi anche se il valore non è cambiato. Ecco perché ho salvato il valore precedente e chiamato $("#mytext").trigger('change')solo se cambia.


Sorpreso, questo non ha avuto più voti, poiché è l'attuale implementazione effettiva di un cambio di elemento HTML.
vol7ron,

4

A partire da febbraio 2019 .addEventListener()non funziona attualmente con jQuery .trigger()o .change(), puoi testarlo di seguito utilizzando Chrome o Firefox.

txt.addEventListener('input', function() {
  console.log('not called?');
})
$('#txt').val('test').trigger('input');
$('#txt').trigger('input');
$('#txt').change();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="txt">

devi usare .dispatchEvent()invece.

txt.addEventListener('input', function() {
  console.log('it works!');
})
$('#txt').val('yes')
txt.dispatchEvent(new Event('input'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="text" id="txt">


1

Da https://api.jquery.com/change/ :

L' changeevento viene inviato a un elemento quando il suo valore cambia. Questo evento è limitato a <input>elementi, <textarea>caselle ed <select>elementi. Per le caselle selezionate, le caselle di controllo e i pulsanti di opzione, l'evento viene generato immediatamente quando l'utente effettua una selezione con il mouse, ma per gli altri tipi di elemento l'evento viene rinviato fino a quando l'elemento non si attiva.


1

So che questo è un vecchio thread, ma per gli altri che cercano, le soluzioni di cui sopra forse non sono buone come le seguenti, invece di controllare gli changeeventi, controllare gli inputeventi.

$("#myInput").on("input", function() {
    // Print entered value in a div box
    $("#result").text($(this).val());
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.