it-swarm.com.de

Ermitteln Sie alle Änderungen an einem <input type = "text"> (sofort) mithilfe von JQuery

Es gibt viele Möglichkeiten, wie sich der Wert eines <input type="text"> ändern kann, darunter:

  • tastendrucke
  • kopieren Einfügen
  • modifiziert mit JavaScript
  • wird vom Browser oder einer Symbolleiste automatisch vervollständigt

Ich möchte, dass meine JavaScript-Funktion bei jeder Änderung (mit dem aktuellen Eingabewert) aufgerufen wird. Und ich möchte, dass es sofort aufgerufen wird, nicht nur, wenn der Eingang den Fokus verliert.

Ich bin auf der Suche nach der saubersten und robustesten Möglichkeit, dies in allen Browsern zu tun (vorzugsweise mit jQuery).

Anwendungsbeispiel: Auf der Seite Twitter Signup wird der Wert des Feldes username in der URL " http : // Twitter / Benutzername "darunter.

379
Dustin Boswell

Leider denke ich, dass setInterval den Preis gewinnt:

<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>

Es ist die sauberste Lösung mit nur einer Codezeile. Es ist auch das robusteste, da Sie sich nicht um die verschiedenen Ereignisse/Möglichkeiten kümmern müssen, mit denen input einen Wert erhalten kann.

Die Nachteile der Verwendung von 'setInterval' scheinen in diesem Fall nicht zuzutreffen:

  • Die 100ms Latenzzeit? Für viele Anwendungen sind 100ms schnell genug.
  • Hinzugefügte Last auf dem Browser? Im Allgemeinen ist es schlecht, viele schwere setIntervals auf Ihrer Seite hinzuzufügen. In diesem speziellen Fall ist die hinzugefügte Seitenladung jedoch nicht erkennbar.
  • Skaliert es nicht auf viele Eingaben? Die meisten Seiten haben nicht mehr als eine Handvoll Eingaben, an denen Sie alle in demselben setInterval riechen können.
102
Dustin Boswell

Dieser jQuery-Code erkennt sofortige Änderungen an einem Element und sollte in allen Browsern funktionieren:

 $('.myElements').each(function() {
   var elem = $(this);

   // Save current value of element
   elem.data('oldVal', elem.val());

   // Look for changes in the value
   elem.bind("propertychange change click keyup input paste", function(event){
      // If value has changed...
      if (elem.data('oldVal') != elem.val()) {
       // Updated stored value
       elem.data('oldVal', elem.val());

       // Do action
       ....
     }
   });
 });
337
phatmann

Eine Echtzeitlösung für jQuery> = 1.9

$("#input-id").on("change keyup paste", function(){
    dosomething();
})

wenn Sie auch ein "Klick" -Ereignis erkennen möchten, gehen Sie wie folgt vor:

$("#input-id").on("change keyup paste click", function(){
    dosomething();
})

wenn Sie jQuery <= 1.4 verwenden, verwenden Sie einfach live anstelle von on.

120
Felix

Die Bindung an das Ereignis oninput scheint in den meisten vernünftigen Browsern problemlos zu funktionieren. IE9 unterstützt es auch, aber die Implementierung ist fehlerhaft (das Ereignis wird beim Löschen von Zeichen nicht ausgelöst).

Ab jQuery-Version 1.7 ist die on -Methode nützlich, um eine Bindung an das Ereignis wie folgt vorzunehmen:

$(".inputElement").on("input", null, null, callbackFunction);
57
HRJ

2017 answer : das Eingabeereignis erledigt genau dies für alle neueren Versionen als IE8.

$(el).on('input', callback)
28
Chris F Carroll

Leider gibt es kein Ereignis oder eine Reihe von Ereignissen, die Ihren Kriterien entsprechen. Tastendruck und Kopieren/Einfügen können beide mit dem Ereignis keyup behandelt werden. Änderungen durch JS sind schwieriger. Wenn Sie die Kontrolle über den Code haben, der das Textfeld festlegt, können Sie diesen am besten so ändern, dass Ihre Funktion entweder direkt aufgerufen oder ein Benutzerereignis für das Textfeld ausgelöst wird:

// Compare the textbox's current and last value.  Report a change to the console.
function watchTextbox() {
  var txtInput = $('#txtInput');
  var lastValue = txtInput.data('lastValue');
  var currentValue = txtInput.val();
  if (lastValue != currentValue) {
    console.log('Value changed from ' + lastValue + ' to ' + currentValue);
    txtInput.data('lastValue', currentValue);
  }
}

// Record the initial value of the textbox.
$('#txtInput').data('lastValue', $('#txtInput').val());

// Bind to the keypress and user-defined set event.
$('#txtInput').bind('keypress set', null, watchTextbox);

// Example of JS code triggering the user event
$('#btnSetText').click(function (ev) {
  $('#txtInput').val('abc def').trigger('set');
});

Wenn Sie nicht die Kontrolle über diesen Code haben, können Sie setInterval() verwenden, um das Textfeld auf Änderungen zu überprüfen:

