Signatur
Beschreibung
Das disconnect-Ereignis gehört zur Web Serial API. Es wird an einem SerialPort-Objekt ausgelöst, sobald das Gerät nicht mehr verfügbar ist. Das passiert typischerweise, wenn ein USB-Seriell-Adapter oder ein Mikrocontroller wie Arduino oder ESP32 abgezogen wird oder eine Bluetooth-RFCOMM-Verbindung abbricht. Du registrierst den Handler mit port.addEventListener("disconnect", handler) oder über die Eigenschaft port.ondisconnect.
Das Ereignis steigt auf (bubbles) zu navigator.serial. Du kannst also einen einzigen Listener an navigator.serial hängen und bekommst Trennungen aller Ports mit, für die deine Seite eine Berechtigung hat. Der betroffene Port steht dann in event.target. Das ist praktisch, wenn deine Anwendung mehrere Geräte gleichzeitig verwaltet.
Ein typischer Einsatz ist das Aufräumen: Laufende Lese- und Schreibschleifen beenden, Reader und Writer freigeben, den Port schließen und die Oberfläche aktualisieren (z. B. „Gerät getrennt“ anzeigen, den Verbinden-Knopf wieder aktivieren). Das Gegenstück ist das Ereignis connect. Es wird ausgelöst, wenn ein bereits berechtigter Port wieder verfügbar ist.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, hier immer "disconnect". |
|
| $handler Pflicht | (event: Event) => void | Callback-Funktion, die ein einfaches Event-Objekt erhält. event.target ist der getrennte SerialPort. |
|
| $options | boolean | AddEventListenerOptions | false | Übliche Listener-Optionen wie once, signal oder capture. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein Event, dessen target der betroffene SerialPort ist.Beispiele
Trennung eines geöffneten Ports erkennen und aufräumen
const connectBtn = document.querySelector('#connect');
connectBtn.addEventListener('click', async () => {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
console.log('Verbunden');
port.addEventListener('disconnect', () => {
console.log('Gerät wurde getrennt');
connectBtn.disabled = false;
}, { once: true });
connectBtn.disabled = true;
const reader = port.readable.getReader();
const decoder = new TextDecoder();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log(decoder.decode(value));
}
} catch (err) {
// Beim Abziehen bricht read() mit einem NetworkError ab
console.warn('Lesefehler:', err.name);
} finally {
reader.releaseLock();
await port.close().catch(() => {});
}
});
Zentraler Listener an navigator.serial für alle Ports
const ports = new Set(await navigator.serial.getPorts());
navigator.serial.addEventListener('connect', (event) => {
ports.add(event.target);
console.log('Port verfügbar:', event.target.getInfo());
});
navigator.serial.addEventListener('disconnect', (event) => {
ports.delete(event.target);
const { usbVendorId, usbProductId } = event.target.getInfo();
console.log(`Getrennt: VID ${usbVendorId?.toString(16)}, PID ${usbProductId?.toString(16)}`);
console.log('Verbleibende Ports:', ports.size);
});
ondisconnect-Eigenschaft und Entfernen des Listeners
const [port] = await navigator.serial.getPorts();
if (port) {
// Variante 1: Eigenschaft (überschreibt einen vorher gesetzten Handler)
port.ondisconnect = () => console.log('Getrennt (ondisconnect)');
// Variante 2: addEventListener / removeEventListener
const onDisconnect = (e) => console.log('Getrennt:', e.target === port);
port.addEventListener('disconnect', onDisconnect);
// Später, z. B. beim Verlassen der Ansicht:
port.removeEventListener('disconnect', onDisconnect);
port.ondisconnect = null;
}
// Wichtig · Fallstricke
- Kompatibilität: Die Web Serial API gibt es nur in Chromium-Desktop-Browsern (Chrome, Edge, Opera ab Version 89). Firefox und Safari unterstützen sie nicht, auf Android ist sie nur eingeschränkt verfügbar. Prüfe vorher mit
if ('serial' in navigator), ob die API vorhanden ist. - Die API ist nur im sicheren Kontext (HTTPS oder
localhost) verfügbar. Eine Permissions Policy (serial) kann sie in iframes sperren. - Das Ereignis wird nur für Ports ausgelöst, für die die Seite bereits eine Berechtigung hat, also über
requestPort()gewählt oder vongetPorts()geliefert. Beliebige Geräte am System lassen sich damit nicht überwachen. - Beim Abziehen bricht ein laufendes
reader.read()mit einem Fehler ab (NetworkError). Die Reihenfolge von Lesefehler unddisconnect-Ereignis ist nicht garantiert. Schreibe deinen Aufräumcode deshalb so, dass er gefahrlos mehrfach laufen kann. Gib Reader und Writer frei, bevor duport.close()aufrufst. - Das Ereignis ist ein einfaches
Eventohne weitere Detailfelder. Den Port findest du inevent.target, Geräteinfos liefertgetInfo(). - Wenn du
port.ondisconnectsetzt, überschreibst du einen vorher gesetzten Handler. Für mehrere Handler nutzeaddEventListener.