Le meilleur moyen de suivre les modifications au fur et à mesure de la saisie dans type d'entrée = "texte"?

449

D'après mon expérience, l' input type="text" onchangeévénement ne se produit généralement qu'après avoir quitté ( blur) le contrôle.

Existe-t-il un moyen de forcer le navigateur à se déclencher à onchangechaque fois que le textfieldcontenu change? Sinon, quelle est la manière la plus élégante de suivre cela «manuellement»?

L'utilisation d' onkey*événements n'est pas fiable, car vous pouvez cliquer avec le bouton droit sur le champ et choisir Coller, ce qui modifiera le champ sans aucune saisie au clavier.

Est-ce setTimeoutle seul moyen? .. Moche :-)

Ilya Birman
la source
@ Y a-t-il une chance que vous puissiez mettre à jour votre réponse acceptée afin que celle qui n'est pas à jour ne soit pas épinglée en haut?
Flimm

Réponses:

271

Mise à jour:

Voir Une autre réponse (2015).


Réponse originale de 2009:

Donc, vous voulez que l' onchangeévénement se déclenche lors du keydown, du flou et du collage? C'est magique.

Si vous souhaitez suivre les modifications au fur et à mesure de leur saisie, utilisez "onkeydown". Si vous devez intercepter les opérations de collage avec la souris, utilisez "onpaste"( IE , FF3 ) et "oninput"( FF, Opera, Chrome, Safari 1 ).

1 Broken for <textarea>sur Safari. Utiliser à la textInputplace

Croissant frais
la source
22
onkeypressdoit être utilisé à la place de onkeydown. onkeydownse déclenche lorsqu'une touche est enfoncée. Si un utilisateur maintient une touche enfoncée, l'événement ne se déclenchera qu'une seule fois pour le premier personnage. onkeypressse déclenche chaque fois qu'un caractère est ajouté au champ de texte.
fent
61
Ce n'est pas tout à fait magique de faire onchangefeu sur toutes ces actions. <input onchange="doSomething();" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();">fera assez bien pour la plupart.
2012
1
Qu'en est-il de la suppression de texte dans la zone de saisie à l'aide de la souris? Je ne pense pas que cela fonctionnera.
Jeevan
47
Avec jquery 1.8.3, on dirait:$().on('change keydown paste input', function() {})
Narfanator
4
@AriWais: OUI, omg la plupart des SO devraient être dépréciés. Les gens cette réponse a 8 ans . Je souhaite qu'il y ait un bouton "obsolète" pour les anciennes réponses comme celle-ci, et que la communauté puisse choisir la meilleure.
Crescent Fresh du
658

Ces jours-ci, écoutez oninput. On se sent comme onchangesans avoir besoin de perdre le focus sur l'élément. C'est HTML5.

Il est pris en charge par tout le monde (même mobile), sauf IE8 et les versions antérieures. Pour IE, ajoutez onpropertychange. Je l'utilise comme ceci:

const source = document.getElementById('source');
const result = document.getElementById('result');

const inputHandler = function(e) {
  result.innerHTML = e.target.value;
}

source.addEventListener('input', inputHandler);
source.addEventListener('propertychange', inputHandler); // for IE8
// Firefox/Edge18-/IE9+ don’t fire on <select><option>
// source.addEventListener('change', inputHandler); 
<input id="source">
<div id="result"></div>

