Dotkniemy teraz tematu, jakim są Custom Web Components a także dziedziczenia z wbudowanych typów. Napiszemy klasę będącą własną wersją tagu <a> o innej funkcjonalności.
Tworzymy custom anchor – dziedziczenie, connectedCallback
Nie tworzymy całkowicie nowego tagu HTML (to też da się zrobić, a może nawet przede wszystkim, za pomocą Web Components), ale własną wersję już istniejącego tagu. Nasz komponent od strony HTML będzie więc wykorzystywał swój normalny tag oraz atrybut „is”:
<a is="custom-anchor" href="#">Custom anchor</a>
<script src="./webcomponent.js"></script>
A oto podstawowy JavaScript do tworzenia komponentów rozszerzających działanie wbudowanych tagów:
class AnchorCustom extends HTMLAnchorElement {
connectedCallback(){
console.log('connected');
}
}
customElements.define('custom-anchor', AnchorCustom, {extends: 'a'});
Słówko kluczowe extends służy do dziedziczenia w JavaScript. W define musimy je jeszcze potwierdzić (gdybyśmy tworzyli własny komponent, byłoby to zbędne zaś naszym tagiem byłby <custom-anchor>) podając odpowiednią nazwę tagu.
Metoda conntectedCallback działa w momencie, gdy element zostanie przypięty do strony. Jeżeli mamy trochę doświadczenia z frameworkami frontendowymi możemy się tego domyślić.
Teraz nasz tag <a> powinien działać jak normalny tag, ale wywołać console.loga po podłączeniu.
Coś prostego – confirm anchor
Zrobimy coś prostego – link, który nas pyta, czy aby na pewno chcemy wyjść ze strony. Oczywiście będziemy potrzebowali jakiegoś adresu, innego niż #, aby to sprawdzić:
<a is="custom-anchor" href="https://www.google.com">Custom anchor</a>
Nasza wariacja tagu <a> nadal nazywa się custom-anchor, ale nazwę klasy zamienimy na AnchorConfirm i sobie tę klasę szybciutko napiszemy:
class AnchorConfirm extends HTMLAnchorElement {
connectedCallback(){
this.addEventListener("click", function(e){
if(!confirm("Do you want to leave this site?"))
e.preventDefault();
});
}
}
customElements.define('custom-anchor', AnchorConfirm, {extends: 'a'});
W define pierwszy argument to nazwa tagu, lub w przypadku dziedziczenia z wbudowanych tagów nazwa wariacji, do której odwołujemy się przez atrybut is. Dalej nazwa klasy i potwierdzenie, z jakiego tagu dziedziczymy.
W normalnej obiektówce wystarczy extends i nazwa klasy, ale tutaj mamy do czynienia z Web Components API i pewne kroki są wymagane.
Dalej, connectedCallback podpina event listener, który wykorzystuje wbudowane (i całkowicie nieznane, słusznie zresztą) confirm API (jest jeszcze alert i prompt, w dawnych, słusznie minionych czasach te funkcje były nadużywane aż do przesady) i jeżeli nie potwierdzimy, że wyjść chcemy – preventDefault.
Pora napisać coś ciekawszego.
Scroll anchor – kotwica do elementu na stronie
Pokażę nasz HTML i już będziemy wiedzieli bez zbędnych wstępów co chcemy tutaj napisać, jeżeli tytuł nas wystarczająco nie naprowadził:
<a is="custom-anchor" href="#heading-two">Custom anchor</a>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<p id="heading-two">Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus similique
harum doloremque eligendi veritatis nesciunt.</p>
<script src="./webcomponent.js"></script>
Wielokrotnie już to robiliśmy w różnych konfiguracjach i na różne sposoby, chodzi nam o smooth scroll za pomocą scrollIntoView. Na początek – zatrzymujemy domyślne działanie, którego nie chcemy:
class AnchorScroll extends HTMLAnchorElement {
connectedCallback(){
this.addEventListener("click", function(e){
e.preventDefault();
});
}
}
Teraz pobieramy kotwicę i wykonujemy scrollIntoView:
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'});
Komponent gotowy do użycia i jak najbardziej działa. Poznaliśmy dziedziczenie w JS oraz zdobyliśmy podstawy Web Components API – to już coś!