Wykryj wszystkie zmiany do (natychmiast) za pomocą JQuery

Istnieje wiele sposobów na zmianę wartości <input type="text">, w tym:

  • klawiatury
  • kopiuj / wklej
  • modified with JavaScript
  • automatyczne uzupełnianie przez przeglądarkę lub pasek narzędzi

Chcę, aby moja funkcja JavaScript była wywoływana (z bieżącą wartością wejściową) za każdym razem, gdy się zmieni. I chcę, żeby to zostało wywołane od razu, a nie tylko wtedy, gdy wejście traci ostrość.

Szukam najczystszego i najbardziej solidnego sposobu, aby to zrobić we wszystkich przeglądarkach (za pomocą jQuery najlepiej).

Przykładowy przypadek użycia: na stronie Twitter Signup , wartość pola username zostanie wyświetlona w adresie url " http://twitter/ nazwa użytkownika" poniżej.

Author: Sankar, 2009-12-22

16 answers

Ten kod jQuery wychwytuje natychmiastowe zmiany w dowolnym elemencie i powinien działać we wszystkich przeglądarkach:

 $('.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
       ....
     }
   });
 });
 322
Author: phatmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-05 18:19:09

A real-time fancy solution for jQuery >= 1.9

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

Jeśli chcesz również wykryć Zdarzenie "click", po prostu:

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

Jeśli używasz jQuery live zamiast on.

 108
Author: Felix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-21 20:39:56

Niestety, chyba setInterval wygrywa:

<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>
To najczystsze rozwiązanie, tylko 1 linijka kodu. Jest również najbardziej wytrzymały, ponieważ nie musisz się martwić o wszystkie różne wydarzenia/sposoby, w jakie an input może uzyskać wartość.

Wady używania 'setInterval' wydają się nie mieć zastosowania w tym przypadku:

  • opóźnienie 100ms? dla wielu aplikacji 100ms jest wystarczająco szybki.
  • Dodano obciążenie przeglądarki? ogólnie rzecz biorąc, dodawanie partii z ciężkimi ustawieniami na twojej stronie jest źle. Ale w tym konkretnym przypadku dodane ładowanie strony jest niewykrywalne.
  • Nie skaluje się do wielu wejść? większość stron nie ma więcej niż garstki danych wejściowych, które można wywęszyć w tym samym setInterval.
 95
Author: Dustin Boswell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-22 21:47:52

Powiązanie ze zdarzeniem oninput wydaje się działać dobrze w większości rozsądnych przeglądarek. IE9 również to wspiera, ale implementacja jest błędna (zdarzenie nie jest wywoływane przy usuwaniu znaków).

W jQuery w wersji 1.7 + Metoda on jest przydatna do powiązania zdarzenia w następujący sposób:

$(".inputElement").on("input", null, null, callbackFunction);
 55
Author: HRJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-28 05:36:18

2017 answer : input event robi dokładnie to dla wszystkiego, co nowsze niż IE8.

$(el).on('input', callback)
 25
Author: Chris F Carroll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-25 10:28:56

Niestety nie ma żadnego zdarzenia lub zestawu zdarzeń spełniających Twoje kryteria. Naciśnięcia klawiszy i kopiowanie/wklejanie mogą być obsługiwane za pomocą zdarzenia keyup. Zmiany przez JS są trudniejsze. Jeśli masz kontrolę nad kodem, który ustawia pole tekstowe, najlepszym rozwiązaniem jest zmodyfikowanie go, aby wywołać bezpośrednio funkcję lub wywołać zdarzenie użytkownika na polu tekstowym:

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

Jeśli nie masz kontroli nad tym kodem, możesz użyć setInterval(), aby "obserwować" pole tekstowe pod kątem zmian:

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

Ten rodzaj aktywnego monitorowania nie będzie łapać aktualizacji "natychmiast", ale wydaje się być wystarczająco szybki, że nie ma wyczuwalnego opóźnienia. Jak zauważył DrLouie w komentarzach, To rozwiązanie prawdopodobnie nie skaluje się dobrze, jeśli trzeba oglądać wiele wejść. Zawsze możesz dostosować 2. parametr do setInterval(), aby sprawdzać mniej lub bardziej często.

 15
Author: Annabelle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-22 20:00:34

Oto nieco inne rozwiązanie, jeśli nie spodobała ci się żadna inna odpowiedź:

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

Weź pod uwagę, że nie możesz polegać na click I keyup, aby przechwycić wklejenie menu kontekstowego.

 6
Author: Peder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-09 10:16:30

Stworzyłem próbkę. Niech ci się uda.

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
Author: Ambuj Khanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-22 07:48:04

W rzeczywistości nie musimy ustawiać pętli do wykrywania zmian w javaScript. Ustawiamy już wiele detektorów zdarzeń do elementu, który chcemy wykryć. samo wywołanie wszelkich szkodliwych zdarzeń sprawi, że praca.

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

