J'ai une zone de texte régulière:
<input type="text">
J'utilise jQuery pour gérer les événements liés aux clés:
$("input:text").keydown(function() {
// keydown code
}).keypress(function() {
// keypress code
}).keyup(function() {
// keyup code
});
L'utilisateur se concentre sur une zone de texte et appuie sur différentes touches de son clavier (les habituelles: lettres, chiffres, MAJ, RETOUR ARRIÈRE, ESPACE, ...). J'ai besoin de détecter quand l'utilisateur appuie sur une touche qui va augmenter la longueur de la valeur de la zone de texte. Par exemple, la touche "A" l'augmentera, la touche "SHIFT" ne le fera pas.
Je me souviens avoir regardé une conférence de PPK où il a mentionné la différence entre ces deux. Cela a quelque chose à voir avec l'événement - keydown vs keypress - et éventuellement avec les propriétés de l'événement - key, char, keyCode.
Mettre à jour !
J'ai besoin de connaître ces informations dans les gestionnaires de touches ou de touches. Je ne peux pas attendre que l'événement keyup se produise.
Pourquoi j'en ai besoin:
J'ai une zone de texte dont la taille change dynamiquement en fonction de l'entrée utilisateur. Vous pouvez jeter un œil à cette démo: http://vidasp.net/tinydemos/variable-size-text-box.html
Dans la démo, j'ai un gestionnaire de keydown et de keyup. Le gestionnaire de touches ajuste la taille de la zone de texte en fonction de la valeur d'entrée. Cependant, le gestionnaire de keydown définit la taille à 1 caractère de plus que la valeur d'entrée. La raison pour laquelle je fais cela est que si je ne le faisais pas, alors le caractère déborderait en dehors de la zone de texte et seulement lorsque l'utilisateur relâcherait la clé, la zone de texte se développerait. Ça a l'air bizarre. C'est pourquoi je dois anticiper le nouveau caractère - j'agrandis la zone de texte sur chaque touche, ergo, avant que le caractère n'apparaisse dans la zone de texte. Comme vous pouvez le voir dans la démo, cette méthode a fière allure.
Cependant, le problème provient des touches RETOUR ARRIÈRE et FLÈCHE - elles développeront également la zone de texte lors de la frappe, et uniquement lors de la frappe, la taille de la zone de texte sera corrigée.
Une solution de contournement:
Une solution de contournement serait de détecter manuellement les touches RETOUR ARRIÈRE, MAJ et FLÈCHE et d'agir en fonction de cela:
// keydown handler
function(e) {
var len = $(this).val().length;
if (e.keyCode === 37 || e.keyCode === 39 ||
e.keyCode === 16) { // ARROW LEFT or ARROW RIGHT or SHIFT key
return;
} else if (e.keyCode === 8) { // BACKSPACE key
$(this).attr("size", len <= 1 ? 1 : len - 1);
} else {
$(this).attr("size", len === 0 ? 1 : len + 1);
}
}
Cela fonctionne (et a fière allure) pour RETOUR ARRIÈRE, MAJ, FLÈCHE GAUCHE et FLÈCHE DROITE. Cependant, j'aimerais avoir une solution plus robuste.
Je pense que cela fera le travail, ou sinon il est très proche et ne nécessitera que des ajustements mineurs. La chose dont vous devez vous souvenir est que vous ne pouvez rien dire de manière fiable sur un caractère pouvant être tapé dans un événement keydown
ou keyup
: tout doit être fait dans un keypress
gestionnaire. La ressource définitive pour les événements clés est http://unixpapa.com/js/key.html
Vous devez également prendre en compte les pâtes, que ce code ne gère pas. Vous aurez besoin d'avoir un gestionnaire d'événements paste
distinct (bien que cet événement ne soit pas pris en charge dans Firefox <3.0, Opera et les très anciens navigateurs WebKit). Vous aurez besoin d'une minuterie dans votre gestionnaire de collage car il est impossible en JavaScript d'accéder au contenu qui est sur le point d'être collé.
function isCharacterKeyPress(evt) {
if (typeof evt.which == "undefined") {
// This is IE, which only fires keypress events for printable keys
return true;
} else if (typeof evt.which == "number" && evt.which > 0) {
// In other browsers except old versions of WebKit, evt.which is
// only greater than zero if the keypress is a printable key.
// We need to filter out backspace and ctrl/alt/meta key combinations
return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
}
return false;
}
<input type="text" onkeypress="alert(isCharacterKeyPress(event))">
Voici une solution beaucoup plus simple qui a bien fonctionné pour moi:
document.addEventListener('keyup', event => {
if (String.fromCharCode(event.keyCode).match(/(\w|\s)/g)) {
//pressed key is a char
} else {
//pressed key is a non-char
//e.g. 'esc', 'backspace', 'up arrow'
}
});
Cela ne nécessite pas de sonder un élément DOM (ce qui ajouterait de la latence et de la laideur).
Exemple d'utilisation mise à jour:
La solution possible que je peux trouver est de vérifier la longueur de la clé dans l'événement.
Par exemple:-
<input type="text" id="testId" onkeyup="keyChecking(event)" />
<script type="text/javascript">
function keyChecking(event) {
if (event.key.length == 1) {
alert("key produced character " + event.key);
} else {
alert("Key DOES NOT produce character");
const alphabets = "AZaz09";
const key = event.key;
var notEvenASymbol = false;
for (let i = 0; i < key.length; i++) {
var charCode = key.charCodeAt(i);
if ((charCode >= alphabets.charCodeAt(0) && charCode <= alphabets.charCodeAt(1)) ||
(charCode >= alphabets.charCodeAt(2) && charCode <= alphabets.charCodeAt(3)) ||
(charCode >= alphabets.charCodeAt(4) && charCode <= alphabets.charCodeAt(5))
) {
notEvenASymbol = true;
console.log(charCode);
break;
}
}
if (notEvenASymbol) {
alert("Key DOES NOT produce even a symbol");
}
console.log(event.key);
}
}
</script>
Donc, si vous appuyez sur des caractères/symboles, le event.key
contiendra ce caractère et sa longueur sera 1. Si vous appuyez sur caractère [~ # ~] v [~ # ~] , puis le event.key
aura une valeur [~ # ~] v [~ # ~] mais si vous appuyez sur la touche Entrée, il contiendra de la valeur Entrez , si vous appuyez sur shift puis Shift et ainsi de suite. Par conséquent, si une clé ne produit pas de caractère, sa longueur sera supérieure à 1.
mis à jour
Certaines touches spéciales du clavier produisent un symbole et sa longueur peut être supérieure à 1, j'ai donc modifié le code pour qu'il puisse alerter même s'il ne s'agit pas d'un symbole. Par exemple:- ???? sa longueur est de 2. Certains claviers mobiles ont des touches de raccourci pour ces symboles.
Une touche non caractère/symbole du clavier sera toujours une combinaison d'alphabets, de chiffres ou des deux, par exemple: - F2 , Maj .
Merci à @Vicky Chijwani d'avoir attiré l'attention sur ce scénario.
OK, je pense que je l'ai. La solution est un peu hackeuse, mais fonctionne vraiment très bien.
Lors du keydown, effectuez un setTimeout pendant 1 milliseconde, qui appelle une fonction pour vérifier/modifier la longueur de votre zone de saisie.
http://jsfiddle.net/rygar/e2wQM/
Cela semble très bien fonctionner, en particulier dans certains endroits où votre version ne fonctionne pas (par exemple, retour arrière, CTRL + V, ou sélectionner tout un tas de texte et appuyer sur Supprimer)
Edit: Même setTimeout avec un retard de 0 ms semble fonctionner!
Vous devez utiliser la propriété keyEventArgs.Key dans la fonction keydown, cela renverra la valeur numérique qui dépendra du système.
voici un lien qui a les différents codes clés pour les différents navigateurs et OS:
Ce n'est peut-être pas la méthode que vous recherchez, mais vous pouvez simplement vérifier la valeur de this.value.length
dans votre fonction keydown. La valeur de retour est la longueur du texte dans le champ de saisie AVANT d'ajouter le nouveau caractère. Donc, si vous vérifiez à nouveau la longueur dans la fonction de saisie, elle sera plus grande si l'utilisateur a appuyé sur un caractère, mais la même chose si l'utilisateur a appuyé sur la touche Maj.
Je suppose que vous configurez un compteur sur la longueur d'un champ de saisie, auquel cas vous n'avez pas besoin d'être aussi sophistiqué, vous pouvez simplement continuer d'affecter la longueur du champ à une variable, et lorsque l'utilisateur accède à votre la longueur maximale ne leur permet que d'appuyer sur la suppression ou le retour arrière comme ceci:
$("input:text").keypress(function() {
var current = $(this).val().length;
if (current >= 130) {
if (e.which != 0 && e.which != 8) {
e.preventDefault();
}
}
}
Vous pouvez également utiliser la variable actuelle pour afficher le compteur, ou faire maxlength - current pour faire un compte à rebours du nombre de caractères restant
Votre objectif de garder la zone de texte plus grande que le texte qui y a été saisi.
J'accomplirais cela en prévoyant d'avoir de la place pour deux caractères supplémentaires (pas un) dans la zone de texte. Ensuite:
// pseudo-code....
old_len = textbox.value.length
keyUp function() {
var new_len = textbox.value.length
if (new_len != old_len) {
old_len = new_len
textbox.style.size = new_len + 2 // pseudo code.
}
}
L'avantage de ce qui précède est que vous n'avez pas besoin de descendre dans le monde inférieur des codes clés.