Robert Siemer
la source
63
Dans un monde en constante évolution comme les standards du Web, la réponse acceptée peut parfois être modifiée après quelques années ... C'est la nouvelle réponse acceptée pour moi.
Erick Petrucelli
1
La prise en charge de oninputmême dans IE9 est cependant partielle ( caniuse.com/#feat=input-event ).
Kenston Choi
Il peut être utile d'utiliser innerTextà la place de innerHTMLsorte qu'aucune majoration ne soit rendue
Jeevan Takhar
47

Le code ci-dessous fonctionne bien pour moi avec Jquery 1.8.3

HTML: <input type="text" id="myId" />

Javascript / JQuery:

$("#myId").on('change keydown paste input', function(){
      doSomething();
});
Amrit Pal Singh
la source
11
La bibliothèque jQuery n'est pas balisée dans la question.
John Weisz
21
Jquery est une API Javascript, et j'ai été amené ici par une recherche avec le mot-clé Jquery, je ne pense pas que cela vaut la peine de créer une nouvelle question pour chaque question javascript pour la réponse Jquery ...
GaelDev
12
Si les gens n'étaient pas autorisés à suggérer l'utilisation de bibliothèques dans les réponses, il y aurait BEAUCOUP plus de questions sans réponse sur SO
dietbacon
3
Se déclenche plusieurs fois. Probablement en raison de changements et de keydown. La saisie probable n'est nécessaire que ici.
mmm
1
vous n'avez pas besoin du keydowncar il va dupliquer la valeur de l'entrée, supprimez-le.
Youssef Al Subaihi
43

Javascript est imprévisible et amusant ici.

  • onchange se produit uniquement lorsque vous brouillez la zone de texte
  • onkeyup& onkeypressne se produit pas toujours lors d'un changement de texte
  • onkeydown se produit lors du changement de texte (mais ne peut pas suivre le copier-coller avec un clic de souris)
  • onpaste& oncutse produit en appuyant sur la touche et même avec le clic droit de la souris.

Ainsi, pour suivre le changement de zone de texte, nous avons besoin onkeydown, oncutet onpaste. Dans le rappel de ces événements, si vous vérifiez la valeur de la zone de texte, vous n'obtenez pas la valeur mise à jour car la valeur est modifiée après le rappel. Une solution consiste donc à définir une fonction de temporisation avec une temporisation de 50 mili-secondes (ou peut-être moins) pour suivre le changement.

C'est un hack sale mais c'est le seul moyen, comme je l'ai recherché.

Voici un exemple. http://jsfiddle.net/2BfGC/12/

Sanket Sahu
la source
4
oninputet textInputsont les événements qui est la solution réelle pour cela, mais ce n'est pas pris en charge par tous les navigateurs.
Sanket Sahu
Pour le deuxième point, je suppose que vous vouliez dire onkeyupet onkeydown, qui sont similaires. Les deux peuvent capturer les touches Ctrl, Alt, Maj et Meta. Pour le troisième point, je suppose que vous vouliez dire onkeypress.
Daniel Stevens
12

onkeyupse produit après avoir tapé par exemple j'appuie tlorsque je lève le doigt l'action se produit mais keydownl'action se produit avant que je ne chiffre le caractèret

J'espère que cela est utile pour quelqu'un.

Il onkeyupvaut donc mieux quand vous voulez envoyer ce que vous venez de taper maintenant.

Fernando André
la source
8

J'avais une exigence similaire (champ de texte de style Twitter). Utilisé onkeyupet onchange. onchangeprend réellement en charge les opérations de collage de la souris lors de la perte de focus du champ.

[Mettre à jour] En HTML5 ou version ultérieure, utilisez oninputpour obtenir des mises à jour en temps réel des modifications de caractères, comme expliqué dans les autres réponses ci-dessus.

Mohnish
la source
L'entrée est utile si vous voulez détecter quand le contenu d'une zone de texte, entrée: texte, entrée: mot de passe ou entrée: élément de recherche a changé, car l'événement onchange sur ces éléments se déclenche lorsque l'élément perd le focus, pas immédiatement après la modification .
hkasera
@hkasera Oui, avec HTML5 oninputest la voie à suivre. Mais, quand j'ai implémenté, HTML5 n'existait pas et nous avions IE 8 :(. J'apprécie votre mise à jour car elle fournit des informations à jour pour les utilisateurs.
Mohnish
7

Si vous utilisez UNIQUEMENT Internet Explorer, vous pouvez utiliser ceci:

<input type="text" id="myID" onpropertychange="TextChange(this)" />

<script type="text/javascript">
    function TextChange(tBox) {
        if(event.propertyName=='value') {
            //your code here
        }
    }
</script>

J'espère que cela pourra aider.

RolandDeschain
la source
8
Cela pourrait être pour un projet interne, je suppose ... :)
eselk
94
Dieu merci, je ne vis pas dans cette maison! : D
Marco Matarazzi
13
Il y a 10 ans, il n'y aurait rien de drôle dans cette phrase .. :(
Michał Tabor
4
pour moi, cela aide, je développe un projet pour certains mobiles avec un système d'exploitation intégré où IE est le seul navigateur.
Anders M.
3
Si vous utilisez UNIQUEMENT Internet Explorer - LOL. J'ai fait ma journée en 2016!
Jack Black
4

il existe une solution assez proche (ne corrigez pas toutes les méthodes de collage) mais la plupart d'entre elles:

Cela fonctionne pour les entrées ainsi que pour les zones de texte:

<input type="text" ... >
<textarea ... >...</textarea>

Fait comme ça:

<input type="text" ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >
<textarea ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >...</textarea>

Comme je l'ai dit, toutes les façons de coller ne déclenchent pas un événement sur tous les navigateurs ... pire, certains ne déclenchent aucun événement, mais les minuteries sont horribles à utiliser pour cela.

Mais la plupart des méthodes de collage se font avec le clavier et / ou la souris, donc normalement un onkeyup ou onmouseup est déclenché après un collage, également onkeyup est déclenché lors de la frappe au clavier.

Assurez-vous que votre code de vérification ne prend pas beaucoup de temps ... sinon l'utilisateur obtient une mauvaise impression.

Oui, l'astuce consiste à tirer sur la touche et sur la souris ... mais attention, les deux peuvent être tirés, alors gardez cela à l'esprit !!!

z666zz666z
la source
4

Veuillez évaluer la prochaine approche à l'aide de JQuery:

HTML:

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

Javascript (JQuery):

$("#inputId").keyup(function(){
        $("#inputId").blur();
        $("#inputId").focus();
});

$("#inputId").change(function(){
        //do whatever you need to do on actual change of the value of the input field
});
Alex Uke
la source
J'utilise de la même manière
:)
Je me rends compte que ce n'est pas la réponse la plus récente, mais ne brouillerait-il pas et ne recentrerait-il pas l'entrée sur chaque touche pour bousiller le placement du curseur si c'était n'importe où sauf à la fin de l'entrée?
Michael Martin-Smucker
@ MichaelMartin-Smucker On pourrait le penser, mais apparemment pas: jsfiddle.net/gsss8c6L
Clonkex
4

