val () löst in jQuery keine change () aus

342

Ich versuche, das changeEreignis in einem Textfeld auszulösen, wenn ich seinen Wert mit einer Schaltfläche ändere, aber es funktioniert nicht. Überprüfen Sie diese Geige .

Wenn Sie etwas in die Textfelder eingeben und auf eine andere Stelle klicken, changewird dies ausgelöst. Wenn Sie jedoch auf die Schaltfläche klicken, wird der Textfeldwert geändert, jedoch changenicht ausgelöst. Warum?

Ergec
quelle
Der Titel selbst beantwortete meine Frage. Bestätigt bei .change () gelb "Hinweis: Wenn Sie den Wert eines Eingabeelements mithilfe von JavaScript ändern, z. B. mit .val (), wird das Ereignis nicht ausgelöst."
Bob Stein
Ich wünschte, ich wäre früher auf stackoverflow.com/questions/11873721/… gestoßen , hoffe, es hilft einigen.
JeopardyTempest

Antworten:

453

onchange Wird nur ausgelöst, wenn der Benutzer die Eingabe eingibt und die Eingabe dann den Fokus verliert.

Sie können das onchangeEreignis manuell aufrufen , indem Sie nach dem Festlegen des Werts Folgendes verwenden:

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

Alternativ können Sie das Ereignis auslösen , indem Sie:

$("#mytext").trigger("change");
djdd87
quelle
18
Sie können jquery jederzeit erweitern und eine Funktion say valWithChange hinzufügen, die das tut, was Sie wollen. Es kann nicht die Standardaktion sein, da Sie nicht möchten, dass das Ereignis aufgrund einer automatisierten Wertänderung ausgelöst wird, nur wenn ein Benutzer mit dem Element interagiert
redsquare
8
Ich möchte, dass diese Antwort bearbeitet wird, um die Option der Verkettung .change()mit der .val()Methode zu behandeln.
Snekse
19
Der Grund dafür kann sein , dass manche Leute nennen .val()in , .change()weil sie die Eingabevalidierung tun. Triggerung .change()auf .val()würde zu einer Endlosschleife führen.
Yingted
7
Nur wenn sie den Wert in etwas ändern würden, das ihre eigene Validierung nicht bestehen würde, wäre das albern.
Leng
3
blur$('#mytext').focus().val('New text').blur();
Wes Johnson
63

Nach dem hervorragenden Vorschlag von redsquare funktioniert dies gut:

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

$("#my-input").changeVal("Tyrannosaurus Rex");
Chris Fulstow
quelle
5
Sie müssen nicht einwickeln this:return this.val(v).trigger("change");
Mr. Polywhirl
27

Sie können die valFunktion zum Auslösen von Änderungen sehr einfach überschreiben, indem Sie sie durch einen Proxy zum Original ersetzenval Funktion .

Fügen Sie diesen Code einfach irgendwo in Ihr Dokument ein (nach dem Laden von 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);

Ein funktionierendes Beispiel: hier

(Beachten Sie, dass dies immer ausgelöst wird, changewennval(new_val) es aufgerufen wird, auch wenn sich der Wert nicht tatsächlich geändert hat.)

Wenn Sie eine Änderung NUR dann auslösen möchten, wenn sich der Wert tatsächlich geändert hat, verwenden Sie diesen:

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

Live-Beispiel dafür: http://jsfiddle.net/5fSmx/1/

Yaron U.
quelle
4
Hmm, unnötiges Entenflicken, denke ich :-p. Könnte besser sein, wie von redsquare kommentiert , einer solchen Funktion einen anderen Namen zu geben als .val().
Binki
1
Wenn Sie es umbenennen, sollten Sie Ihren vorhandenen Code ändern - auf diese Weise funktioniert Ihr vorhandener Code weiterhin
Yaron U.
4
Aber dann würde der gesamte Code, der mit der richtigen Definition von .val()geschrieben wurde, plötzlich Nebenwirkungen hervorrufen :-p.
Binki
2
Dies führt auch zu Fehlfunktionen der Plugins, die möglicherweise nicht so einfach zu beheben sind
SoWhat,
1
Um Nebenwirkungen zu vermeiden, habe ich die val-Funktion wie oben beschrieben geändert, aber ich löse ein anderes Ereignis ("val") aus, mit dem ich den vorhandenen Code beibehalten und ihn jederzeit problemlos verarbeiten kann: $ (... ) .on ('change val', ...)
ulu
22

Sie müssen die Methode wie folgt verketten:

$('#input').val('test').change();
Timothy Gonzalez
quelle
1
<3 für die Verkettung!
Gusstavv Gil
14

Nein, Sie müssen es möglicherweise manuell auslösen, nachdem Sie den Wert eingestellt haben:

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

oder:

$('#mytext').trigger('change');
Darin Dimitrov
quelle
8

Es sieht so aus, als ob die Ereignisse nicht sprudeln. Versuche dies:

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

Ich hoffe das hilft.

Ich habe nur ein einfaches altes versucht, $("#mytext").trigger('change')ohne den alten Wert zu speichern, und die .changeBrände, auch wenn sich der Wert nicht geändert hat. Deshalb habe ich den vorherigen Wert gespeichert und $("#mytext").trigger('change')nur aufgerufen , wenn er sich ändert.

Jay Godse
quelle
Überrascht hatte dies nicht mehr Stimmen, da es sich um die derzeit effektive Implementierung einer HTML-Elementänderung handelt.
Vol7ron
4

Ab Februar 2019 .addEventListener()funktioniert derzeit nicht mit jQuery .trigger()oder .change()Sie können es unten mit Chrome oder Firefox testen.

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

Sie müssen .dispatchEvent()stattdessen verwenden.

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

cieunteung
quelle
1

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

Das changeEreignis wird an ein Element gesendet, wenn sich sein Wert ändert. Diese Veranstaltung ist auf <input>Elemente, <textarea>Felder und <select>Elemente beschränkt. Bei Auswahlfeldern, Kontrollkästchen und Optionsfeldern wird das Ereignis sofort ausgelöst, wenn der Benutzer eine Auswahl mit der Maus trifft. Bei den anderen Elementtypen wird das Ereignis jedoch verschoben, bis das Element den Fokus verliert.

Himmel Yip
quelle
1

Ich weiß, dass dies ein alter Thread ist, aber für andere, die suchen, sind die oben genannten Lösungen möglicherweise nicht so gut wie die folgenden, anstatt changeEreignisse zu überprüfen, überprüfen Sie die inputEreignisse.

$("#myInput").on("input", function() {
    // Print entered value in a div box
    $("#result").text($(this).val());
});
Slipoch
quelle