2015-03-06 14 views
32

Voglio semplicemente a che fare questo con il mio KeyboardEventPerché Event.target non è un elemento in dattiloscritto?

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

Mentre Event.target è di tipo EventTarget esso non eredita da Element. Quindi devo lanciare in questo modo:

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

Ciò è probabilmente dovuto ad alcuni browser non standard seguenti, giusto? Qual è l'implementazione agnostica del browser corretta in TypeScript?

PS: sto utilizzando jQuery per acquisire KeyboardEvent.

+0

Sintassi un po 'più pulita 'var element = ev.target as HTMLElement' –

risposta

25

Non eredita da Element perché non tutti i target di eventi sono elementi.

From MDN:

Elemento, documenti, e la finestra sono i bersagli degli eventi più comuni, ma altri oggetti possono essere bersagli di eventi anche, per esempio XMLHttpRequest, AudioNode, AudioContext, e altri.

Anche il KeyboardEvent si sta cercando di utilizzare può verificarsi su un elemento DOM o sull'oggetto finestra (e teoricamente su altre cose), quindi proprio lì, non avrebbe senso per evt.target da definire come Element.

Se si tratta di un evento su un elemento DOM, quindi direi che si può tranquillamente assumere evt.target. è un Element. Non penso che si tratti di un comportamento cross-browser. Solo che EventTarget è un'interfaccia più astratta di Element.

Ulteriori approfondimenti: https://typescript.codeplex.com/discussions/432211

+2

In tal caso KeyboardEvent e MouseEvent dovrebbero avere il proprio equivalente di EventTarget che conterrà sempre l'elemento associato. DOM è così schifoso ...:/ –

+0

@ daniel.sedlacek Sembra che stai incolpando DOM per le limitazioni nel sistema di tipi di TypeScript. Le persone che usano Javascript semplice non hanno problemi a usare 'Event.target'. – JLRishe

+4

Non sono un esperto di DOM né di TypeScript, ma direi che il design di EventTarget ha troppa ambiguità e che non ha nulla a che fare con TypeScript. –

2

Utilizzando dattiloscritto, io uso un'interfaccia personalizzata che si applica solo alla mia funzione. Esempio di utilizzo.

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

In questo caso, handleChange riceverà un oggetto con campo di destinazione che è di tipo HTMLInputElement.

Più tardi nel mio codice posso usare

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

Un approccio più pulito sarebbe quello di mettere l'interfaccia in un file separato.

interface HandleNameChangeInterface { 
    target: HTMLInputElement; 
} 

poi utilizzare la seguente definizione di funzione:

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

Nel mio caso d'uso, è espressamente definita che l'unico chiamante di handleChange è un tipo di elemento HTML di testo di input.

Problemi correlati