Es gibt viele Möglichkeiten, wie sich der Wert eines <input type="text">
ändern kann, darunter:
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.
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:
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
....
}
});
});
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
.
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);
2017 answer : das Eingabeereignis erledigt genau dies für alle neueren Versionen als IE8.
$(el).on('input', callback)
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.
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.
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
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.
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>
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.
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>");
}
});
});
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:
<input>
gestaltet.value
-Eigenschaft, aber der Text wird als innerText
gerendert und ist Teil seines inneren Körpers.<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.