J'essaie de créer un compteur/un limiteur de mots pour les champs d'entrée/de zone de texte. Je crois que ma logique fonctionne assez bien. J'ai une fonction en cours d'exécution sur l'événement input
qui sert à la fois à mettre à jour le compteur de mots restants, mais également à gérer les cas où le contenu est modifié sans appuyer sur une touche (opération de collage, par exemple).L'événement d'entrée Javascript ne se déclenche pas lorsque vous collez des espaces
Cet événement est déclenché si j'essaie de copier quelques mots et de les coller (l'événement se déclenche et la valeur est tronquée). Cependant, j'ai trouvé que si je ne fais que copier et coller des espaces, l'événement ne se déclenche pas.
Est-ce que quelqu'un sait pourquoi l'événement ne se déclencherait pas lors du collage des espaces? Y at-il un meilleur événement que je peux écouter pour ramasser ce comportement.
Ceci est principalement par intérêt personnel, pas pour un vrai projet. Donc, mon JS n'est pas très amical avec les anciens navigateurs.
function limitFieldKeyDown(event) {
const maxWords = parseInt(this.getAttribute('data-word-limit'), 10);
// See what character was entered.
let pressedKey = event.key;
// Check against special keys
if (pressedKey.length > 1) {
pressedKey = '';
}
// Get text (including pressed key).
const text = `${this.value}${pressedKey}`.trim();
// Get the count of words
let words;
if (text === '') {
// Handle special case of empty string
words = [];
}
else {
words = text.split(/\s+/);
}
const currentWordCount = words.length;
if (currentWordCount >= maxWords) {
// Detect if the word was whitespace.
if (pressedKey !== pressedKey.trim()) {
// On last word, no more spaces.
event.preventDefault();
}
}
}
function truncateToWords(text, words, limit) {
let currentIndex = 0;
// Find the character position which matches the current word limit.
for (let i = 0; i < limit; i++) {
currentIndex = text.indexOf(words[i], currentIndex) + words[i].length;
}
// Truncate the text to position.
return text.substring(0, currentIndex);
}
function limitFieldInput() {
const maxWords = parseInt(this.getAttribute('data-word-limit'), 10);
let text = this.value.trim();
let words;
if (text === '') {
// Handle special case of empty string
words = [];
}
else {
words = text.split(/\s+/);
}
let currentWordCount = words.length;
// Check if text is longer than maximum
if (currentWordCount > maxWords) {
// Longer than maximum, truncate.
text = truncateToWords(text, words, maxWords);
// Update variables with truncated text.
this.value = text;
words = text.split(/\s+/);
currentWordCount = words.length;
}
// Update the word counter.
const counterFields = this.parentNode.querySelectorAll('span.word-limit');
if (counterFields.length > 0) {
const remainingWords = maxWords - currentWordCount;
for (let i = 0; i < counterFields.length; ++i) {
counterFields[i].innerText = `${remainingWords} remaining`;
}
}
}
function limitField(field) {
field.addEventListener('keydown', limitFieldKeyDown);
field.addEventListener('input', limitFieldInput);
const event = new KeyboardEvent('keydown');
field.dispatchEvent(event);
const event2 = new Event('input');
field.dispatchEvent(event2);
}
const limtiedFields = document.querySelectorAll('textarea.word-limit');
for (let i = 0; i < limtiedFields.length; ++i) {
// Run on every keydown event.
limitField(limtiedFields[i]);
}
<div>
<textarea class="word-limit" data-word-limit="5"></textarea>
<span class="word-limit"></span>
</div>
J'ai essayé de désactiver cette section de code mais cela ne semble pas être la cause. 'event.preventDefault()' ne devrait pas arrêter la propagation de l'événement. – Dracs