javascript - Varför får addEventListener() bara förslag för eventen fullscreenchange och fullscreenerror på ett element från document.querySelector?
Vad jag vill ha (ett exempel på alla de händelser som föreslås för addEventListener på document-objektet):
Vad jag har (händelser föreslagna för addEventListener på objektet som returneras från min document.querySelector-fråga (endast fullscreenchange och fullscreenerror)):
Jag vill ha förslag som visas i den första bilden.
Här är en utskrift av bilderna ovan så att du kan prova själv:
const titleElement = document.querySelector("#title");
document.addEventListener("", (ev) => {});
// ^lots of suggested event names
titleElement.addEventListener("", (ev) => {});
// ^only the `fullscreenchange` and `fullscreenerror` events are suggested
Svar #1
Detta beror på typning. document.querySelector garanteras bara att returnera ett element av typen Element, även om det förstås kan returnera ett objekt av en subtyp av Element. Men för typdefinitionerna i lib.dom.ts är Element bara definierad att ha dessa två händelser (fullscreenchange och fullscreenerror) på sig - troligen eftersom det är de enda två händelser som är giltiga för alla möjliga Element-subtyper.
För att lösa ditt problem kan du skicka typen du förväntar dig som ett generiskt argument till querySelector-anropet, på detta sätt:
document.querySelector<HTMLHeadingElement>("#title")
vilket kommer att typa det returnerade objektet som HTMLHeadingElement | null.
Alternativt kan du lägga till en typanteckning för att tala om för TypeScript-kompilatorn eller VS Code den exakta typen som du förväntar dig att det frågade elementet ska ha.
I TypeScript kan du göra en typkonvertering med nyckelordet as på detta sätt (du behöver själv lägga till | null om du vill ha det):
const titleElement = document.querySelector("#title") as HTMLHeadingElement;
// or whatever HTML type your `#title`-IDed element is.
I JavaScript kan du använda JSDoc-kommentarer för att göra typindikeringar som VS Code och andra verktyg kommer att känna igen:
/** @type {HTMLHeadingElement} */
const titleElement = document.querySelector("#title");
Eller så kan du omsluta användningen av objektet som returneras från frågan med en typkontroll:
const titleElement = document.querySelector("#title");
if (titleElement instanceof HTMLHeadingElement) {
titleElement.addEventListever("click", (ev) => {
console.log("hello world!");
});
}
TypeScript-språktjänsten som driver IntelliSense i VS Code kommer att veta att inuti den if-satsen måste typen av titleElement vara åtminstone HTMLHeadingElement (eller vilken typ du än anger i instanceof-kontrollen) på grund av instanceof-kontrollen. Du kan läsa mer om instanceof-operatorn på MDN.
För att få en lista över alla befintliga HTML-element kan man titta på MDN:s sida för HTML-elementreferens, eller så kan du helt enkelt skriva HTML i din fil i VS Code och trigga autokompletteringsförslag.

