Start · Sprachen · JavaScript · Referenz · ScreenDetails: screenschange

ScreenDetails: screenschange

Ereignis

Wird auf einem <code>ScreenDetails</code>-Objekt ausgelöst, wenn ein Bildschirm an das System angeschlossen oder davon getrennt wurde.

seit JavaScript Chromium 100+ (Chrome, Edge, Opera); nicht in Fire Kategorie: webapi

Signatur

screenDetails.addEventListener("screenschange", handler)

Beschreibung

Das Ereignis screenschange gehört zur Window Management API, früher Multi-Screen Window Placement API genannt. Es wird auf dem ScreenDetails-Objekt ausgelöst, das window.getScreenDetails() liefert. Das passiert immer dann, wenn sich die Menge der verfügbaren Bildschirme ändert: Ein neuer Monitor, Beamer oder Fernseher wird angeschlossen oder ein vorhandener getrennt. Danach steht in screenDetails.screens bereits die aktualisierte Liste.

Einen Handler registrierst du entweder mit screenDetails.addEventListener("screenschange", handler) oder über die Eigenschaft screenDetails.onscreenschange = handler. Das Ereignisobjekt ist ein einfaches Event ohne zusätzliche Eigenschaften. Welche Bildschirme dazugekommen oder weggefallen sind, findest du nur heraus, wenn du die neue screens-Liste mit einem früheren Stand vergleichst.

Typische Einsatzfälle sind Präsentations-Software, die automatisch eine Referentenansicht auf dem zweiten Bildschirm öffnet, Handelsplattformen mit mehreren Fenstern, Werkzeuge für Videoproduktion oder Leitstände. Wird ein Bildschirm getrennt, kann die Anwendung ihre Fenster neu anordnen oder wieder auf dem Hauptbildschirm zusammenführen.

Abgrenzung: Ändern sich nur die Eigenschaften eines einzelnen Bildschirms, etwa Auflösung, Ausrichtung oder devicePixelRatio, wird screenschange nicht ausgelöst. Dafür gibt es das Ereignis change auf dem jeweiligen ScreenDetailed-Objekt. Wechselt das aktuelle Fenster auf einen anderen Bildschirm, meldet das currentscreenchange.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, immer "screenschange".
$handler Pflicht (event: Event) => void Callback, der ein einfaches Event-Objekt erhält. event.target ist das ScreenDetails-Objekt.
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal, zum Beispiel ein AbortSignal zum Entfernen des Listeners.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein Event ohne zusätzliche Eigenschaften.

Beispiele

Auf angeschlossene oder getrennte Bildschirme reagieren

// Muss durch eine Nutzeraktion ausgelöst werden (Berechtigungsabfrage)
document.querySelector('#multiscreen').addEventListener('click', async () => {
  if (!('getScreenDetails' in window)) {
    console.warn('Window Management API wird nicht unterstützt');
    return;
  }

  const screenDetails = await window.getScreenDetails();
  console.log(`Aktuell ${screenDetails.screens.length} Bildschirm(e)`);

  screenDetails.addEventListener('screenschange', () => {
    console.log(`Bildschirme geändert: jetzt ${screenDetails.screens.length}`);
    screenDetails.screens.forEach((s) => {
      console.log(`- ${s.label}: ${s.width}×${s.height}, primär: ${s.isPrimary}`);
    });
  });
});
Aktuell 1 Bildschirm(e) Bildschirme geändert: jetzt 2 - Built-in Retina Display: 1512×982, primär: true - DELL U2720Q: 2560×1440, primär: false

Hinzugefügte und entfernte Bildschirme ermitteln

const describe = (s) => `${s.label}@${s.left},${s.top}`;

const watchScreens = async () => {
  const details = await window.getScreenDetails();
  let known = new Set(details.screens.map(describe));

  details.onscreenschange = () => {
    const current = new Set(details.screens.map(describe));
    const added = [...current].filter((k) => !known.has(k));
    const removed = [...known].filter((k) => !current.has(k));
    console.log('Neu:', added, 'Entfernt:', removed);
    known = current;
  };
};

document.querySelector('#start').addEventListener('click', watchScreens);
Neu: ['HDMI-Beamer@1512,0'] Entfernt: []

Referentenansicht automatisch öffnen und Listener sauber entfernen

const controller = new AbortController();
let presenterWindow = null;

const placePresenterView = (details) => {
  const secondary = details.screens.find((s) => !s.isPrimary);
  if (secondary && !presenterWindow) {
    presenterWindow = window.open(
      '/presenter.html',
      'presenter',
      `left=${secondary.availLeft},top=${secondary.availTop},` +
      `width=${secondary.availWidth},height=${secondary.availHeight}`
    );
  } else if (!secondary && presenterWindow) {
    presenterWindow.close();
    presenterWindow = null;
  }
};

document.querySelector('#present').addEventListener('click', async () => {
  const details = await window.getScreenDetails();
  placePresenterView(details);
  details.addEventListener('screenschange', () => placePresenterView(details), {
    signal: controller.signal,
  });
});

// Präsentation beenden: Listener entfernen
document.querySelector('#stop').addEventListener('click', () => controller.abort());

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Das Ereignis gibt es nur in Chromium-basierten Browsern (ab Chrome/Edge 100). Firefox und Safari unterstützen die Window Management API nicht. Prüfe daher vorher mit 'getScreenDetails' in window, ob sie verfügbar ist.
  • Berechtigung: getScreenDetails() verlangt die Berechtigung window-management (früher window-placement) und einen sicheren Kontext (HTTPS). Lehnt der Nutzer ab, wird das Promise mit NotAllowedError abgewiesen, und es kommen gar keine Ereignisse an. In iframes muss die Permissions Policy window-management erlaubt sein.
  • Nicht verwechseln: Ändern sich Auflösung, Ausrichtung oder Skalierung eines Bildschirms, wird screenschange nicht ausgelöst. Dafür gibt es das Ereignis change auf dem ScreenDetailed-Objekt. Wechselt das Fenster auf einen anderen Bildschirm, wird currentscreenchange ausgelöst.
  • Keine Unterschiede im Ereignis: Das Ereignis enthält keine Informationen darüber, welche Bildschirme dazugekommen oder weggefallen sind. Merke dir den vorherigen Stand selbst, zum Beispiel über label und Position. label kann leer oder mehrdeutig sein.
  • Mehrfache Auslösung: Beim Anschließen per Docking-Station feuert das Ereignis unter Umständen mehrmals kurz hintereinander. Für aufwendige Neuanordnungen empfiehlt sich deshalb ein Debounce.
  • Datenschutz: Bildschirmdaten eignen sich für Fingerprinting. Frage die Berechtigung daher nur an, wenn die Funktion wirklich gebraucht wird.