L'événement de changement de zone de texte jQuery ne se déclenche pas jusqu'à ce que la zone de texte perde le focus?


133

J'ai trouvé que l'événement de changement jQuery sur une zone de texte ne se déclenche pas tant que je ne clique pas en dehors de la zone de texte.

HTML:

<input type="text" id="textbox" />

JS:

$("#textbox").change(function() {alert("Change detected!");});

Voir la démo sur JSFiddle

Mon application nécessite que l'événement soit déclenché à chaque changement de caractère dans la zone de texte. J'ai même essayé d'utiliser keyup à la place ...

$("#textbox").keyup(function() {alert("Keyup detected!");});

... mais c'est un fait connu que l'événement keyup n'est pas déclenché par un clic droit et coller.

Une solution de contournement? Est-ce que le fait d'avoir les deux auditeurs va poser des problèmes?


^^ Ceci. Vous pouvez avoir autant de gestionnaires d'événements que vous le souhaitez.
Réintégrer Monica Cellio le

Réponses:


298

Lier les deux événements est la manière typique de le faire. Vous pouvez également vous lier à l'événement de collage.

Vous pouvez vous lier à plusieurs événements comme celui-ci:

$("#textbox").on('change keyup paste', function() {
    console.log('I am pretty sure the text box changed');
});

Si vous voulez être pédant à ce sujet, vous devez également vous lier à mouseup pour permettre de faire glisser du texte et ajouter une lastValuevariable pour vous assurer que le texte a réellement changé:

var lastValue = '';
$("#textbox").on('change keyup paste mouseup', function() {
    if ($(this).val() != lastValue) {
        lastValue = $(this).val();
        console.log('The text box really changed this time');
    }
});

Et si vous voulez être super duperpédant, vous devez utiliser une minuterie d'intervalle pour prendre en charge le remplissage automatique, les plugins, etc.

var lastValue = '';
setInterval(function() {
    if ($("#textbox").val() != lastValue) {
        lastValue = $("#textbox").val();
        console.log('I am definitely sure the text box realy realy changed this time');
    }
}, 500);

9
Finalement, quelqu'un a lu la question et a répondu à l'ensemble!
Réintégrer Monica Cellio le

4
.on('change keyup paste', function() {...}tire en fait plusieurs fois! Si j'ai tapé un caractère, puis cliqué à l'extérieur, les événements 'change' et 'keyup' sont tous deux déclenchés, ce qui entraîne l'exécution de la fonction plusieurs fois! Si j'ai cliqué avec le bouton droit de la souris, puis cliqué à l'extérieur, «modifier» et «coller» sont tous deux déclenchés. Zut! En utilisant Ctrl + V pour coller, puis en cliquant à l'extérieur, il déclenche trois fois !!
SNag

1
@SNag oui, donc vous devriez également ajouter une vérification en utilisant une lastValuevariable pour vous assurer qu'elle a réellement changé.
Petah le

1
+1. Cependant, le «changement» est-il même nécessaire ici? Je ne sais pas quel cas cela traiterait qui n'aurait pas déjà été traité au moment où il (le changement) a été déclenché.
Madbreaks

1
L'événement de collage est déclenché avant que le texte ne soit réellement collé
developerbmw

85

Sur les navigateurs modernes, vous pouvez utiliser l' inputévénement :

DEMO

$("#textbox").on('input',function() {alert("Change detected!");});

1
Bien - je n'étais pas au courant. Est-ce une chose HTML5?
Réintégrer Monica Cellio le

4
J'aurais aimé accepter cette réponse, mais comme vous l'avez dit, c'est une solution pour les navigateurs modernes. Mon application Web est destinée aux utilisateurs qui utilisent encore IE8, et cela ne fonctionne pas sur IE8. :( Que puis-je dire .. :(
SNag

Ne se déclenche pas si, par exemple, sélectionnez tout le texte et appuyez sur la touche Supprimer
jjxtra

4
$(this).bind('input propertychange', function() {
        //your code here
    });

Cela fonctionne pour taper, coller, coller avec le bouton droit de la souris, etc.


1
Cela semble être la meilleure solution car il ne déclenche pas plusieurs événements si vous faites quelque chose comme appuyez sur la flèche vers le haut sur un champ numérique.
Justin

Solution simple et efficace
Abdulhameed

4
if you write anything in your textbox, the event gets fired.
code as follows :

HTML:

<input type="text" id="textbox" />

JS:

<script type="text/javascript">
  $(function () {
      $("#textbox").bind('input', function() {
      alert("letter entered");
      });
   });
</script>

2

Essaye ça:

$("#textbox").bind('paste',function() {alert("Change detected!");});

Voir la démo sur JSFiddle .


Comme la question est sur coller, cela ne fonctionne pas. L'événement n'est pas déclenché par un clic droit et un collage.
Dhaval Marthak

Et qu'est-ce que cela a à voir avec l'utilisation de bind()?
Réintégrer Monica Cellio le

il a dit que l'événement keyup n'est pas déclenché quand il fait un clic droit + coller dessus, donc keyupet qu'il change()a son propre comportement typique, donc il veut exécuter l'événement alors pastepourrait être l'option
Dhaval Marthak

Bien sûr, mais cela ne répond toujours pas pourquoi l'utilisation de bindau lieu de on.
Réintégrer Monica Cellio le

0

Essayez le code ci-dessous:

$("#textbox").on('change keypress paste', function() {
  console.log("Handler for .keypress() called.");
});

Comment cela capture-t-il le collage avec la souris, comme mentionné dans la question?
Réintégrer Monica Cellio le

keypress convient car il a dit queevent to be fired on every character change in the textbox
Venkat.R

Si vous lisiez toutes les questions que vous verriez, il a également dit:"...but it's a known fact that the keyup event isn't fired on right-click-and-paste."
Réintégrer Monica Cellio

0

La lecture de vos commentaires m'a amené à une mauvaise solution. Ce n'est pas une bonne façon, je le sais, mais cela peut être une solution.

$(function() {
    $( "#inputFieldId" ).autocomplete({
        source: function( event, ui ) {
            alert("do your functions here");
            return false;
        }
    });
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.