Signatur
Beschreibung
Das Ereignis inputreport ist der zentrale Weg, um Daten von einem HID-Gerät (Human Interface Device) über die WebHID API zu empfangen, z. B. von Gamepads, Makro-Tastaturen, Stream-Decks, Barcode-Scannern oder eigenen Mikrocontroller-Geräten. Jedes Mal, wenn das Gerät einen Input Report schickt, erhält der Handler ein HIDInputReportEvent.
Das Ereignisobjekt enthält drei wichtige Eigenschaften: device (das auslösende HIDDevice), reportId (die ID des Berichts, 0 wenn das Gerät keine Report-IDs nutzt) und data, ein DataView mit den Nutzdaten ohne das Report-ID-Byte. Wie die Bytes zu deuten sind, legt der Report-Deskriptor des Geräts fest; über device.collections lässt sich die Struktur einsehen.
Registrieren lässt sich der Handler per addEventListener("inputreport", handler) oder über die Eigenschaft hidDevice.oninputreport = handler. Voraussetzung ist, dass das Gerät zuvor mit navigator.hid.requestDevice() ausgewählt und mit device.open() geöffnet wurde – vorher werden keine Berichte zugestellt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "inputreport". |
|
| $handler Pflicht | (event: HIDInputReportEvent) => void | Callback, der pro empfangenem Bericht aufgerufen wird. event.data ist ein DataView, event.reportId eine Zahl, event.device das HIDDevice. |
|
| $options | boolean | AddEventListenerOptions | false | Übliche Listener-Optionen wie once oder signal (zum Entfernen per AbortController). |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein HIDInputReportEvent.Beispiele
Gerät auswählen, öffnen und Berichte empfangen
const connectButton = document.querySelector('#connect');
connectButton.addEventListener('click', async () => {
// Muss durch eine Nutzeraktion ausgelöst werden
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x057e }] // Beispiel: Nintendo
});
if (!device) return;
await device.open();
device.addEventListener('inputreport', (event) => {
const { data, reportId, device } = event;
const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
console.log(`${device.productName} – Report ${reportId}:`, bytes);
});
});
Tastenstatus aus dem DataView auslesen
const handleReport = ({ data, reportId }) => {
if (reportId !== 1) return; // nur Report 1 enthält Tasten
const buttons = data.getUint8(0); // Bitmaske
const x = data.getInt16(1, true); // Little Endian
const y = data.getInt16(3, true);
const pressed = [...Array(8).keys()].filter((bit) => buttons & (1 << bit));
console.log({ pressed, x, y });
};
const [device] = await navigator.hid.getDevices();
if (device) {
if (!device.opened) await device.open();
device.oninputreport = handleReport;
}
Listener wieder entfernen und Gerät schließen
const controller = new AbortController();
const [device] = await navigator.hid.getDevices();
await device.open();
device.addEventListener('inputreport', (e) => {
console.log('Bytes:', e.data.byteLength);
}, { signal: controller.signal });
// Nach 10 Sekunden aufräumen
setTimeout(async () => {
controller.abort(); // entfernt den Listener
device.oninputreport = null; // falls zusätzlich gesetzt
await device.close();
console.log('Verbindung beendet');
}, 10_000);
// Wichtig · Fallstricke
- Browser-Unterstützung: Nur Chromium-Browser auf dem Desktop (Chrome, Edge, Opera). Firefox und Safari unterstützen WebHID nicht, daher vorher
if ('hid' in navigator)prüfen. - Sicherer Kontext: Funktioniert nur über HTTPS (oder
localhost).requestDevice()braucht eine Nutzeraktion, und in iframes muss die Permissions Policyhiderlaubt sein. - Kein Ereignis ohne
open(): Ein nur ausgewähltes, nicht geöffnetes Gerät sendet keine Berichte. - Report-ID nicht in
data: Das erste Byte ist bereits entfernt. Wer Offsets aus Datenblättern übernimmt, muss sie oft um 1 verschieben. - DataView korrekt nutzen: Bei
new Uint8Array(data.buffer)immerbyteOffsetundbyteLengthangeben. Für Mehrbyte-Werte auf die Byte-Reihenfolge achten (HID nutzt meist Little Endian). - Blockierte Geräte: Tastaturen, Mäuse und FIDO-Sicherheitsschlüssel sind durch eine Sperrliste geschützt. Ihre Berichte kommen nicht an.
- Leistung: Manche Geräte senden Hunderte Berichte pro Sekunde. Im Handler wenig Arbeit erledigen und DOM-Änderungen z. B. per
requestAnimationFramebündeln.