粘贴空格时不会触发 Javascript 输入事件

标签 javascript events

我正在尝试为输入/文本区域字段制作单词计数器/限制器。我相信我的逻辑运作得很好。我有一个在 input 事件上运行的函数,它不仅可以更新剩余单词计数器,还可以处理无需按键即可更改内容的情况(例如粘贴操作)。

如果我尝试复制几个单词并将其粘贴到其中(事件触发并且值被 chop ),则会触发此事件。但是,我发现如果我仅复制并粘贴空格,该事件不会触发。

有谁知道为什么该事件不会在粘贴空白时触发?是否有更好的事件我可以监听以拾取此行为。

这主要是出于个人兴趣,而不是为了真正的项目。所以我的 JS 对旧版浏览器不太友好。

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>

最佳答案

您需要修复此处的逻辑:

if (pressedKey !== pressedKey.trim()) {
  // On last word, no more spaces.
  event.preventDefault();
}

pressedKey 当它是空格时等于 "",无论是复制+粘贴还是仅从空格键,但 pressedKey.trim() 等于 "",因此您可以阻止其余事件监听器触发。

关于粘贴空格时不会触发 Javascript 输入事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46459172/

相关文章:

javascript - 在 ngRepeat 生成的每个表格行下方添加表格行

jsf - 在primefaces中动态允许一定范围的日期

c# - 在 .NET 进程中观看本地进程创建的全局事件

javascript - 如何在成功函数中为多个语句扩展单个语句

javascript - 带下拉菜单的菜单按钮

javascript - ThreeJS 运动 - 在固定时间内绕圈移动

javascript - 如何向 django 添加表情?

Android光传感器不触发事件

wpf - 在事件上使用 Setter

python - 将一个函数绑定(bind)到kivy中的多个动态创建的按钮?