VisualViewport
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. It’s been available across browsers since August 2021.
* Some parts of this feature may have varying levels of support.
Das VisualViewport-Interface der CSSOM view API repräsentiert das visuelle Viewport für ein bestimmtes Fenster. Für eine Seite, die iframes enthält, wird jedes iframe sowie die enthaltende Seite ein einzigartiges Fensterobjekt haben. Jedes Fenster auf einer Seite wird ein einzigartiges VisualViewport haben, das die Eigenschaften darstellt, die mit diesem Fenster verbunden sind.
Das mobile Web enthält zwei Viewports: den Layout-Viewport und den visuellen Viewport. Der Layout-Viewport erstreckt sich über alle Elemente einer Seite, während der visuelle Viewport das darstellt, was tatsächlich auf dem Bildschirm sichtbar ist. Wenn der Benutzer in die Seite hineinzoomt, verkleinert sich der visuelle Viewport, aber der Layout-Viewport bleibt unverändert. Benutzeroberflächenelemente wie die Bildschirmtastatur (OSK) können den visuellen Viewport verkleinern, ohne den Layout-Viewport zu beeinflussen.
Was passiert, wenn ein Element einer Webseite unabhängig vom sichtbaren Teil einer Webseite auf dem Bildschirm sichtbar sein muss? Zum Beispiel, was ist, wenn Sie ein Set von Bildsteuerungen dauerhaft sichtbar halten müssen, unabhängig vom Zoom-Level des Geräts? Aktuelle Browser variieren, wie sie dies handhaben. Der visuelle Viewport ermöglicht es Webentwicklern, dieses Problem zu lösen, indem Elemente relativ zu dem positioniert werden, was auf dem Bildschirm angezeigt wird.
Sie können den visuellen Viewport eines Fensters mit Window.visualViewport abrufen.
Hinweis:
Nur das Top-Level-Fenster hat einen visuellen Viewport, der sich vom Layout-Viewport unterscheidet. Daher ist in der Regel nur das VisualViewport-Objekt des Top-Level-Fensters nützlich. Für ein <iframe> stimmen visuelle Viewport-Metriken wie VisualViewport.width immer mit Layout-Viewport-Metriken wie document.documentElement.clientWidth überein.
Instanz-Eigenschaften
Erbt auch Eigenschaften von seinem Eltern-Interface, EventTarget.
VisualViewport.offsetLeftSchreibgeschützt-
Gibt den Versatz der linken Kante des visuellen Viewports von der linken Kante des Layout-Viewports in CSS-Pixeln zurück.
VisualViewport.offsetTopSchreibgeschützt-
Gibt den Versatz der oberen Kante des visuellen Viewports von der oberen Kante des Layout-Viewports in CSS-Pixeln zurück.
VisualViewport.pageLeftSchreibgeschützt-
Gibt die x-Koordinate des visuellen Viewports relativ zum Ursprung des initialen umgebenden Blocks der oberen Kante in CSS-Pixeln zurück.
VisualViewport.pageTopSchreibgeschützt-
Gibt die y-Koordinate des visuellen Viewports relativ zum Ursprung des initialen umgebenden Blocks der oberen Kante in CSS-Pixeln zurück.
VisualViewport.widthSchreibgeschützt-
Gibt die Breite des visuellen Viewports in CSS-Pixeln zurück.
VisualViewport.heightSchreibgeschützt-
Gibt die Höhe des visuellen Viewports in CSS-Pixeln zurück.
VisualViewport.scaleSchreibgeschützt-
Gibt den Pinch-Zoom-Skalierungsfaktor zurück, der auf den visuellen Viewport angewendet wird.
Instanz-Methoden
Erbt auch Methoden von seinem Eltern-Interface, EventTarget.
Ereignisse
Diese Ereignisse können über addEventListener() oder durch Zuweisung eines Ereignislisteners zur entsprechenden oneventname-Eigenschaft dieses Interfaces abgehört werden.
resize-
Wird ausgelöst, wenn der visuelle Viewport verändert wird. Auch verfügbar über die
onresize-Eigenschaft. scroll-
Wird ausgelöst, wenn der visuelle Viewport gescrollt wird. Auch verfügbar über die
onscroll-Eigenschaft. scrollend-
Wird ausgelöst, wenn eine Scroll-Operation auf dem visuellen Viewport endet. Auch verfügbar über die
onscrollend-Eigenschaft.
Beispiele
>Abrufen von visuellen Viewport-Informationen während des Scrollens und Zoomens
Unser visueller Viewport-Beispiel bietet eine grundlegende Demonstration, wie die verschiedenen Funktionen des visuellen Viewports funktionieren, einschließlich der drei Ereignistypen. Laden Sie die Seite in unterstützenden Desktop- und mobilen Browsern und versuchen Sie, die Seite zu scrollen und zu zoomen. Bei resize und scroll wird die Informationsbox so neu positioniert, dass sie ihre Position relativ zum visuellen Viewport beibehält, und die darin angezeigten Viewport- und Scroll-Informationen werden aktualisiert. Zudem färben wir die Box bei resize und scroll, um anzuzeigen, dass etwas geschieht, und setzen sie bei scrollend zurück.
Sie werden feststellen, dass bei Desktop-Browsern die Werte von Window.scrollX und Window.scrollY aktualisiert werden, wenn das Fenster verschoben wird — die Position des visuellen Viewports ändert sich nicht. Bei mobilen Browsern hingegen werden die Werte von VisualViewport.offsetLeft und VisualViewport.offsetTop in der Regel aktualisiert — meistens verändert sich der visuelle Viewport und nicht die Fensterposition.
Im Beispiel wird die HTML-Informationsbox durch ein <div> mit einer id von output dargestellt, während das CSS der Kürze halber ausgeblendet ist.
<p id="instructions">
Try scrolling around and pinch-zooming to see how the reported values change.
</p>
<div id="output">
<p id="visual-info"></p>
<hr />
<p id="window-info"></p>
</div>
Im JavaScript beginnen wir damit, Referenzen zur Informationsbox zu erhalten, die bei Zoom- und Scroll-Vorgängen aktualisiert wird, sowie zu den beiden Absätzen, die darin enthalten sind. Der erste wird die gemeldeten Werte von VisualViewport.offsetLeft und VisualViewport.offsetTop enthalten, während der zweite die gemeldeten Werte von Window.scrollX und Window.scrollY enthalten wird.
const output = document.getElementById("output");
const visualInfo = document.getElementById("visual-info");
const windowInfo = document.getElementById("window-info");
Als Nächstes definieren wir die beiden Schlüssel-Funktionen, die wir ausführen werden, wenn die Ereignisse ausgelöst werden:
- Die Funktion
scrollUpdater()wird beiresizeundscrollausgeführt: Diese Funktion aktualisiert die Position der Informationsbox relativ zum visuellen Viewport, indem die EigenschaftenVisualViewport.offsetTopundVisualViewport.offsetLeftabgefragt und ihre Werte verwendet werden, um die Werte der relevanten Inset-Eigenschaften zu aktualisieren. Außerdem ändern wir die Hintergrundfarbe der Informationsbox, um anzuzeigen, dass etwas geschieht, und führen die FunktionupdateText()aus, um die in der Box angezeigten Werte zu aktualisieren. - Die Funktion
scrollEndUpdater()wird beiscrollendausgeführt: Diese Funktion stellt die ursprüngliche Farbe der Informationsbox wieder her und führt die FunktionupdateText()aus, um sicherzustellen, dass die neuesten Werte beiscrollendangezeigt werden.
const scrollUpdater = () => {
output.style.top = `${visualViewport.offsetTop + 10}px`;
output.style.left = `${visualViewport.offsetLeft + 10}px`;
output.style.background = "yellow";
updateText();
};
const scrollendUpdater = () => {
output.style.background = "lime";
updateText();
};
Die Funktion updateText() setzt den HTMLElement.innerText des ersten Absatzes, um die aktuellen Werte von VisualViewport.offsetLeft und VisualViewport.offsetTop anzuzeigen, und den HTMLElement.innerText des zweiten Absatzes, um die aktuellen Werte von Window.scrollX und Window.scrollY anzuzeigen. Nachdem updateText() definiert wurde, wird es sofort aufgerufen, damit die Informationsbox beim Laden der Seite korrekt angezeigt wird.
function updateText() {
visualInfo.innerText = `Visual viewport left: ${visualViewport.offsetLeft.toFixed(2)}
top: ${visualViewport.offsetTop.toFixed(2)}`;
windowInfo.innerText = `Window scrollX: ${window.scrollX.toFixed(2)}
scrollY: ${window.scrollY.toFixed(2)}`;
}
updateText();
Wir haben alle Werte auf zwei Dezimalstellen mit der Methode Number.toFixed() gekürzt, da einige Browser Unterpixel-Werte mit möglicherweise vielen Dezimalstellen rendern.
Jetzt setzen wir Ereignishandler-Eigenschaften sowohl für den visuellen Viewport als auch für das Window-Objekt, um die Schlüssel-Funktionen zur passenden Zeit sowohl auf Mobilgeräten als auch auf dem Desktop auszuführen:
- Wir setzen die Handler auf
window, damit die Position und der Inhalt der Informationsbox bei konventionellen Scroll-Operationen des Fensters aktualisiert werden, beispielsweise beim Scrollen der Seite in einem Desktop-Browser. - Wir setzen die Handler auf
visualViewport, damit die Position und der Inhalt der Informationsbox bei Scroll- und Zoom-Operationen des visuellen Viewports aktualisiert werden, beispielsweise beim Scrollen und Zoomen der Seite in einem mobilen Browser.
visualViewport.onresize = scrollUpdater;
visualViewport.onscroll = scrollUpdater;
visualViewport.onscrollend = scrollendUpdater;
window.onresize = scrollUpdater;
window.onscroll = scrollUpdater;
window.onscrollend = scrollendUpdater;
Die Funktion scrollUpdater() wird bei resize und scroll ausgeführt, während scrollEndUpdater() bei scrollend ausgeführt wird.
Ausblenden einer überlagerten Box beim Zoomen
Dieses Beispiel, entnommen aus der Visual Viewport README, zeigt, wie man ein wenig Code schreibt, der eine überlagerte Box (die beispielsweise eine Werbung enthalten könnte) ausblendet, wenn der Benutzer hineinzoomt. Dies ist eine gute Möglichkeit, die Benutzererfahrung beim Zoomen auf Seiten zu verbessern. Ein Live-Beispiel ist ebenfalls verfügbar.
const bottomBar = document.getElementById("bottom-bar");
const viewport = window.visualViewport;
function resizeHandler() {
bottomBar.style.display = viewport.scale > 1.3 ? "none" : "block";
}
window.visualViewport.addEventListener("resize", resizeHandler);
Simulation von position: device-fixed
Dieses Beispiel, ebenfalls entnommen aus der Visual Viewport README, zeigt, wie diese API verwendet werden kann, um position: device-fixed zu simulieren, wodurch Elemente an den visuellen Viewport gebunden werden. Ein Live-Beispiel ist ebenfalls verfügbar.
const bottomBar = document.getElementById("bottom-bar");
const viewport = window.visualViewport;
function viewportHandler() {
const layoutViewport = document.getElementById("layoutViewport");
// Since the bar is position: fixed we need to offset it by the visual
// viewport's offset from the layout viewport origin.
const offsetLeft = viewport.offsetLeft;
const offsetTop =
viewport.height -
layoutViewport.getBoundingClientRect().height +
viewport.offsetTop;
// You could also do this by setting style.left and style.top if you
// use width: 100% instead.
bottomBar.style.transform = `translate(${offsetLeft}px, ${offsetTop}px) scale(${
1 / viewport.scale
})`;
}
window.visualViewport.addEventListener("scroll", viewportHandler);
window.visualViewport.addEventListener("resize", viewportHandler);
Hinweis:
Diese Technik sollte mit Vorsicht verwendet werden; die Emulation von position: device-fixed auf diese Weise kann dazu führen, dass das fixierte Element während des Scrollens flackert.
Spezifikationen
| Specification |
|---|
| CSSOM View Module> # the-visualviewport-interface> |
Browser-Kompatibilität
Siehe auch
- Web Viewports Explainer — nützliche Erklärung der Konzepte von Web-Viewports, einschließlich des Unterschieds zwischen visuellem Viewport und Layout-Viewport.