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

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

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

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

我需要做什么才能在文本区看到字母?我目前 运行 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="">

Javascript sending key codes to a <textarea> element

我环顾四周,这似乎比我之前不相关的回答更相关。对于那个很抱歉。我知道这是jquery,但前提是一样的。

在活动中添加这个就可以了

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

这里是纯javascriptjsfiddle

按下某个键时会触发 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';
});

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

希望这对您有所帮助,

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

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

字符实际上是如何进入 input 的?在 MDN 上你可以找到 Keyboardevent sequence 的描述(假设没有调用 preventDefault):

  • A keydown event is first fired. If the key is held down further and the key produces a character key, then the event continues to be emitted in a platform implementation dependent interval and the KeyboardEvent.repeat read only property is set to true.
  • If the key produces a character key that would result in a character being inserted into possibly an <input>, <textarea> or an element with HTMLElement.contentEditable set to true, the beforeinput and input event types are fired in that order. Note that some other implementations may fire keypress event if supported. The events will be fired repeatedly while the key is held down.
  • A keyup event is fired once the key is released. This completes the process.

因此,keydown 默认会导致 input 事件。但这仅适用于 trusted events:

Most untrusted events will not trigger default actions, with the exception of the click event... All other untrusted events behave as if the preventDefault() method had been called on that event.

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

然后如何在 input 上测试 KeyboardEvent

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

如果您仍然需要 KeyboardEvent 处理程序,则取决于其中发生了什么。例如。如果你在某些情况下调用 preventDefault 那么你可以检查它是否在使用间谍的测试中被调用。这是一个使用 sinon as a spy and chai 作为断言库的示例。

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