如何使用自定义键盘事件和keyCode更改输入/textarea值

How to change input/textarea value with custom keyboard event and keyCode?

本文关键字:输入 textarea keyCode 自定义 何使用 键盘 事件      更新时间:2023-09-26

我想通过触发键盘事件来填充文本区域,例如keydown(我这样做是为了测试用例)。

我添加了一个片段(如下)来显示我用于创建和触发事件的代码。事件触发,但文本区域从未接收到字母A的keyCode值。

我需要做什么才能在文本区看到这封信?我目前正在Chrome控制台中运行这个片段,但它也应该在IE9中运行。

var t = document.getElementById('foo');
// Event creation
var event = document.createEvent('HTMLEvents');
event.initEvent('keydown', true, true);
event.keyCode = 65;
event.which = 65;
// Listener for demo purpose
t.addEventListener('keydown', function (e) {
  document.getElementById('fired').value = e.type + ' fired';
});
// Event trigger
t.dispatchEvent(event);
<textarea id="foo"></textarea>
<br>
<input id="fired" value="">

为什么触发keydown后值没有变化

简而言之:不能通过编程方式调度KeyboardEvent来更改input/texarea的值。

字符实际上是如何进入input的?在MDN上,您可以找到键盘事件序列的描述(假设未调用preventDefault):

  • 首先激发keydown事件。如果该键被进一步按下,并且该键生成一个字符键,那么该事件将继续在依赖于平台实现的间隔中发出,并且KeyboardEvent.repeat只读属性将设置为true
  • 如果该键生成的字符键可能会导致字符插入到<input><textarea>或HTMLElement.contentEditable设置为true的元素中,则beforeinputinput事件类型将按该顺序激发。请注意,如果支持,某些其他实现可能会激发keypress事件。当按键按下时,事件将被反复触发
  • 一旦释放密钥,就会触发密钥设置事件。这就完成了这个过程

因此,默认情况下keydown会导致input事件。但这只适用于可信事件:

大多数不受信任的事件不会触发默认操作,click事件除外。。。所有其他不受信任的事件的行为就好像对该事件调用了preventDefault()方法一样。

基本上,可信事件是由用户发起的事件,而不可信事件是通过脚本发起的。在大多数浏览器中,每个事件都有一个属性isTrusted,指示该事件是否可信。

那么如何在inputs上测试KeyboardEvents呢

首先,考虑一下您是否真的需要一个KeyboardEvent处理程序。也许您可以在InputEvent处理程序中完成所有操作。这意味着您可以在测试中设置input的值,然后触发InputEvent

如果你仍然需要KeyboardEvent处理程序,这取决于它中发生了什么。例如,如果你在某些条件下调用preventDefault,那么你可以使用间谍检查它是否在测试中被调用。这里有一个例子,西农是间谍,柴是断言库。

const myEvent = new KeyboardEvent('keydown', { key: 'a' })
sinon.spy(myEvent, 'preventDefault')
document.getElementById('foo').dispatchEvent(myEvent)
expect(myEvent.preventDefault.calledOnce).to.equal(true)

按下键时会触发keydown事件,但它不负责在DOM元素中写入数据。

问题是;如果用户首先在<textarea>上写入,则字符将添加到元素值中,然后触发keyDown事件。然而,在您的情况下,您是直接触发事件的,因此将字符添加到<textarea>值的第一步不会发生。

您有两个选项,以浏览器的方式编写值,然后发送事件

t.value = t.value + String.fromCharCode(e.keyCode);
t.addEventListener('keydown', function (e) {
  document.getElementById('fired').value = e.type + ' fired';
});

也可以在keyDown事件上写入<textarea>的值:

// Listener for demo purpose
t.addEventListener('keydown', function (e) {
  t.value = t.value + String.fromCharCode(e.keyCode);
  document.getElementById('fired').value = e.type + ' fired';
});

但是,如果您想使用第二种方法进行用户交互,这是无稽之谈,因为在用户输入数据的情况下,数据将被写入两次(一次用于用户输入,另一次用于事件)。

希望这有帮助,

Javascript向<text区域>元件

我环顾四周,这似乎比我之前的非相关答案更相关。很抱歉。我知道这是jquery,但前提是一样的。

在事件中添加此项将工作

document.getElementById('foo').innerHTML += String.fromCharCode(e.keyCode);

这里是纯javascript jsfiddle