본문 바로가기

개발하자

Event.target이 Typescript에서 Element가 아닌 이유는 무엇입니까?

반응형

Event.target이 Typescript에서 Element가 아닌 이유는 무엇입니까?

나는 단지 이것을 내 것으로 하고 싶다.

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

가 유형이지만, 에서 상속되지 않습니다. 그래서 나는 이것을 다음과 같이 캐스팅해야 합니다.

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

이것은 아마도 일부 브라우저가 표준을 따르지 않기 때문일 것입니다, 그렇죠? TypeScript에서 브라우저에 구애받지 않는 올바른 구현은 무엇입니까?

추신: jQuery를 사용하여 를 캡처하고 있습니다.




모든 이벤트 대상이 요소가 아니므로 에서 상속되지 않습니다.

:

요소, 문서 및 창이 가장 일반적인 이벤트 대상이지만 XMLHttpRequest, AudioNode, AudioContext 등과 같은 다른 개체도 이벤트 대상이 될 수 있습니다.

사용하려는 것도 DOM 요소나 창 개체(이론적으로 다른 것)에서 발생할 수 있으므로 바로 여기서 로 정의되는 것은 의미가 없습니다.

DOM 요소에 대한 이벤트라면 .는 .라고 가정해도 무방합니다. 이것은 브라우저 간 동작의 문제가 아니라고 생각합니다. 단지 그것은 보다 더 추상적인 인터페이스이다.

추가 정보:




타이핑 스크립트를 사용하여, 나는 내 기능에만 적용되는 사용자 지정 인터페이스를 사용한다. 사용 사례.

  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 });
  }

내 사용 사례에서 변경을 처리할 유일한 호출자는 입력 텍스트의 HTML 요소 유형이라고 명시적으로 정의되어 있습니다.




JLR은 그녀의 대답이 맞으므로 이벤트 핸들러에서 다음과 같이 간단히 사용합니다.

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



스크립트 3.2.4를 입력합니다.

속성을 검색하려면 적절한 데이터 유형에 대상을 지정해야 합니다.

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



@방곤칼리는 정답을 제공하지만, 이 구문은 내게 더 읽기 쉽고 더 나은 것 같다.

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



typescript를 사용하면 다음과 같이 type 별칭을 활용할 수 있습니다.

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



확장 가능한 자신만의 범용 인터페이스를 만들 수 있을까요?

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

그런 다음 다음과 같이 사용할 수 있습니다.

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



나는 이것을 사용한다:

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



저는 보통 키업과 같은 현장에서 발생하는 사건들을 처리할 때 이 문제에 직면합니다. 그러나 이벤트는 의 청취자(예: 연결되지 않은 사용자)에서 발생할 수 있습니다. 따라서 정보를 올바르게 제공하기 위해 다음과 같은 추가 유형을 제공합니다.

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

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

함수에 대한 입력의 유형이 다음과 같은 경우 실제로 어떤 입력인지 유형 스크립트를 지정해야 할 수 있습니다.

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

이는 예를 들어 Angular(각도)




Angular 10+ 사용자용

아래 부트스트랩 4+ 파일 브라우저 입력에 대해 했던 것처럼 HTML 입력 요소를 선언하고 대상을 개체로 사용하도록 확장하십시오. 이렇게 하면 많은 작업을 절약할 수 있습니다.

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



그리고 정답은 맞지만, 더 좋은 방법이 있습니다. 예를들면


  // in another file
  export interface DOMEvent<T extends EventTarget> extends Event {
  readonly target: T;
  }


  onFileChange(event: Event): void {
    const { target } = event as DOMEvent<HTMLInputElement>;
    if (target.files && target.files.length > 0) {
      // do something with the target
    }
  }


반응형