I ofc jest to dostępne tylko wtedy, gdy masz pełną kontrolę nad zmianami javascript w projekcie.

 3
Author: Serdar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 15:17:06

Dodaj ten kod gdzieś, to załatwi sprawę.

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

Znaleziono To rozwiązanie w val() nie wywołuje zmiany () w jQuery

 3
Author: lpradhap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-31 07:25:19

Cóż, najlepszym sposobem jest pokrycie tych trzech baz, które wymieniłeś sam. Proste :onblur,: onkeyup itp. nie będą działać na to, co chcesz, więc po prostu połącz je.

KeyUp powinien obejmować dwa pierwsze, a jeśli Javascript modyfikuje pole wprowadzania, cóż, mam nadzieję, że to twój własny javascript, więc po prostu dodać callback w funkcji, która go modyfikuje.

 1
Author: idrumgood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-22 19:03:25

Oto przykład pracy, którego używam do implementacji wariacji autocomplete, która zapełnia selektor (listę) jqueryui, ale nie chcę, aby działał dokładnie tak, jak autocomplete jQueryUI, który ma rozwijane menu.

$("#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
Author: clearlight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-05 12:44:15

Nie możesz po prostu użyć <span contenteditable="true" spellcheck="false"> elementu zamiast <input type="text">?

<span> (z contenteditable="true" spellcheck="false" jako atrybutami) wyróżnia się przez <input> głównie dlatego, że:

  • to nie jest stylizowane na <input>.
  • nie ma właściwości value, ale tekst jest renderowany jako {[7] } i stanowi część jego wewnętrznego ciała.
  • jest wielowierszowa, podczas gdy {[4] }nie jest, chociaż Ustawiłeś atrybut multiline="true".

Aby uzyskać wygląd można oczywiście stylizować go w CSS, natomiast pisząc wartość jako innerText można uzyskać dla niego Zdarzenie:

Oto skrzypce.

Niestety jest coś, co nie działa w IE i Edge, czego nie jestem w stanie znaleźć.

 0
Author: Davide Cannizzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-01 16:08:35

Możesz zobaczyć ten przykład i wybrać, które wydarzenia Cię interesują:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<title>evetns</title>
</head>
<body>
<form>
    <input class="controlevents" id="i1" type="text" /><br />
    <input class="controlevents" id="i2" type="text" /><br />
    <input class="controlevents" id="i3" type="text" /><br />
    <input class="controlevents" id="i4" type="text" /><br />
    <input class="controlevents" id="i5" type="text" /><br />
</form>
<div id="datatext"></div>
</body>
</html>
<script>
$(function(){

function testingevent(ev){
    if (ev.currentTarget.tagName=="INPUT")
        $("#datatext").append("<div>id : " + ev.currentTarget.id + ", tag: " + ev.currentTarget.tagName + ", type: "+ ev.type +"</div>");
}   

    var eventlist = ["resizeend","rowenter","dragleave","beforepaste","dragover","beforecopy","page","beforeactivate","beforeeditfocus","controlselect","blur",
                    "beforedeactivate","keydown","dragstart","scroll","propertychange","dragenter","rowsinserted","mouseup","contextmenu","beforeupdate",
                    "readystatechange","mouseenter","resize","copy","selectstart","move","dragend","rowexit","activate","focus","focusin","mouseover","cut",
                    "mousemove","focusout","filterchange","drop","blclick","rowsdelete","keypress","losecapture","deactivate","datasetchanged","dataavailable",
                    "afterupdate","mousewheel","keyup","movestart","mouseout","moveend","cellchange","layoutcomplete","help","errorupdate","mousedown","paste",
                    "mouseleave","click","drag","resizestart","datasetcomplete","beforecut","change","error","abort","load","select"];

    var inputs = $(".controlevents");

    $.each(eventlist, function(i, el){
        inputs.bind(el, testingevent);
    });

});
</script>
 -2
Author: andres descalzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-22 20:55:23

Mogę się spóźnić na imprezę, ale nie możesz po prostu użyć .Zdarzenie change (), które dostarcza jQuery.

Powinieneś być w stanie zrobić coś takiego ...
$(#CONTROLID).change(function(){
    do your stuff here ...
});

Zawsze możesz powiązać go z listą kontrolek za pomocą czegoś takiego ...

var flds = $("input, textarea", window.document);

flds.live('change keyup', function() {
    do your code here ...
});

Aktywny segregator zapewnia, że wszystkie elementy, które istnieją na stronie teraz i w przyszłości, są obsługiwane.

 -3
Author: Andy Crouch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-11 08:20:01

Jest to najszybszy i czysty sposób, aby to zrobić:

Używam Jquery-- >

$('selector').on('change', function () {
    console.log(this.id+": "+ this.value);
});
Dla mnie działa całkiem nieźle.
 -4
Author: Despertaweb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-10 13:20:54