// Check the textbox every 100 milliseconds.  This seems to be pretty responsive.
setInterval(watchTextbox, 100);

Bei dieser Art der aktiven Überwachung werden Aktualisierungen nicht "sofort" erfasst, aber es scheint schnell genug zu sein, dass keine wahrnehmbare Verzögerung auftritt. Wie DrLouie in Kommentaren hervorhob, lässt sich diese Lösung wahrscheinlich nicht gut skalieren, wenn Sie viele Eingaben überwachen müssen. Sie können den 2. Parameter jederzeit auf setInterval() einstellen, um mehr oder weniger häufig zu prüfen.

15
Annabelle

Hier ist eine etwas andere Lösung, wenn Sie sich keine der anderen Antworten vorgestellt haben:

var field_selectors = ["#a", "#b"];
setInterval(function() { 
  $.each(field_selectors, function() { 
    var input = $(this);
    var old = input.attr("data-old-value");
    var current = input.val();
    if (old !== current) { 
      if (typeof old != 'undefined') { 
        ... your code ...
      }
      input.attr("data-old-value", current);
    }   
  }   
}, 500);

Bedenken Sie, dass Sie sich beim Einfügen von Kontextmenüs nicht auf Klicken und Tastatureingaben verlassen können.

6
Peder

Fügen Sie diesen Code irgendwo hinzu, dies wird den Trick machen.

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

Fand diese Lösung bei val () löst nicht change () in jQuery aus

4
lpradhap

Tatsächlich müssen keine Schleifen eingerichtet werden, um JavaScript-Änderungen zu erkennen. Wir haben bereits viele Ereignis-Listener für das Element eingerichtet, das wir erkennen möchten. Nur das Auslösen eines schädlichen Ereignisses macht den Job.

$("input[name='test-element']").on("propertychange change click keyup input paste blur", function(){
console.log("yeh thats worked!");
});

$("input[name='test-element']").val("test").trigger("blur");

und dies ist nur möglich, wenn Sie die volle Kontrolle über Javascript-Änderungen in Ihrem Projekt haben.

3
Serdar

Ich habe ein Muster erstellt. Möge es für Sie arbeiten.

var typingTimer;
var doneTypingInterval = 10;
var finaldoneTypingInterval = 500;

var oldData = $("p.content").html();
$('#tyingBox').keydown(function () {
    clearTimeout(typingTimer);
    if ($('#tyingBox').val) {
        typingTimer = setTimeout(function () {
            $("p.content").html('Typing...');
        }, doneTypingInterval);
    }
});

$('#tyingBox').keyup(function () {
    clearTimeout(typingTimer);
    typingTimer = setTimeout(function () {
        $("p.content").html(oldData);
    }, finaldoneTypingInterval);
});


<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>


<textarea id="tyingBox" tabindex="1" placeholder="Enter Message"></textarea>
<p class="content">Text will be replace here and after Stop typing it will get back</p>

http://jsfiddle.net/utbh575s/

3
Ambuj Khanna

Nun, der beste Weg ist, die drei Basen, die Sie selbst aufgelistet haben, abzudecken. Ein einfaches: onblur,: onkeyup usw. funktioniert nicht für das, was Sie wollen, also kombinieren Sie sie einfach.

KeyUp sollte die ersten beiden behandeln, und wenn Javascript das Eingabefeld ändert, hoffe ich, dass es Ihr eigenes Javascript ist. Fügen Sie einfach einen Rückruf in die Funktion ein, die es ändert.

1
idrumgood

Hier ist ein funktionierendes Beispiel, das ich verwende, um eine Autocomplete-Variante zu implementieren, die einen jqueryui-Selektor (Liste) auffüllt, aber ich möchte nicht, dass er genau wie der jqueryui-Autocomplete funktioniert, der ein Dropdown-Menü ausführt.

$("#tagFilter").on("change keyup paste", function() {
     var filterText = $("#tagFilter").val();
    $("#tags").empty();
    $.getJSON("http://localhost/cgi-bin/tags.php?term=" + filterText,
        function(data) {
            var i;
            for (i = 0; i < data.length; i++) {
                var tag = data[i].value;
                $("#tags").append("<li class=\"tag\">" + tag + "</li>");
            }
        }); 
});
1
clearlight

Können Sie nicht einfach das Element <span contenteditable="true" spellcheck="false"> anstelle von <input type="text"> verwenden?

<span> (mit contenteditable="true" spellcheck="false" als Attributen) unterscheidet sich durch <input> hauptsächlich, weil:

  • Es ist nicht wie ein <input> gestaltet.
  • Es hat keine value -Eigenschaft, aber der Text wird als innerText gerendert und ist Teil seines inneren Körpers.
  • Es ist mehrzeilig, während <input> nicht ist, obwohl Sie das Attribut multiline="true" festgelegt haben.

Um das Erscheinungsbild zu erreichen, können Sie es natürlich in CSS formatieren. Wenn Sie den Wert jedoch als innerText schreiben, erhalten Sie ein Ereignis:

Hier ist ein Geige .

Leider funktioniert in IE und Edge etwas nicht, was ich nicht finden kann.

0
Davide Cannizzo