javascript oninput Détecter toutes les modifications apportées à<input type="text">(immédiatement) en utilisant JQuery




value change jquery (13)

Eh bien, le meilleur moyen est de couvrir ces trois bases que vous avez énumérées par vous-même. Un simple: onblur,: onkeyup, etc ne fonctionnera pas pour ce que vous voulez, alors il suffit de les combiner.

KeyUp devrait couvrir les deux premiers, et si JavaScript est en train de modifier la boîte de saisie, eh bien, j'espère que c'est votre propre javascript, alors ajoutez juste un rappel dans la fonction qui le modifie.

La valeur d'un <input type="text"> peut varier de plusieurs façons, notamment:

  • les touches
  • copier coller
  • modifié avec JavaScript
  • auto-complété par le navigateur ou une barre d'outils

Je veux que ma fonction JavaScript soit appelée (avec la valeur d'entrée actuelle) chaque fois qu'elle change. Et je veux qu'il soit appelé tout de suite, pas seulement quand l'entrée perd son focus.

Je suis à la recherche de la façon la plus propre et la plus robuste de faire cela à travers tous les navigateurs (en utilisant jQuery de préférence).

Exemple de cas d'utilisation: Sur la page d' inscription de Twitter , la valeur du champ de nom d'utilisateur apparaît dans l'url " http://twitter/ username " en dessous.


Ne pouvez-vous pas simplement utiliser l'élément <span contenteditable="true" spellcheck="false"> à la place de <input type="text"> ?

<span> (avec contenteditable="true" spellcheck="false" comme attributs) distinct par <input> principalement parce que:

  • Ce n'est pas comme un <input> .
  • Il n'a pas de propriété value , mais le texte est rendu innerText et fait partie de son corps interne.
  • C'est multiligne alors que <input> ne l'est pas bien que vous définissiez l'attribut multiline="true" .

Pour réaliser l'apparence, vous pouvez, bien sûr, le innerText en CSS, alors qu'en écrivant la valeur comme innerText vous pouvez obtenir un événement:

Voici un fiddle .

Malheureusement, il y a quelque chose qui ne fonctionne pas dans IE et Edge, que je suis incapable de trouver.


Malheureusement, je pense que setInterval remporte le prix:

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

C'est la solution la plus propre, à seulement 1 ligne de code. C'est aussi le plus robuste, car vous n'avez pas à vous soucier de tous les différents événements / façons dont une input peut avoir une valeur.

Les inconvénients de l'utilisation de 'setInterval' ne semblent pas s'appliquer dans ce cas:

  • La latence de 100ms? Pour de nombreuses applications, 100ms est assez rapide.
  • Ajout de la charge sur le navigateur? En général, l'ajout de beaucoup de setIntervals lourds sur votre page est mauvais. Mais dans ce cas particulier, le chargement de la page ajoutée est indétectable.
  • Cela ne correspond pas à de nombreuses entrées? La plupart des pages n'ont pas plus d'une poignée d'entrées, que vous pouvez renifler toutes dans le même setInterval.

Malheureusement, aucun événement ou ensemble d'événements ne correspond à vos critères. Les touches et le copier / coller peuvent tous deux être manipulés avec l'événement keyup . Les changements par JS sont plus délicats. Si vous avez le contrôle sur le code qui définit la zone de texte, le mieux est de la modifier pour appeler directement votre fonction ou déclencher un événement utilisateur dans la zone de texte:

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

Si vous n'avez pas le contrôle sur ce code, vous pouvez utiliser setInterval() pour "regarder" la zone de texte pour les changements:

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

Ce type de surveillance active n'attrape pas les mises à jour «immédiatement», mais il semble être assez rapide pour qu'il n'y ait pas de retard perceptible. Comme DrLouie l'a souligné dans ses commentaires, cette solution ne s'adapte probablement pas bien si vous avez besoin de regarder beaucoup d'intrants. Vous pouvez toujours ajuster le second paramètre à setInterval() pour vérifier plus ou moins fréquemment.


Ce code jQuery capte les modifications immédiates apportées à n'importe quel élément et devrait fonctionner dans tous les navigateurs:

 $('.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
       ....
     }
   });
 });

Ajoutez ce code quelque part, cela fera l'affaire.

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

Trouvé cette solution à val () ne déclenche pas de changement () dans jQuery


C'est le moyen le plus rapide et le plus propre de le faire:

J'utilise Jquery ->

$('selector').on('change', function () {
    console.log(this.id+": "+ this.value);
});

Cela fonctionne très bien pour moi.


Voici une solution légèrement différente si vous n'avez pas envie des autres réponses:

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

Considérez que vous ne pouvez pas compter sur le clic et le clavier pour capturer le contenu du menu contextuel.


Réponse 2017 : l' événement d'entrée fait exactement cela pour quelque chose de plus récent que IE8.

$(el).on('input', callback)

Une solution sophistiquée en temps réel pour jQuery> = 1.9

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

si vous voulez également détecter un événement "click", juste:

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

Si vous utilisez jQuery <= 1.4, utilisez simplement live au lieu de on .


vous pouvez voir cet exemple et choisir quels sont les événements qui vous intéressent:

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

En fait, nous n'avons pas besoin d'installer des boucles pour détecter les changements de JavaScript. Nous avons déjà mis en place de nombreux écouteurs d'événements sur l'élément que nous voulons détecter. le simple déclenchement d'un événement non nuisible fera le travail.

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

et d'ailleurs c'est seulement disponible si vous avez le plein contrôle sur les changements de javascript sur votre projet.


J'ai créé un échantillon. Mai cela fonctionnera pour vous.

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/





html