Vanilla JavaScript Islands
Erstelle interaktive Components mit purem JavaScript - kein Framework, keine Abhängigkeiten.
Überblick
Vanilla JS Islands sind perfekt wenn du benötigst:
- ✅ Einfache Interaktionen (Klicks, Formular-Übermittlung)
- ✅ DOM-Manipulation
- ✅ Minimale Bundle-Größe (0kb Framework-Overhead)
- ✅ Volle Kontrolle über den Code
- ✅ Keine Build-Komplexität
Bundle-Größe: Nur dein Code (typischerweise 1-5kb)
Grundstruktur
javascript
// islands/my-island.js
export default class MyIsland {
constructor(element, props = {}) {
this.element = element;
this.props = props;
this.init();
}
init() {
// Initialize your island
this.render();
this.attachEventListeners();
}
render() {
// Create HTML
this.element.innerHTML = `
<div class="p-6 bg-white rounded-lg">
<h3 class="text-lg font-semibold">${this.props.title || 'Island'}</h3>
<button class="px-4 py-2 bg-blue-600 text-white rounded">
Click Me
</button>
</div>
`;
}
attachEventListeners() {
// Add event listeners
this.element.querySelector('button').addEventListener('click', () => {
this.handleClick();
});
}
handleClick() {
alert('Button clicked!');
}
destroy() {
// Clean up when island is removed
}
}Kernkonzepte
State Management
Vanilla JS erfordert manuelle State-Verwaltung:
javascript
class MyIsland {
constructor(element, props = {}) {
this.element = element;
this.props = props;
// State als Instanz-Variablen
this.count = 0;
this.isLoading = false;
this.items = [];
this.init();
}
updateState() {
// Manuelles UI-Update nach State-Änderung
this.render();
}
}DOM-Manipulation
Effiziente DOM-Updates mit gecachten Referenzen:
javascript
init() {
this.render();
// Cache DOM references
this.button = this.element.querySelector('button');
this.display = this.element.querySelector('.display');
this.attachEvents();
}
updateDisplay() {
// Direktes Update ohne erneutes Query
this.display.textContent = this.count;
}Event Handling
Saubere Event-Listener mit Cleanup:
javascript
attachEvents() {
this.handleClick = this.handleClick.bind(this);
this.button.addEventListener('click', this.handleClick);
}
handleClick() {
this.count++;
this.updateDisplay();
}
destroy() {
this.button.removeEventListener('click', this.handleClick);
}Asynchrone Operationen
javascript
async loadData() {
try {
this.showLoading();
const response = await fetch('/api/data');
if (!response.ok) throw new Error('API error');
const data = await response.json();
this.items = data;
this.render();
} catch (error) {
this.showError(error.message);
} finally {
this.hideLoading();
}
}Vorteile
- ✅ Keine Abhängigkeiten - Keine Framework-Abhängigkeiten
- ✅ Kleinste Bundle-Größe - Nur dein Code (1-5kb)
- ✅ Volle Kontrolle - Volle Kontrolle über den Code
- ✅ Keine Kompilierung - Direktes Browser-Execution
Nachteile
- ❌ Manuelle DOM-Updates - Verbose für komplexe UIs
- ❌ Keine Reaktivität - Manuelles UI-Update erforderlich
- ❌ State Management - Eigene Implementierung nötig
Vollständige Beispiele
Siehe Beispiele mit Islands für vollständige Implementierungen:
- Counter - State Management
- Contact Form - Formulare mit Validierung
- Image Carousel - Intervals & Lifecycle
- Search Filter - Live Search & Filtering