417 votes

Détecter toutes les modifications d'un <input type="text"> (immédiatement) en utilisant JQuery

Il existe de nombreuses façons d'évaluer la valeur d'un <input type="text"> peuvent changer, notamment :

  • pressions sur 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'elle soit appelée immédiatement, et pas seulement lorsque l'entrée perd le focus.

Je cherche le moyen le plus propre et le plus robuste de le faire sur tous les navigateurs (en utilisant jQuery de préférence).

1 votes

360voto

phatmann Points 4153

Ce code jQuery capte les changements immédiats de tout élément et devrait fonctionner sur 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
       ....
     }
   });
 });

21 votes

Pour la référence de tout le monde, input est l'événement HTML5 qui, selon moi, devrait couvrir tous les navigateurs modernes ( Référence MDN ). keyup devrait rattraper le reste, mais avec un léger retard ( input est déclenché lorsque la touche est enfoncée). propertychange est un événement propriétaire de MS, et je ne suis pas sûr si paste est réellement nécessaire.

1 votes

Il est important de noter qu'avant IE 9, onpropertychange ne fait pas de bulles. Cela signifie qu'il est impossible de se lier à cet événement à l'aide de la fonction .live() (o .on() dans les cas utiles), à moins que vous ne le liiez directement à l'élément de saisie lui-même.

77 votes

Je me trompe ou cela ne gère pas le changement de texte via javascript comme par exemple document.getElementById('txtInput').value = 'some text';

130voto

Felix Points 351

Une solution de fantaisie en temps réel pour jQuery >= 1.9

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

si vous voulez aussi détecter l'événement "click", il suffit de :

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

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

3 votes

Cela a un inconvénient. Si vous laissez le champ de saisie avec la touche de tabulation, l'événement keyup sera déclenché même si le contenu n'a pas été modifié.

3 votes

Comment détecter quand le datetimepicker remplit le #input-id ? Aucun des événements (changer, coller) ne fonctionne.

0 votes

C'est génial ! Je l'ai essayé avec jquery 1.8.3 et ça marche. J'ai encore du code livequery() à remplacer et je ne peux donc pas encore passer à la version 1.9.1. Je sais qu'il est vieux mais tout le site l'est aussi.

111voto

Dustin Boswell Points 1452

Malheureusement, je pense 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, avec seulement une ligne de code. C'est aussi la plus robuste, puisque vous n'avez pas à vous soucier de tous les différents événements/manières dont une action de input peut obtenir une valeur.

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

  • La latence de 100 ms ? Pour de nombreuses applications, 100 ms est une vitesse suffisante.
  • Charge supplémentaire sur le navigateur ? En général, l'ajout d'un grand nombre de setIntervals lourds sur votre page est mauvais. Mais dans ce cas particulier, la charge supplémentaire de la page est indétectable.
  • Il ne s'adapte 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.

0 votes

Étant donné que d'autres réponses sont censées ne pas prendre en compte les modifications apportées à l'image de marque de l'entreprise. input via Javascript, une alternative ne serait-elle pas de capturer tous les événements que la modification par l'utilisateur peut déclencher, et aussi de faire en sorte que toutes les modifications des éléments d'entrée par le code utilisent une fonction wrapper qui déclenche explicitement un événement de changement sur l'élément d'entrée ? Cette solution aurait ses propres inconvénients (risque de ne pas utiliser la fonction wrapper par inadvertance ; ne fonctionnerait pas pour une bibliothèque / un plugin sur la page de quelqu'un d'autre ; nécessiterait de modifier le code existant) mais éliminerait la latence ; vous pourriez peut-être énumérer les deux approches et les comparer ?

1 votes

D'autres extraits de code ont été postés ici, mais en voici un basé sur cet article : codepen.io/chrisfargen/pen/qbyaG

24 votes

Cela semble être le seul moyen de détecter les modifications apportées à un champ de saisie dans un formulaire lors de l'utilisation du navigateur Nintendo 3DS (Version/1.7552.EU).

58voto

HRJ Points 4750

Lié à la oninput semble fonctionner correctement dans la plupart des navigateurs sains d'esprit. IE9 le prend également en charge, mais son implémentation est boguée (l'événement n'est pas déclenché lors de la suppression de caractères).

Avec la version 1.7 et plus de jQuery, la fonction on est utile pour se lier à l'événement comme ceci :

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

12 votes

oninput L'événement ne fonctionne pas avec input[type=reset] ou l'édition en javascript comme vous pouvez le voir dans ce test : codepen.io/yukulele/pen/xtEpb

2 votes

@Yukulélé, Au moins, nous pouvons contourner ce problème plus facilement qu'en essayant de détecter toutes les possibilités. utilisateur action.

16voto

Annabelle Points 4476

Malheureusement, aucun événement ou ensemble d'événements ne correspond à vos critères. Les pressions sur les touches et les copier/coller peuvent tous deux être gérés par la fonction keyup événement. Les modifications par JS sont plus délicates. Si vous avez le contrôle du code qui définit la zone de texte, votre meilleure chance est de le modifier pour qu'il appelle directement votre fonction ou déclenche un événement utilisateur sur 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 de ce code, vous pouvez utiliser setInterval() pour "surveiller" les modifications apportées à la zone de texte :

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

Ce type de surveillance active ne permet pas d'obtenir des mises à jour "immédiatement", mais elle semble suffisamment rapide pour qu'aucun décalage ne soit perceptible. Comme DrLouie l'a souligné dans les commentaires, cette solution n'est probablement pas adaptée si vous devez surveiller de nombreuses entrées. Vous pouvez toujours ajuster le 2ème paramètre à setInterval() pour vérifier plus ou moins fréquemment.

0 votes

Pour votre information, il existe en fait un grand nombre d'événements qui peuvent être combinés pour répondre aux critères du PO à des degrés divers selon les navigateurs (voir les liens dans le commentaire de la première question). Cette réponse n'utilise aucun de ces événements, et ironiquement, elle fonctionnera probablement aussi bien dans tous les navigateurs, bien qu'avec un léger décalage ;)

0 votes

L'OP veut attraper les changements apportés à la zone de texte via JavaScript (par ex. myTextBox.value = 'foo'; . Aucun événement JavaScript ne gère cette situation.

1 votes

Et si quelqu'un avait 50 champs à surveiller ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X