Why is Event.target not Element in Typescript?

后端 未结 8 691
情歌与酒
情歌与酒 2020-12-01 03:55

I simply want to do this with my KeyboardEvent

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

While Event.target is of type EventTarget it doe

相关标签:
8条回答
  • 2020-12-01 04:26

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

    From 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.

    Even the KeyboardEvent you'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.target to be defined as an 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 EventTarget is a more abstract interface than Element.

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

    0 讨论(0)
  • 2020-12-01 04:28

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

    if (event.target instanceof Element) { /*...*/ }
    
    0 讨论(0)
  • 2020-12-01 04:28

    Typescript 3.2.4

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

    e => console.log((e.target as Element).id)
    
    0 讨论(0)
  • 2020-12-01 04:29

    With typescript we can leverage type aliases, like so:

    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...
    };
    
    0 讨论(0)
  • 2020-12-01 04:31

    I use this:

    onClick({ target }: MouseEvent) => {
        const targetDivElement: HTMLDivElement = target as HTMLDivElement;
        
        const listFullHeight: number = targetDivElement.scrollHeight;
        const listVisibleHeight: number = targetDivElement.offsetHeight;
        const listTopScroll: number = targetDivElement.scrollTop;
    }
    
    0 讨论(0)
  • 2020-12-01 04:43

    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.

    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.

    0 讨论(0)
提交回复
热议问题