Start · Sprachen · JavaScript · Referenz · ShadowRoot.pointerLockElement

ShadowRoot.pointerLockElement

Eigenschaft

Gibt das Element innerhalb dieses Shadow-Baums zurück, das gerade die Zeigersperre (Pointer Lock) hält, oder <code>null</code>.

seit JavaScript Baseline: alle modernen Browser (Chrome 53+, Firef Kategorie: webapi

Signatur

ShadowRoot.pointerLockElement

Beschreibung

Die schreibgeschützte Eigenschaft pointerLockElement des ShadowRoot-Interfaces liefert das Element, an das während einer aktiven Zeigersperre alle Mausereignisse gehen. Die Eigenschaft stammt aus dem Mixin DocumentOrShadowRoot und entspricht Document.pointerLockElement, bezieht sich aber auf den jeweiligen Shadow-Baum.

Für Web Components ist das wichtig: document.pointerLockElement gibt aus Kapselungsgründen nicht das eigentliche Element im Shadow DOM zurück, sondern nur den Shadow-Host. Nur über shadowRoot.pointerLockElement kommt man an das konkrete innere Element, zum Beispiel ein <canvas> in einer 3D-Viewer-Komponente oder einem Spiel.

Der Wert wird umgelenkt (retargeting):

  • Liegt das gesperrte Element direkt in diesem Shadow-Baum, bekommt man genau dieses Element.
  • Liegt es in einem verschachtelten Shadow-Baum, bekommt man den Shadow-Host, der in diesem Baum liegt.
  • Ist keine Sperre aktiv oder liegt das Element außerhalb dieses Shadow-Baums, ist der Wert null.

Typischerweise fragt man die Eigenschaft im Handler für das Ereignis pointerlockchange ab, um festzustellen, ob die eigene Komponente die Sperre bekommen oder verloren hat.

Rückgabewert

Typ
Element | null
Beschreibung
Das Element in diesem Shadow-Baum (oder der Host eines verschachtelten Shadow-Baums), das die Zeigersperre hält. Sonst null.

Beispiele

Zeigersperre für ein Canvas in einer Web Component

class GameView extends HTMLElement {
  constructor() {
    super();
    this.root = this.attachShadow({ mode: 'open' });
    this.root.innerHTML = '<canvas width="400" height="300"></canvas>';
    this.canvas = this.root.querySelector('canvas');
  }

  connectedCallback() {
    this.canvas.addEventListener('click', () => this.canvas.requestPointerLock());
    // pointerlockchange wird auf dem Document ausgelöst, nicht auf dem ShadowRoot
    this.onLockChange = () => {
      const locked = this.root.pointerLockElement === this.canvas;
      console.log('Canvas gesperrt:', locked);
      console.log('document.pointerLockElement:', document.pointerLockElement?.tagName);
    };
    document.addEventListener('pointerlockchange', this.onLockChange);
  }

  disconnectedCallback() {
    document.removeEventListener('pointerlockchange', this.onLockChange);
  }
}

customElements.define('game-view', GameView);
document.body.append(document.createElement('game-view'));
// Nach einem Klick auf das Canvas: Canvas gesperrt: true document.pointerLockElement: GAME-VIEW

Mausbewegung nur bei aktiver Sperre auswerten

const host = document.querySelector('game-view');
const root = host.shadowRoot;
const canvas = root.querySelector('canvas');
let yaw = 0;
let pitch = 0;

document.addEventListener('mousemove', (event) => {
  // Nur reagieren, wenn unser Canvas die Sperre hält
  if (root.pointerLockElement !== canvas) return;
  yaw += event.movementX * 0.2;
  pitch = Math.max(-90, Math.min(90, pitch - event.movementY * 0.2));
  console.log(`Blickrichtung: yaw=${yaw.toFixed(1)}, pitch=${pitch.toFixed(1)}`);
});
Blickrichtung: yaw=2.4, pitch=-1.0

Sperre per Taste gezielt aufheben

const root = document.querySelector('game-view').shadowRoot;

document.addEventListener('keydown', (event) => {
  if (event.key === 'p' && root.pointerLockElement) {
    document.exitPointerLock();
    console.log('Pause – Zeigersperre aufgehoben');
  }
});
Pause – Zeigersperre aufgehoben

// Wichtig · Fallstricke

  • Ereignisse auf dem Document: pointerlockchange und pointerlockerror werden auf dem document ausgelöst, nicht auf dem ShadowRoot. Listener also dort registrieren und in disconnectedCallback wieder entfernen.
  • Retargeting: document.pointerLockElement gibt bei Elementen im Shadow DOM nur den Host zurück. Einen Vergleich mit dem inneren Element sollte man deshalb immer über shadowRoot.pointerLockElement machen.
  • Geschlossene Shadow Roots: Bei mode: 'closed' kommt man von außen nicht über host.shadowRoot an den Baum. Die Referenz muss man intern speichern, zum Beispiel als Rückgabewert von attachShadow().
  • Benutzergeste nötig: requestPointerLock() funktioniert nur nach einer Benutzeraktion (etwa einem Klick). Mit Esc hebt der Browser die Sperre auf. Direkt danach lehnen manche Browser eine neue Anfrage kurz ab (pointerlockerror).
  • Kompatibilität: Wird von allen modernen Desktop-Browsern unterstützt. In Iframes braucht man sandbox=\"allow-pointer-lock\". Auf Mobilgeräten wird Pointer Lock meist nicht unterstützt. In neueren Browsern gibt requestPointerLock() ein Promise zurück, in älteren undefined.