Znamy już różnicę pomiędzy Node (węzłem) a Elementem, teraz najwyższa pora poznać czym jest HTMLElement. Do dzieła.
Widzieliśmy już to w wersji HTMLUnknownElement:
function isValidTagname(tagname) {
return document.createElement(tagname).toString() != "[object HTMLUnknownElement]";
}
Widzieliśmy też inne, bardziej wyspecjalizowane dzieci HTMLElement, np. przy omawianiu web components:
class AnchorScroll extends HTMLAnchorElement {
connectedCallback(){
this.addEventListener("click", function(e){
e.preventDefault();
const anchor = this.getAttribute('href');
document.querySelector(anchor).scrollIntoView({
behavior: 'smooth'
});
});
}
}
customElements.define('custom-anchor', AnchorScroll, {extends: 'a'});
Ale co to ten element? Cóż, dziedziczy z trzech rzeczy:
- Node, czyli ma wszystkie properties z node
- Element, czyli ma wszystkie properties z Element
- EventTarget, ciekawa sprawa, bo EventTarget daje od siebie 3 metody:
- addEventListener
- removeEventListener
- dispatchEvent
HTMLElement ma wszystkie te properties, które należą mu się z racji bycia elementem HTML, nie elementem w ogóle, elementem XML i tak dalej. Na przykład isContentEditable to property HTMLElement.
Zaś tagName, className, attributes, to wszystko properties Elementu. A textContent, nodeType, nodeName to properties klasy Node.
Z klasy Element pochodzi na przykład metoda hasAttribute, getAttribute, matches i tak dalej:
const birds = document.querySelectorAll("li");
for (const bird of birds) {
if (bird.matches(".endangered")) {
console.log(`The ${bird.textContent} is endangered!`);
}
}
A metody cloneNode, appendChild i tak dalej, to metody klasy Node. Dodawnie/usuwanie event listenerów oraz emitowanie eventu, to metody klasy EventTarget.
I tu mamy odpowiedź, dlaczego cloneNode usuwa event listenery (w związku z tym jest dobre do usuwania listenerów):
- cloneNode to metoda klasy Node, zaś node nie posiada listenerów
- add/remove evt listener (oraz dispatch event) to metody klasy EventTarget
- HTMLElement dziedziczy z Node, Element i EventTarget
Oczywiście dociekliwi mogą powiedzieć chwila chwila, node też dziedziczy po event target. To prawda, plus za dociekliwość w czytaniu dokumentacji.
Inne typy węzłów niż Elementy-HTMLElementy, mogą odpalać pewne eventy. Jest to trochę relikt przeszłości odkąd mamy mutation observery. Więcej o nich niedługo.