Start · Sprachen · JavaScript · Referenz · MediaQueryList: change

MediaQueryList: change

Ereignis

Wird ausgelöst, wenn sich das Ergebnis einer Media Query ändert, also <code>MediaQueryList.matches</code> von <code>true</code> auf <code>false</code> wechselt oder umgekehrt.

seit JavaScript Baseline: alle modernen Browser (addEventListener- Kategorie: webapi

Signatur

mediaQueryList.addEventListener("change", handler)

Beschreibung

Das Ereignis change wird auf einem MediaQueryList-Objekt ausgelöst, das Sie mit window.matchMedia() erzeugt haben. Es feuert immer dann, wenn die Media Query neu ausgewertet wird und sich das Ergebnis dadurch ändert, zum Beispiel wenn das Fenster eine Breitengrenze überschreitet, das Gerät gedreht wird oder die Person im Betriebssystem zwischen hellem und dunklem Farbschema wechselt.

Der Handler bekommt ein MediaQueryListEvent mit den Eigenschaften matches (der neue boolesche Zustand) und media (die serialisierte Query als String). Sie können ihn mit addEventListener("change", handler) registrieren oder über die Eigenschaft onchange zuweisen.

Gegenüber einem resize-Listener ist das Ereignis deutlich effizienter: Es feuert nur beim tatsächlichen Wechsel des Zustands und nicht bei jedem Pixel. Damit eignet es sich gut für JavaScript-Logik, die zu CSS-Breakpoints passen soll, für Dark-Mode-Umschaltung, prefers-reduced-motion oder für die Erkennung von Druckansicht und Ausrichtung.

Wichtig: Beim Registrieren wird das Ereignis nicht sofort ausgelöst. Den Anfangszustand müssen Sie selbst über mql.matches abfragen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, hier immer "change".
$handler Pflicht (event: MediaQueryListEvent) => void Callback, der bei jedem Zustandswechsel aufgerufen wird. event.matches enthält den neuen Zustand, event.media die Query.
$options boolean | AddEventListenerOptions false Die üblichen Optionen von addEventListener, z. B. { once: true } oder { signal } zum Entfernen per AbortController.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler bekommt ein MediaQueryListEvent.

Beispiele

Responsives Verhalten per addEventListener

const mql = window.matchMedia("(max-width: 768px)");

const applyLayout = (isMobile) => {
  document.body.classList.toggle("mobile-nav", isMobile);
  console.log(isMobile ? "Mobil-Layout aktiv" : "Desktop-Layout aktiv");
};

// Anfangszustand selbst setzen, denn change feuert nicht beim Registrieren
applyLayout(mql.matches);

mql.addEventListener("change", (event) => {
  applyLayout(event.matches);
});
Desktop-Layout aktiv // nach dem Verkleinern unter 768px: Mobil-Layout aktiv

Dark Mode des Systems verfolgen (onchange-Property)

const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");

const setTheme = (dark) => {
  document.documentElement.dataset.theme = dark ? "dark" : "light";
};

setTheme(darkQuery.matches);

darkQuery.onchange = (event) => {
  setTheme(event.matches);
  console.log(`Theme gewechselt: ${event.media} -> ${event.matches}`);
};
Theme gewechselt: (prefers-color-scheme: dark) -> true

Listener wieder entfernen (removeEventListener und AbortController)

const motionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");

const onMotionChange = (event) => {
  console.log("Reduzierte Bewegung:", event.matches);
};

motionQuery.addEventListener("change", onMotionChange);
// später, z. B. beim Unmount einer Komponente:
motionQuery.removeEventListener("change", onMotionChange);

// Alternative: mehrere Listener auf einmal über ein Signal entfernen
const controller = new AbortController();
const printQuery = window.matchMedia("print");
printQuery.addEventListener("change", (e) => console.log("Druck:", e.matches), {
  signal: controller.signal,
});
controller.abort(); // Listener ist entfernt

// Wichtig · Fallstricke

  • Kein Initialaufruf: change feuert erst beim ersten Wechsel. Den Startzustand müssen Sie immer über mql.matches auswerten.
  • Veraltete API: mql.addListener(fn) und mql.removeListener(fn) gelten als veraltet. Safari vor Version 14 unterstützt nur diese Variante, dort war MediaQueryList noch kein EventTarget. Wenn Sie ältere Browser unterstützen müssen, prüfen Sie vorher: if (mql.addEventListener) { … } else { mql.addListener(fn); }.
  • Referenz behalten: Rufen Sie matchMedia() einmal auf und speichern Sie das Objekt. Ein zweiter Aufruf liefert ein neues Objekt, auf dem der Listener nicht registriert ist. removeEventListener funktioniert außerdem nur mit derselben Funktionsreferenz.
  • Nur Zustandswechsel: Das Ereignis meldet ausschließlich einen Wechsel von matches, keine Größenänderungen innerhalb eines Bereichs. Für stufenlose Werte brauchen Sie resize oder den ResizeObserver.
  • In iframes und bei Zoom werden Media Queries relativ zum jeweiligen Viewport ausgewertet. Durch Browser-Zoom kann das Ereignis deshalb ebenfalls feuern.