如何用特定的keyCode创建KeyboardEvent

How to create KeyboardEvent with specific keyCode

本文关键字:创建 KeyboardEvent keyCode 何用特      更新时间:2023-09-26

我试图在单元测试中模拟一个keydown事件(angular2/TypeScript)。我并不总是有一个DebugElement可用,所以我试图在本地元素上发出事件。我的问题是如何在创建KeyboardEvent时定义keyCode。keyCode没有定义为KeyboardEventInit定义的一部分,并且在KeyboardEvent本身上,它仅作为只读属性公开。

简单地添加keyCode属性(并将obj类型设置为)也不起作用。

    let elm = <HTMLElement>content.nativeElement;
    let ev = new KeyboardEvent('keydown', {
        code: '123',
        //keyCode: 345,
        key: 'a',
    });
    elm.dispatchEvent(ev);

有什么建议吗?

编辑:根据mdn链接,keyCode已弃用,不应使用,而应使用'code'。https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

我仍然认为这是Typescript方面的一个错误,因为LanguageEvent有初始化项。在任何情况下,一个解决方法是使用Object.define来设置keyCode。

let arrowRight = new KeyboardEvent('keydown');
Object.defineProperty(arrowRight, 'keyCode', {
    get : () => 39
});
console.log(arrowRight.keyCode, arrowRight.key, arrowRight.code);

不管keyCode被弃用,这并不意味着初始化器不应该支持它。最有力的论据是Internet Explorer 9和11依赖于此,它们不支持代码https://caniuse.com/#search=event.code或者完全支持 https://caniuse.com/#search=event.key所以我认为LanguageEvent应该在它的初始化器中允许keyCode。

let arrowRight = new KeyboardEvent('keydown', { keyCode: 39 });

keyCode已被弃用,Angular本身使用key -我建议你也重写你的逻辑来使用它。请记住,它是浏览器依赖-在IE中空格键是Space,在其他浏览器中它是Escape和CC_6也不同。不要记住任何其他不同的

如果你使用angular,你可以设置键盘事件,并在HTML模板中键入键并绑定到你的方法。

参见angular文档:https://angular.io/guide/user-input#key-event-filtering-with-keyenter

既然你不需要测试angular API,因为它不是你要测试的系统,你应该简单地通过将模拟数据传递到你绑定key事件的方法来编写单元测试。


如果你指的是UI/集成测试,那么所有这些都不是特别有用,因为上述内容实际上只适用于单元测试。

或者,如果您想在用户按CTRL+ALT+D时运行一个函数,您的代码将看起来像这样:

 window.addEventListener('keydown', (event: KeyboardEvent) => {
       // Fall back to event.which if event.keyCode is null
       const keycode = event.keyCode || event.which;
       if (keycode === 68 && event.ctrlKey && event.altKey) {
         // Do stuff here
       }
    });

看一下:

<!DOCTYPE html>
<html>
<body>
  <script>
  function EventHandler(e) {
    e = e || window.event;
    var code = typeof e.which !== 'undefined' ? e.which : e.keyCode; 
    if(code == 112 || code == 113 
        || code == 114 || code == 115
        || code == 116 || code == 117
        || code == 118 || code == 119
        || code == 120 || code == 121
        || code == 122 || code == 123) {
      e.returnValue = false;
      var target2 = document.getElementById("iFrameId"); 
      var targetBody = target2.contentDocument.body; 
      var keyboardEvent = document.createEvent("KeyboardEvent");
      Object.defineProperty(keyboardEvent, 'keyCode', {
        get : function() {
          return this.keyCodeVal;
        }
      });
      Object.defineProperty(keyboardEvent, 'which', {
        get : function() {
          return this.keyCodeVal;
        }
      });
      var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
      keyboardEvent[initMethod](
         "keydown", // event type : keydown, keyup, keypress
         true, // bubbles
         true, // cancelable
         window, // viewArg: should be window
         false, // ctrlKeyArg
         false, // altKeyArg
         false, // shiftKeyArg
         false, // metaKeyArg
         code, // keyCodeArg : unsigned long the virtual key code, else 0
         0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
      );
      keyboardEvent.keyCodeVal = code;
      targetBody.dispatchEvent(keyboardEvent);        
    }
  }
  </script>
  <form>
    <input type="text" name="first" onkeydown="EventHandler()" > <br>
    <iframe id="iFrameId" src="frame.html" > </iframe>
  </form>
</body>
</html>