Ik wil dit gewoon doen met mijn KeyboardEvent
var tag = evt.target.tagName.toLowerCase();
Hoewel Event.target
van het type EventTarget
is, neemt het niet over van Element
. Dus ik moet het als volgt casten:
var tag = (<Element>evt.target).tagName.toLowerCase();
Dit komt waarschijnlijk doordat sommige browsers de standaarden niet volgen, toch? Wat is de juiste browseronafhankelijke implementatie in TypeScript?
P.S. Ik gebruik jQuery om het KeyboardEvent
vast te leggen.
Antwoord 1, autoriteit 100%
Het neemt niet over van Element
omdat niet alle gebeurtenisdoelen elementen zijn.
Element, document en venster zijn de meest voorkomende gebeurtenisdoelen, maar andere objecten kunnen ook gebeurtenisdoelen zijn, bijvoorbeeld XMLHttpRequest, AudioNode, AudioContext en andere.
Zelfs het KeyboardEvent
dat u probeert te gebruiken, kan voorkomen op een DOM-element of op het vensterobject (en in theorie op andere dingen), dus daar zou het niet logisch zijn voor evt.target
moet worden gedefinieerd als een Element
.
Als het een gebeurtenis is op een DOM-element, dan zou ik zeggen dat je veilig kunt uitgaan van evt.target
. is een Element
. Ik denk niet dat dit een kwestie is van cross-browser gedrag. Alleen dat EventTarget
een meer abstracte interface is dan Element
.
Meer lezen: https://github.com/Microsoft/TypeScript/issues/29540
Antwoord 2, autoriteit 88%
JLRishe’s antwoord is correct, dus ik gebruik dit gewoon in mijn gebeurtenishandler:
if (event.target instanceof Element) { /*...*/ }
Antwoord 3, autoriteit 82%
Met typescript gebruik ik een aangepaste interface die alleen van toepassing is op mijn functie. Voorbeeld use case.
handleChange(event: { target: HTMLInputElement; }) {
this.setState({ value: event.target.value });
}
In dit geval ontvangt de handleChange een object met een doelveld van het type HTMLInputElement.
Later in mijn code kan ik
. gebruiken
<input type='text' value={this.state.value} onChange={this.handleChange} />
Een schonere benadering zou zijn om de interface in een apart bestand te plaatsen.
interface HandleNameChangeInterface {
target: HTMLInputElement;
}
gebruik dan later de volgende functiedefinitie:
handleChange(event: HandleNameChangeInterface) {
this.setState({ value: event.target.value });
}
In mijn gebruikssituatie is uitdrukkelijk gedefinieerd dat de enige aanroeper om ChangeChange af te handelen een HTML-elementtype invoertekst is.
Antwoord 4, autoriteit 57%
Typescript 3.2.4
Voor het ophalen van eigendom moet u het doel casten naar het juiste gegevenstype:
e => console.log((e.target as Element).id)
Antwoord 5, autoriteit 16%
Kun je je eigen generieke interface maken die Event
uitbreidt. Zoiets?
interface DOMEvent<T extends EventTarget> extends Event {
readonly target: T
}
Dan kun je het als volgt gebruiken:
handleChange(event: DOMEvent<HTMLInputElement>) {
this.setState({ value: event.target.value });
}
Antwoord 6, autoriteit 3%
Met typescript kunnen we type-aliassen gebruiken, zoals:
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...
};
Antwoord 7
@Bangonkali geeft het juiste antwoord, maar deze syntaxis lijkt me leesbaarder en gewoon leuker:
eventChange($event: KeyboardEvent): void {
(<HTMLInputElement>$event.target).value;
}
Antwoord 8
Ik heb meestal met dit probleem te maken als ik te maken heb met gebeurtenissen uit een input
-veld, zoals key up. Maar onthoud dat de gebeurtenis overal vandaan kan komen, b.v. van een keyup
-luisteraar op document
, waar geen bijbehorende value
is. Dus om de informatie correct te verstrekken, zou ik een extra type opgeven:
interface KeyboardEventOnInputField extends KeyboardEvent {
target: HTMLInputElement;
}
...
onKeyUp(e: KeyboardEventOnInputField) {
const inputValue = e.target.value;
...
}
Als de invoer van de functie een type Event
heeft, moet u wellicht met typescript vertellen wat het eigenlijk is:
onKeyUp(e: Event) {
const evt = e as KeyboardEventOnInputField;
const inputValue = evt.target.value;
this.inputValue.next(inputValue);
}
Dit is bijvoorbeeld vereist in Angular.
Antwoord 9
Ik gebruik dit:
onClick({ target }: MouseEvent) => {
const targetDivElement: HTMLDivElement = target as HTMLDivElement;
const listFullHeight: number = targetDivElement.scrollHeight;
const listVisibleHeight: number = targetDivElement.offsetHeight;
const listTopScroll: number = targetDivElement.scrollTop;
}
Antwoord 10
Voor Angular 10+ gebruikers
Declareer gewoon het HTML-invoerelement en breid het uit om het doel als een object te gebruiken, zoals ik hieronder deed voor mijn bootstrap 4+ bestandsbrowserinvoer. Op deze manier kunt u veel werk besparen.
selectFile(event: HTMLInputElement & { target: HTMLInputElement}) {
console.log(event.target.files);
this.selectedFile = event.target.files[0];
}