Signatur
Beschreibung
Die statische Methode DeviceOrientationEvent.requestPermission() zeigt einen Systemdialog, in dem der Benutzer entscheidet, ob die Webseite Daten zur Lage des Geräts empfangen darf. Erst wenn der Benutzer zustimmt, feuert das Event deviceorientation mit den Werten alpha, beta und gamma. Ohne Zustimmung registriert man zwar Listener, sie werden aber nie aufgerufen.
Die Methode gibt es vor allem in Safari unter iOS und iPadOS ab Version 13. Apple hat sie eingeführt, weil Webseiten die Bewegungssensoren für Fingerprinting und Seitenkanal-Angriffe missbraucht haben, etwa um Eingaben auf der Bildschirmtastatur zu erraten. Chromium-basierte Browser und Firefox haben die Methode nicht. Dort kommen die Events ohne Nachfrage an, sofern die Seite in einem sicheren Kontext (HTTPS) läuft und die Permissions Policy es erlaubt.
Der Aufruf muss direkt aus einer Benutzeraktion kommen, etwa aus einem click- oder touchend-Handler (transient activation). Beim Laden der Seite oder in einem setTimeout weist Safari die Anfrage ab. Deshalb der übliche Ablauf: Mit Feature-Detection prüfen, ob die Methode existiert. Falls ja, einen Button wie „Bewegungssteuerung aktivieren“ anzeigen und erst im Klick-Handler die Erlaubnis anfordern.
Für Beschleunigungsdaten (devicemotion) gibt es eine eigene Methode: DeviceMotionEvent.requestPermission(). In der Praxis fragt man oft beide Erlaubnisse im selben Klick-Handler ab.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $absolute | boolean | false | Mit true wird die Erlaubnis für absolute Orientierungsdaten angefordert, die sich am Erdmagnetfeld ausrichten (Event deviceorientationabsolute bzw. webkitCompassHeading). Ohne Argument geht es um relative Orientierungsdaten. |
Rückgabewert
"granted" (erlaubt) oder "denied" (abgelehnt) erfüllt wird. Es wird mit einem NotAllowedError (DOMException) zurückgewiesen, wenn der Aufruf nicht aus einer Benutzeraktion kommt.Beispiele
Feature-Detection und Anfrage per Button-Klick
const button = document.querySelector('#enable-motion');
const handleOrientation = (event) => {
const { alpha, beta, gamma } = event;
console.log(`alpha=${alpha?.toFixed(1)} beta=${beta?.toFixed(1)} gamma=${gamma?.toFixed(1)}`);
};
const needsPermission =
typeof DeviceOrientationEvent !== 'undefined' &&
typeof DeviceOrientationEvent.requestPermission === 'function';
if (needsPermission) {
// iOS/iPadOS Safari: Button anzeigen, Anfrage nur nach Benutzeraktion
button.hidden = false;
button.addEventListener('click', async () => {
try {
const state = await DeviceOrientationEvent.requestPermission();
console.log('Erlaubnis:', state);
if (state === 'granted') {
window.addEventListener('deviceorientation', handleOrientation);
button.hidden = true;
}
} catch (err) {
console.error('Anfrage fehlgeschlagen:', err.name);
}
});
} else {
// Andere Browser: keine Erlaubnis nötig
window.addEventListener('deviceorientation', handleOrientation);
}
Orientierung und Bewegung im selben Klick anfordern
const requestSensors = async () => {
const ask = (Ctor) =>
typeof Ctor?.requestPermission === 'function'
? Ctor.requestPermission()
: Promise.resolve('granted');
// Beide Anfragen sofort starten, solange die Benutzeraktion noch gilt
const [orientation, motion] = await Promise.all([
ask(window.DeviceOrientationEvent),
ask(window.DeviceMotionEvent)
]);
return { orientation, motion };
};
document.querySelector('#start-game').addEventListener('click', async () => {
const result = await requestSensors();
console.log(result);
});
Absolute Orientierung für einen Kompass
const compass = document.querySelector('#compass');
document.querySelector('#enable-compass').addEventListener('click', async () => {
const state = await DeviceOrientationEvent.requestPermission(true);
if (state !== 'granted') {
compass.textContent = 'Kompass nicht erlaubt';
return;
}
window.addEventListener('deviceorientation', (event) => {
// Safari liefert die Himmelsrichtung über webkitCompassHeading
const heading = event.webkitCompassHeading ?? (360 - event.alpha);
compass.style.transform = `rotate(${-heading}deg)`;
});
});
Fehlerfall: Aufruf ohne Benutzeraktion
// Direkt beim Laden aufgerufen, ohne Klick
DeviceOrientationEvent.requestPermission()
.then((state) => console.log(state))
.catch((err) => console.log(err.name));
// Wichtig · Fallstricke
- Erst auf Existenz prüfen: In Chrome, Edge und Firefox gibt es die Methode nicht. Wer sie dort ohne Prüfung aufruft, bekommt einen
TypeError. Deshalb immer vorher testen:typeof DeviceOrientationEvent.requestPermission === 'function'. - Nur nach einer Benutzeraktion: Der Aufruf muss direkt in einem Handler für
click,touchendo. Ä. stehen. Einawaitauf etwas anderes vor dem Aufruf kann die Benutzeraktivierung verbrauchen. Die Folge ist einNotAllowedError. - Sicherer Kontext: Die Methode funktioniert nur über HTTPS bzw.
localhost. In iframes muss die Permissions Policy den Zugriff erlauben, z. B.allow="accelerometer; gyroscope; magnetometer". - Ablehnung bleibt bestehen: Wenn der Benutzer abgelehnt hat, löst Safari je nach Version sofort mit
"denied"auf und zeigt keinen Dialog mehr. Der Benutzer muss die Website-Daten löschen oder den Tab neu öffnen. Bieten Sie in diesem Fall eine Alternative an, z. B. Steuerung per Touch. - Eigene Erlaubnis für Bewegung: Für
devicemotionist eine separate Erlaubnis überDeviceMotionEvent.requestPermission()nötig. - Datenschutz: Sensordaten eignen sich für Fingerprinting. Fordern Sie sie nur an, wenn eine Funktion sie wirklich braucht, und erklären Sie vorher, wozu.