2015-03-06 18 views
32

ja po prostu chcę to zrobić z moim KeyboardEventDlaczego Event.target nie jest elementem w maszynopisie?

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

Podczas Event.target jest typu eventtarget nie dziedziczą z elementu. Więc mam do oddania go tak:

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

Jest to prawdopodobnie ze względu na niektórych przeglądarkach nie następujących standardów, prawda? Jaka jest poprawna implementacja agnostyczna przeglądarki w TypeScript?

PS: Używam jQuery do przechwytywania KeyboardEvent.

+0

Trochę czystsza składnia 'var element = ev.target jako HTMLElement' –

Odpowiedz

25

Nie dziedziczy po Element, ponieważ nie wszystkie cele zdarzenia są elementami.

From MDN:

Element, dokument, a okna są najczęstsze cele zdarzeń, ale inne obiekty mogą być celami zdarzeń też, na przykład XMLHttpRequest, AudioNode, AudioContext i innych.

Nawet KeyboardEvent próbujesz użyć może występować na elemencie DOM lub obiektu window (i teoretycznie na inne rzeczy), więc tam nie ma sensu dla evt.target być zdefiniowane jako Element.

Jeśli jest to wydarzenie na elemencie DOM, to powiedziałbym, że można bezpiecznie założyć evt.target. jest Element. Nie sądzę, że jest to kwestia zachowania w różnych przeglądarkach. Tylko, że EventTarget jest bardziej abstrakcyjnym interfejsem niż Element.

Dalsze czytanie: https://typescript.codeplex.com/discussions/432211

+2

W takim przypadku KeyboardEvent i MouseEvent powinny mieć własny odpowiednik EventTarget, który zawsze będzie zawierał powiązany Element. DOM jest tak podejrzany ...:/ –

+0

@ daniel.sedlacek Wygląda na to, że obwiniasz DOM za ograniczenia w systemie typu TypeScript. Osoby używające zwykłego kodu Javascript nie mają problemów z korzystaniem z 'Event.target'. – JLRishe

+4

Nie jestem ekspertem od DOM ani TypeScript, ale powiedziałbym, że projekt EventTarget ma zbyt wiele niejednoznaczności i nie ma nic wspólnego z TypeScript. –

2

Korzystanie maszynopis, używam interfejsu niestandardowego, które odnoszą się tylko do mojej funkcji. Przykład użycia.

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

W takim przypadku handleChange otrzyma obiekt z polem docelowym typu HTMLInputElement.

Później w moim kodu można użyć

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

Czystsze rozwiązaniem byłoby umieścić interfejs do osobnego pliku.

interface HandleNameChangeInterface { 
    target: HTMLInputElement; 
} 

potem wykorzystać następującą definicję funkcję:

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

W moim usecase, to wyraźnie określono, że tylko dzwoniący do handleChange jest typ elementu HTML tekstu wejściowego.

Powiązane problemy