typescript - Hvordan opprette en ny HTMLElement?


Jeg prøver å instantiere et nytt HTMLDivElement i TypeScript

var elem = new HTMLDivElement();

men nettleseren kaster

Uncaught TypeError: Illegal constructor.

Løsningen ser ut til å være å bruke

var elem = document.createElement('div');

men jeg synes dette er suboptimalt av ulike grunner.

Hvorfor kan jeg ikke instansiere DOM-elementer direkte når det finnes et new-nøkkelord for det i lib.d.ts?

declare var HTMLDivElement: {
    prototype: HTMLDivElement;
    new (): HTMLDivElement;
}

Svar #1

Merk at feilen du får her er "Illegal constructor". Dette er forskjellig fra feilen "object is not a function" som du ville fått hvis du for eksempel skrev new {}().

Så, teknisk sett, HTMLDivElement har en konstruktør. Det er bare at denne spesifikke konstruktøren kaster et unntak i stedet for å opprette et objekt.

Vanligvis ville lib.d.ts bare ekskludere slike ubrukelige signaturer, men TypeScript krever at høyresiden av instanceof-operatoren har en konstruktør. Med andre ord er det lov å skrive foo instanceof HTMLElement, men ikke foo instanceof [], og forskjellen bestemmes av det faktum at HTMLElement har en konstruktør.

Det var egentlig tre valg på bordet her:

  1. Fjern konstruktørsignaturen fra DOM-elementene og fjern begrensningen på høyre operand til instanceof. Dette er uønsket fordi du virkelig vil fange opp feil der noen ved et uhell skriver kode som x instanceof foo i stedet for x instanceof Foo (hvor foo er en instans av Foo).
  2. Fjern konstruktørsignaturen fra DOM-elementer, men behold instanceof-sjekken på plass. Dette er dårlig fordi foo instanceof HTMLElement er en veldig rimelig ting å skrive.
  3. Den nåværende situasjonen, der konstruktørene eksisterer, men du må vite at du ikke skal kalle dem.

Du kan ikke konstruere DOM-elementer ved å bruke vanlige konstruktører fordi du skal gå gjennom document.createElement. Dette er i utgangspunktet av tekniske årsaker knyttet til hvordan nettlesere implementerer disse objektene.

Svar #2

Du har forvekslet TypeScript-syntaks med C#-syntaks.

Bare erstatt

var elem = new HTMLDivElement();

med en av følgende

var elem = document.createElement('div');

eller

var elem = <HTMLDivElement>(document.createElement('div'));

eller

let elem = document.createElement('div') as HTMLDivElement

(hvis du trenger å bruke HTMLDivElement-attributter)

Svar #3

Hvis du utvider HTMLElement eller en hvilken som helst underklasse som HTMLDivElement

Du må også registrere det tilpassede elementet

class SampleDiv extends HTMLDivElement{
    constructor(){
       super();
    }
}
customElements.define('sample-div', SampleDiv, { extends: 'div' });

Se mer her: https://javascript.info/custom-elements

Relaterte artikler