"input" a fonctionné pour moi.

var searchBar  = document.getElementById("searchBar");
searchBar.addEventListener("input", PredictSearch, false);
Sam
la source
3

Vous pouvez utiliser les keydown, keyupet les keypressévénements ainsi.

Gombo
la source
3

Pour suivre chacun, essayez cet exemple et, avant cela, réduisez complètement le taux de clignotement du curseur à zéro.

<body>
//try onkeydown,onkeyup,onkeypress
<input type="text" onkeypress="myFunction(this.value)">
<span> </span>
<script>
function myFunction(val) {
//alert(val);
var mySpan = document.getElementsByTagName("span")[0].innerHTML;
mySpan += val+"<br>";
document.getElementsByTagName("span")[0].innerHTML = mySpan;
}
</script>

</body>

onblur: l'événement génère à la sortie

onchange: l'événement est généré à la sortie si des modifications sont apportées au texte d'entrée

onkeydown: l'événement est généré à n'importe quelle pression sur une touche (pour une pression prolongée sur une touche également)

onkeyup: l'événement est généré sur n'importe quelle libération de clé

onkeypress: identique à onkeydown (ou onkeyup) mais ne réagit pas pour ctrl, backsace, alt autre

Venkat
la source
1

2018 ici, c'est ce que je fais:

$(inputs).on('change keydown paste input propertychange click keyup blur',handler);

Si vous pouvez signaler des failles dans cette approche, je vous en serais reconnaissant.

a20
la source
2
2019 ici, et cela se déclenchera plusieurs fois pour chaque pression de touche. Pour un exemple, voir ici: jsfiddle.net/sp00n82/3r4691tq/5
sp00n
1

Méthode 1: ajouter un écouteur d'événements pour input:

element.addEventListener("input", myFunction);

 

Méthode 2: définissez la oninputpropriété avec JavaScript:

element.oninput = function()
{
    myFunction();
};

 

Méthode 3: définissez la oninputpropriété avec HTML:

<input type="text" oninput="myFunction();">
Pikamander2
la source
0

Robert Siemer addEventListener n'est pas pris en charge dans IE8.

"Les anciennes versions d'IE prenaient en charge une méthode EventTarget.attachEvent () propriétaire équivalente." https://developer.mozilla.org/it/docs/Web/API/Element/addEventListener

bpolelli
la source
cela ressemble plus à un commentaire à une réponse existante qu'à une nouvelle réponse
slfan