Signatur
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
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}`);
});
});
});
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);
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 Berechtigungwindow-management(früherwindow-placement) und einen sicheren Kontext (HTTPS). Lehnt der Nutzer ab, wird das Promise mitNotAllowedErrorabgewiesen, und es kommen gar keine Ereignisse an. In iframes muss die Permissions Policywindow-managementerlaubt sein. - Nicht verwechseln: Ändern sich Auflösung, Ausrichtung oder Skalierung eines Bildschirms, wird
screenschangenicht ausgelöst. Dafür gibt es das Ereignischangeauf demScreenDetailed-Objekt. Wechselt das Fenster auf einen anderen Bildschirm, wirdcurrentscreenchangeausgelö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
labelund Position.labelkann 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.