Web komponenty (web components)

Web komponenty pozwalają na tworzenie własnych tagów (lub innych elementów) HTML.

Przykład

Przykład przedstawia stworzenie prostego komponentu opisującego pogodę.

1. Rejestracja komponentu

Aby zarejestrować komponent wystarczy następujący fragment kodu:

class Wheather extends HTMLElement {
	constructor () {
		super();
	}
}

window.customElements.define('weather-information', Wheather);

Niestety nie robi on w tym momencie kompletnie nic. Mamy tutaj definicję klasy Wheater rozszerzającą klasę HTMLElement i wywołującą jej konstruktor. Po czym następuje rejestracja elementu (z racji rozszerzania klasy HTMLElement nazywam ją elementem) pod konkretną nazwą.

2. Dodanie szablonu

Aby trochę ożywić ten komponent, można nadpisać funkcję connectedCallback, która jest uruchamiana przy pierwszym dołączeniu komponentu do DOM. Ustawimy w niej atrybut innerHTML wstawiając tam na sztywno cały szablon:

class Wheather extends HTMLElement {

	constructor () {
		super();
	}

	connectedCallback () {
		this.innerHTML = this.prepareHTML();
	}
	
	prepareHTML(){
		return '<div> ' +
			'<span>Temperature: 36.6</span><br>' +
			'<span>Humidity: 50%</span>' +
		'</div>';
	}
}

window.customElements.define('weather-information', Wheather);

Dla następującego HTML:

<!DOCTYPE html> 
<html lang="en"> 
<head>     
<meta charset="utf-8">
<script src="script.js"></script>
</head> 
<body> 
<weather-information></weather-information>
</body> 
</html> 

Rezultat to

3. Obsługa atrybutów

Trochę słabo, że temperatura jak i wilgotność są wpisane na stałe, fajnie by było móc je przekazać jako atrybuty:

<!DOCTYPE html> 
<html lang="en"> 
<head>     
<meta charset="utf-8">
<script src="script.js"></script>
</head> 
<body> 
<weather-information temperature="36.6" humidity="50%"></weather-information>
</body> 
</html> 

Aby obsługiwać atrybuty należy dodać obsługę obserwowania atrybutów. Należy wykonać dwa kroki:
1. Zaznaczyć które atrybuty chcemy obserwować -> static get observedAttributes()
2. Obsłużyć zmianę atrybutów -> attributeChangedCallback(name, oldValue, newValue)
Przykładowy kod:

class Wheather extends HTMLElement {
	
	temperature;
	humidity;

	static get observedAttributes() { 
      return ["temperature", "humidity"];
    }

	constructor () {
		super();
	}

	connectedCallback () {
		this.innerHTML = this.prepareHTML();
	}
	
	attributeChangedCallback(name, oldValue, newValue) {
	  if(name == 'temperature'){
		  this.temperature = newValue;
	  }
	  else if( name === 'humidity'){
		  this.humidity = newValue;
	  }
	  this.innerHTML = this.prepareHTML();
    }
	
	prepareHTML(){
		return '<div> ' +
			'<span>Temperature: ' + this.temperature + '</span><br>' +
			'<span>Humidity: ' + this.humidity + '</span>' +
		'</div>';
	}
}

window.customElements.define('weather-information', Wheather);

Uruchomienie powyższego daje identyczny rezultat jak w punkcie drugim:

Warto zajrzeć

  1. https://developer.mozilla.org/en-US/docs/Web/Web_Components