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

时间:2015-03-06 13:43:25

标签: typescript

我只想用我的KeyboardEvent

来做这件事
var tag = evt.target.tagName.toLowerCase();

虽然Event.target的类型为EventTarget,但它不会从Element继承。所以我必须这样投:

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

这可能是因为有些浏览器没有遵循标准,对吧? TypeScript中与浏览器无关的正确实现是什么?

PS:我正在使用jQuery来捕获KeyboardEvent。

11 个答案:

答案 0 :(得分:35)

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

From MDN

  

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

即使您尝试使用的KeyboardEvent也可能出现在DOM元素或窗口对象上(理论上也可能出现在其他事物上),所以就在那里evt.target对{ {1}}被定义为Element

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

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

答案 1 :(得分:24)

使用typescript,我使用仅适用于我的函数的自定义界面。用例示例。

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

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

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

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

更简洁的方法是将接口放到单独的文件中。

interface HandleNameChangeInterface {
  target: HTMLInputElement;
}

然后使用以下函数定义:

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

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

答案 2 :(得分:12)

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

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

答案 3 :(得分:8)

打字稿3.2.4

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

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

答案 4 :(得分:6)

您能否创建扩展Event的自己的通用接口。像这样吗?

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

然后您可以像使用它一样

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

答案 5 :(得分:2)

使用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...
};

答案 6 :(得分:1)

只需使用e.currentTarget代替e.target,它已经被正确键入

答案 7 :(得分:0)

@Bangonkali提供了正确的答案,但是这种语法似乎更易读,对我而言更好:

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

答案 8 :(得分:0)

我使用这个:

onClick({ target }: MouseEvent) => {
    const targetDivElement: HTMLDivElement = target as HTMLDivElement;
    
    const listFullHeight: number = targetDivElement.scrollHeight;
    const listVisibleHeight: number = targetDivElement.offsetHeight;
    const listTopScroll: number = targetDivElement.scrollTop;
}

答案 9 :(得分:0)

在处理来自 input 字段的事件时,我通常会遇到这个问题,比如 key up。但请记住,该事件可能源于任何地方,例如来自 keyup 上的 document 侦听器,其中没有关联的 value。因此,为了正确提供信息,我将提供一个额外的类型:

interface KeyboardEventOnInputField extends KeyboardEvent {
  target: HTMLInputElement;
}
...

  onKeyUp(e: KeyboardEventOnInputField) {
    const inputValue = e.target.value;
    ...
  }

如果函数的输入类型为 Event,您可能需要告诉 typescript 它实际上是什么:

  onKeyUp(e: Event) {
    const evt = e as KeyboardEventOnInputField;
    const inputValue = evt.target.value;
    this.inputValue.next(inputValue);
  }

例如,这是 Angular 所必需的。

答案 10 :(得分:0)

Angular 10+ 用户

只需声明 HTML 输入元素并将其扩展为使用目标作为对象,就像我在下面为我的引导程序 4+ 文件浏览器输入所做的那样。这样您就可以节省大量工作。

  selectFile(event: HTMLInputElement & { target: HTMLInputElement}) {
    console.log(event.target.files);
    this.selectedFile = event.target.files[0];
  }