Signatur
Beschreibung
Die Methode values() von XRInputSourceArray gibt einen neuen Iterator zurück. Er liefert die XRInputSource-Objekte, die gerade mit einer WebXR-Sitzung verbunden sind, der Reihe nach vom ersten bis zum letzten Eintrag. Eingabequellen sind zum Beispiel Handcontroller, erkannte Hände oder Blick- bzw. Bildschirmeingaben.
Ein XRInputSourceArray bekommst du über XRSession.inputSources. Das Objekt sieht aus wie ein Array, ist aber keins: Es hat length und einen Index-Zugriff, aber keine Methoden wie map() oder filter(). Mit values(), entries(), keys() und forEach() kannst du die Einträge trotzdem bequem durchlaufen.
In der Praxis brauchst du values() selten direkt. Das Objekt ist selbst iterierbar, for...of und der Spread-Operator funktionieren also ohne Umweg. Direkt nützlich ist values(), wenn du den Iterator als Objekt brauchst: zum Beispiel um ihn schrittweise mit next() abzufragen oder an eine Funktion zu übergeben, die einen Iterator erwartet.
Rückgabewert
next() liefert das nächste XRInputSource-Objekt als value. Wenn alle Einträge durchlaufen sind, gibt er { value: undefined, done: true } zurück.Beispiele
Alle Eingabequellen im Render-Loop durchlaufen
const onXRFrame = (time, frame) => {
const session = frame.session;
const refSpace = session.__refSpace; // vorher per requestReferenceSpace() gesetzt
for (const source of session.inputSources.values()) {
if (!source.gripSpace) continue; // z. B. Blickeingabe ohne Griff-Position
const pose = frame.getPose(source.gripSpace, refSpace);
if (pose) {
console.log(source.handedness, pose.transform.position);
}
}
session.requestAnimationFrame(onXRFrame);
};
Iterator manuell mit next() abfragen
const iterator = session.inputSources.values();
let result = iterator.next();
while (!result.done) {
const source = result.value;
console.log(`${source.handedness}: ${source.targetRayMode}, Profile: ${source.profiles.join(', ')}`);
result = iterator.next();
}
Echtes Array erzeugen, um filter() und map() zu nutzen
session.addEventListener('inputsourceschange', () => {
const controllers = Array.from(session.inputSources.values())
.filter((source) => source.targetRayMode === 'tracked-pointer')
.map((source) => source.handedness);
console.log('Verbundene Controller:', controllers);
});
// Wichtig · Fallstricke
- Momentaufnahme mit Vorsicht: Das
XRInputSourceArrayist „live“: Wenn Controller verbunden oder getrennt werden, ändert es sich. Heb einen Iterator oder eine daraus gebaute Kopie nicht über mehrere Frames auf. Hol die Einträge lieber in jedem Frame neu oder reagiere auf das Ereignisinputsourceschange. - Kein echtes Array: Methoden wie
map()undfilter()fehlen. Wenn du sie brauchst, wandle das Objekt vorher mitArray.from()oder[...inputSources]in ein Array um. - Einmal verbraucht: Ein Iterator lässt sich nur einmal durchlaufen. Für einen zweiten Durchlauf rufst du
values()erneut auf. - Kompatibilität: Die WebXR-API gibt es nur in sicheren Kontexten (HTTPS). Unterstützt wird sie vor allem von Chromium-Browsern (Chrome, Edge) und dem Meta Quest Browser. Firefox und Safari auf dem Desktop unterstützen sie nicht. Prüf die Unterstützung vorher mit
'xr' in navigatorundnavigator.xr.isSessionSupported(). - Performance: Leg im Render-Loop keine unnötigen Array-Kopien an. Ein direktes
for...oferzeugt weniger Müll für die Speicherbereinigung alsArray.from()in jedem Frame.