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?



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

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

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/


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


14

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

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

oder:

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

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.


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


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.


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());
});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.