在 keydown 上,为啥值的 console.log 与将值分配给对象不同?

Posted

技术标签:

【中文标题】在 keydown 上,为啥值的 console.log 与将值分配给对象不同?【英文标题】:On keydown why does a console.log of the value differ to assigning the value to an object?在 keydown 上,为什么值的 console.log 与将值分配给对象不同? 【发布时间】:2020-08-08 03:37:05 【问题描述】:

当我在文本框中键入并在 Chrome 中控制台记录 keydown 事件时,我可以看到它有很多属性(特别是我正在尝试访问 KeyboardEvent.code)。

控制台输出


altKey: false
bubbles: true
cancelBubble: false
cancelable: true
charCode: 0
code: "Tab"
composed: true
ctrlKey: false
currentTarget: null
defaultPrevented: true
detail: 0
eventPhase: 0
isComposing: false
isTrusted: true
key: "Tab"
keyCode: 9
location: 0
metaKey: false
path: (25) [input#My-monthly-budget.form-control.p-0.border-left-0.spec--money-input.ng-untouched.ng-invalid.is…, div.input-group.is-invalid, div.fc-col-input, div.fc-row, finance-control-money.col-sm-12.my-2.my-md-3.my-lg-0.col-lg-3, div.row.mb-1.pb-2.ng-star-inserted, finance-filters-section.mt-5.mt-lg-3.pt-1, div.finance-filters-container, section#finance-filters.ng-star-inserted, finance-section.ng-star-inserted, section.pl-3.py-3, div.ng-tns-c15-4.ng-trigger.ng-trigger-toggleAccordion, div.py-3, personalise-journey-step-accordion#personalise-funding.ng-tns-c15-4, div.container.mt-5, ng-component.ng-star-inserted, ng-component.ng-star-inserted, div.position-relative.pt-5.ng-trigger.ng-trigger-routerTransition, div.ng-tns-c3-1, ng-component.ng-tns-c3-1.ng-star-inserted, app-root, body#login-page.login-page.system-page.live.auth-page, html, document, Window]
repeat: false
returnValue: false
shiftKey: false
sourceCapabilities: InputDeviceCapabilities firesTouchEvents: false
srcElement: input#My-monthly-budget.form-control.p-0.border-left-0.spec--money-input.ng-untouched.ng-invalid.is-invalid.ng-dirty
target: input#My-monthly-budget.form-control.p-0.border-left-0.spec--money-input.ng-untouched.ng-invalid.is-invalid.ng-dirty
timeStamp: 11386.555000091903
type: "keydown"
view: Window parent: Window, opener: null, top: Window, length: 0, frames: Window, …
which: 9

但是当我将此值分配给一个对象时,我可以访问的唯一属性是“isTrusted”

对象值

 "isTrusted": true 

可以在下面的 CodePen 中看到一个示例

https://codepen.io/aidanbiggs/pen/KKdWmBQ

HTML

<my-app></my-app>

TypeScript

// import does not work in Codepen
// using const instead
const Component, HostListener = ng.core;
const bootstrap = ng.platform.browser;

@Component(
    selector: 'my-app',
    template: '<div style="padding:1rem; display:flex; flex-direction: column"><input placeholder="Type here to see"> <div style="margin-top:1rem;">Event has property "code": value</div><div style="margin:1rem 0">Event:</div><span style="border:1px solid black; padding:1rem">event | json</span><div style="margin-top:1rem">View console to see difference between object and console.log</div>'
)
class AppComponent 
  public value:boolean ;
  public event: KeyboardEvent;
@HostListener('keydown', ['$event'])
    public onKeyDown(event: KeyboardEvent): boolean 
      this.value = event.hasOwnProperty('code');
      this.event = event;
      console.log(event)
    

bootstrap(AppComponent);

为什么事件的console.log()和分配事件有区别?

【问题讨论】:

并非所有事物都有自己的属性,因此您必须手动克隆事件:cloning javascript event object 和 How to clone or re-dispatch DOM events? 【参考方案1】:

为什么事件的console.log()和分配事件有区别?

没有区别,您会看到不同的输出,因为 json 管道 (event | json) 执行 JSON.stringify 以将值转换为其 JSON 格式表示。 Source

您可以找到有关JSON.stringify 工作原理here 的更多信息


因此,如果您将日志更新为 console.log(JSON.stringify(event)) - 您将获得完全相同的输出。

【讨论】:

另外,我认为他们可能有兴趣从事件中获取按键的代码。 感谢您的信息,它确实做同样的事情。能够查看我的键盘事件是否具有“代码”属性然后如果我无法从对象访问它的最佳方法是什么? 我不确定我是否理解这个问题。只需使用event.code @AlekseyL.我需要在读取它之前检查该属性是否存在,因为 IE11 不会调度 KeyboardEvent.code。所以我想检查对象是否具有该属性,如果它有,那么我使用this.value = event.code,但如果它没有,那么我使用this.value = event.key @aidanbiggs this.value = event.code || event.keythis.value = event.code ?? event.key

以上是关于在 keydown 上,为啥值的 console.log 与将值分配给对象不同?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Windows 在 KeyDown 上播放哔声,但在 DoubleClick 上不播放?

keyup、keydown 和 keypress 事件在移动设备上不起作用

我不明白为啥 CSS 转换在 keydown 上不起作用 [重复]

为啥 JQuery keydown 适用于窗口而不适用于文本框?

为啥我的 WPF KeyDown 处理程序没有捕获 CTRL+A?

为啥“console.log()”在这个网站上不起作用?