Start · Sprachen · JavaScript · Referenz · VisualViewport: resize

VisualViewport: resize

Ereignis

Wird ausgelöst, wenn sich die Größe des visuellen Viewports ändert – etwa durch Pinch-Zoom, eingeblendete Bildschirmtastatur oder Fenstergrößenänderung.

seit JavaScript Baseline: seit 2021 in allen modernen Browsern (Ch Kategorie: webapi

Signatur

visualViewport.addEventListener("resize", handler)

Beschreibung

Das resize-Ereignis von VisualViewport feuert immer dann, wenn sich die Breite oder Höhe des visuellen Viewports ändert. Der visuelle Viewport ist der tatsächlich sichtbare Ausschnitt der Seite. Er kann kleiner sein als der Layout-Viewport, z. B. wenn der Nutzer per Pinch hineinzoomt oder auf Mobilgeräten die Bildschirmtastatur eingeblendet wird.

Das Ereignis wird über window.visualViewport.addEventListener("resize", handler) oder über die Eigenschaft window.visualViewport.onresize registriert. Der Handler bekommt ein einfaches Event-Objekt ohne Größenangaben. Die aktuellen Werte liest man direkt aus visualViewport.width, height, scale, offsetTop und offsetLeft.

Typische Einsatzfälle sind: fixierte Werkzeugleisten oberhalb der Bildschirmtastatur halten, schwebende Elemente beim Zoomen an ihrer Position lassen oder Layouts an die wirklich sichtbare Fläche anpassen. Anders als window-resize reagiert dieses Ereignis auch auf Zoom und Tastatur, die den Layout-Viewport nicht verändern.

Verschiebt sich der visuelle Viewport nur, ohne seine Größe zu ändern, feuert stattdessen das Ereignis scroll von VisualViewport. Für eine vollständige Nachführung sollte man meist beide Ereignisse abonnieren.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "resize".
$handler Pflicht (event: Event) => void Callback-Funktion. Sie erhält ein allgemeines Event; event.target ist das VisualViewport-Objekt.
$options boolean | AddEventListenerOptions false Optionale Einstellungen wie once, passive oder signal (zum Entfernen über einen AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Die neuen Maße liest man im Handler aus visualViewport aus.

Beispiele

Größenänderung protokollieren (addEventListener)

const vv = window.visualViewport;

const logSize = () => {
  console.log(`Sichtbar: ${Math.round(vv.width)}×${Math.round(vv.height)} px, Zoom: ${vv.scale.toFixed(2)}`);
};

if (vv) {
  vv.addEventListener('resize', logSize);
  logSize();
}
Sichtbar: 390×664 px, Zoom: 1.00 Sichtbar: 390×328 px, Zoom: 1.00 // nach Einblenden der Tastatur

Werkzeugleiste über der Bildschirmtastatur halten

const toolbar = document.querySelector('#toolbar');
const vv = window.visualViewport;

const positionToolbar = () => {
  // Abstand zwischen Unterkante des Layout-Viewports und Unterkante des sichtbaren Bereichs
  const offsetBottom = window.innerHeight - (vv.height + vv.offsetTop);
  toolbar.style.transform = `translateY(${-Math.max(0, offsetBottom)}px)`;
};

vv.addEventListener('resize', positionToolbar);
vv.addEventListener('scroll', positionToolbar);
positionToolbar();

on-Property und Entfernen per AbortController

const vv = window.visualViewport;

// Variante 1: on-Property (überschreibt einen vorherigen Handler)
vv.onresize = () => console.log('Neue Höhe:', vv.height);

// Variante 2: Listener mit AbortController wieder entfernen
const controller = new AbortController();
vv.addEventListener('resize', () => {
  console.log('Zoomfaktor:', vv.scale);
}, { signal: controller.signal });

// Später, z. B. beim Verlassen der Ansicht:
controller.abort();
vv.onresize = null;
Neue Höhe: 512 Zoomfaktor: 1.5

Handler mit requestAnimationFrame drosseln

const vv = window.visualViewport;
let scheduled = false;

const onResize = () => {
  if (scheduled) return;
  scheduled = true;
  requestAnimationFrame(() => {
    document.documentElement.style.setProperty('--vv-height', `${vv.height}px`);
    scheduled = false;
  });
};

vv.addEventListener('resize', onResize, { passive: true });

// Später wieder entfernen:
// vv.removeEventListener('resize', onResize);

// Wichtig · Fallstricke

  • Keine Daten im Event: Das Ereignisobjekt enthält keine Maße. Die Werte stehen in window.visualViewport bzw. event.target.
  • Existenz prüfen: In älteren Browsern (z. B. Firefox vor Version 91) gibt es window.visualViewport nicht. Vorher prüfen: if (window.visualViewport) { … }.
  • Tastaturverhalten unterscheidet sich je Plattform: Unter iOS Safari verkleinert die Bildschirmtastatur nur den visuellen Viewport. Unter Android Chrome wurde früher auch der Layout-Viewport verkleinert. Seit Chrome 108 geschieht das standardmäßig nicht mehr, steuerbar über <meta name="viewport" content="interactive-widget=…">. Auf mobilen Geräten immer testen.
  • Hohe Auslösefrequenz: Beim Pinch-Zoom feuert das Ereignis sehr oft. Aufwendige DOM-Änderungen sollte man per requestAnimationFrame bündeln und Layout-Thrashing (abwechselndes Lesen und Schreiben von Layout-Werten) vermeiden.
  • Nicht mit window-resize verwechseln: Beim Zoomen feuert window kein resize, visualViewport dagegen schon. Ändert sich nur offsetTop/offsetLeft, kommt ein scroll-Ereignis und kein resize.
  • Das Ereignis steigt nicht auf (kein Bubbling) und lässt sich nicht abbrechen.