为什么 Event.target 不是 Typescript 中的元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28900077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:36:31  来源:igfitidea点击:

Why is Event.target not Element in Typescript?

typescript

提问by daniel.sedlacek

I simply want to do this with my KeyboardEvent

我只是想用我的 KeyboardEvent 做到这一点

var tag = evt.target.tagName.toLowerCase();

While Event.target is of type EventTarget it does not inherit from Element. So I have to cast it like this:

虽然 Event.target 是 EventTarget 类型,但它不继承自 Element。所以我必须像这样投射:

var tag = (<Element>evt.target).tagName.toLowerCase();

This is probably due to some browsers not following standards, right? What is the correct browser agnostic implementation in TypeScript?

这可能是由于某些浏览器不遵循标准,对吗?TypeScript 中正确的浏览器不可知实现是什么?

PS: I am using jQuery to capture the KeyboardEvent.

PS:我使用 jQuery 来捕获 KeyboardEvent。

采纳答案by JLRishe

It doesn't inherit from Elementbecause not all event targets are elements.

它不会继承自,Element因为并非所有事件目标都是元素。

From MDN:

来自 MDN

Element, document, and window are the most common event targets, but other objects can be event targets too, for example XMLHttpRequest, AudioNode, AudioContext, and others.

元素、文档和窗口是最常见的事件目标,但其他对象也可以是事件目标,例如 XMLHttpRequest、AudioNode、AudioContext 等。

Even the KeyboardEventyou're trying to use can occur on a DOM element or on the window object (and theoretically on other things), so right there it wouldn't make sense for evt.targetto be defined as an Element.

甚至KeyboardEvent您尝试使用的 DOM 元素或 window 对象(理论上也可以在其他事物上)出现,因此将evt.target其定义为Element.

If it is an event on a DOM element, then I would say that you can safely assume evt.target. is an Element. I don't think this is an matter of cross-browser behavior. Merely that EventTargetis a more abstract interface than Element.

如果它是 DOM 元素上的事件,那么我会说您可以安全地假设evt.target. 是一个Element。我不认为这是跨浏览器行为的问题。这EventTarget只是一个比Element.

Further reading: https://typescript.codeplex.com/discussions/432211

进一步阅读:https: //typescript.codeplex.com/discussions/432211

回答by Bangonkali

Using typescript, I use a custom interface that only applies to my function. Example use case.

使用打字稿,我使用了一个仅适用于我的函数的自定义界面。示例用例。

  handleChange(event: { target: HTMLInputElement; }) {
    this.setState({ value: event.target.value });
  }

In this case, the handleChange will receive an object with target field that is of type HTMLInputElement.

在这种情况下,handleChange 将接收一个具有 HTMLInputElement 类型的目标字段的对象。

Later in my code I can use

稍后在我的代码中我可以使用

<input type='text' value={this.state.value} onChange={this.handleChange} />

A cleaner approach would be to put the interface to a separate file.

一种更简洁的方法是将接口放在一个单独的文件中。

interface HandleNameChangeInterface {
  target: HTMLInputElement;
}

then later use the following function definition:

然后稍后使用以下函数定义:

  handleChange(event: HandleNameChangeInterface) {
    this.setState({ value: event.target.value });
  }

In my usecase, it's expressly defined that the only caller to handleChange is an HTML element type of input text.

在我的用例中,明确定义了 handleChange 的唯一调用者是输入文本的 HTML 元素类型。

回答by Simon Epskamp

JLRishe's answer is correct, so I simply use this in my event handler:

JLRishe 的回答是正确的,所以我只是在我的事件处理程序中使用它:

if (event.target instanceof Element) { /*...*/ }

回答by dimpiax

Typescript 3.2.4

打字稿 3.2.4

For retrieving property you must cast target to appropriate data type:

要检索属性,您必须将目标转换为适当的数据类型:

e => console.log((e.target as Element).id)

回答by Maksim Kostromin

With typescript we can leverage type aliases, like so:

使用 typescript,我们可以利用类型别名,如下所示:

type KeyboardEvent = {
  target: HTMLInputElement,
  key: string,
};
const onKeyPress = (e: KeyboardEvent) => {
  if ('Enter' === e.key) { // Enter keyboard was pressed!
    submit(e.target.value);
    e.target.value = '';
    return;
  }
  // continue handle onKeyPress input events...
};

回答by WickyNilliams

Could you create your own generic interface that extends Event. Something like this?

您能否创建自己的通用接口来扩展Event. 像这样的东西?

interface DOMEvent<T extends EventTarget> extends Event {
  target: T
}

Then you can use it like:

然后你可以像这样使用它:

handleChange(event: DOMEvent<HTMLInputElement>) {
  this.setState({ value: event.target.value });
}

回答by hovado

@Bangonkali provide the right answer, but this syntax seems more readable and just nicer to me:

@Bangonkali 提供了正确的答案,但这种语法似乎更具可读性,对我来说也更好:

eventChange($event: KeyboardEvent): void {
    (<HTMLInputElement>$event.target).value;
}