VisualViewport

Baseline 廣泛可用 *

此特性已發展成熟,可在多種裝置和瀏覽器版本上使用。自 ⁨2021 年 8 月⁩ 起,它已在所有瀏覽器中可用。

* 此特性的某些部分可能存在不同級別的支援。

VisualViewport 介面是 Visual Viewport API 的一部分,用於表示給定視窗的可視視口。對於包含 iframe 的頁面,每個 iframe 以及包含它的頁面都會有一個唯一的視窗物件。頁面上的每個視窗都有一個唯一的 VisualViewport,用於表示與該視窗關聯的屬性。

您可以透過 Window.visualViewport 獲取視窗的可視視口。

注意: 只有頂層視窗的可視視口才與佈局視口不同。因此,通常只有頂層視窗的 VisualViewport 物件才有用。對於 <iframe>,可視視口度量(例如 VisualViewport.width)始終對應於佈局視口度量(例如 document.documentElement.clientWidth)。

EventTarget VisualViewport

例項屬性

還繼承了其父介面 EventTarget 的屬性。

VisualViewport.offsetLeft 只讀

返回可視視口的左邊緣與佈局視口左邊緣的偏移量,以 CSS 畫素為單位。

VisualViewport.offsetTop 只讀

返回可視視口的頂部邊緣與佈局視口頂部邊緣的偏移量,以 CSS 畫素為單位。

VisualViewport.pageLeft 只讀

返回可視視口相對於頂邊初始包含塊原點的 x 座標,以 CSS 畫素為單位。

VisualViewport.pageTop 只讀

返回可視視口相對於頂邊初始包含塊原點的 y 座標,以 CSS 畫素為單位。

VisualViewport.width 只讀

返回可視視口的寬度,以 CSS 畫素為單位。

VisualViewport.height 只讀

返回可視視口的高度,以 CSS 畫素為單位。

VisualViewport.scale 只讀

返回應用於可視視口的捏合縮放因子。

例項方法

還繼承了其父介面 EventTarget 的方法。

事件

使用 addEventListener() 或將事件監聽器分配給此介面的相應 oneventname 屬性來監聽這些事件。

resize

當可視視口大小調整時觸發。也可透過 onresize 屬性訪問。

scroll

當可視視口滾動時觸發。也可透過 onscroll 屬性訪問。

scrollend

當可視視口的滾動操作結束時觸發。也可透過 onscrollend 屬性訪問。

示例

縮放時隱藏覆蓋框

此示例摘自 Visual Viewport README,展示瞭如何編寫少量程式碼,在使用者放大頁面時隱藏覆蓋框(例如廣告)。這是一個改善使用者在放大頁面時體驗的好方法。還有一個 即時示例

js
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);

模擬 position: device-fixed

此示例也摘自 Visual Viewport README,展示瞭如何使用此 API 來模擬 position: device-fixed,該屬性將元素固定到可視視口。還有一個 即時示例

js
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);

注意: 應謹慎使用此技術;以這種方式模擬 position: device-fixed 可能會導致固定元素在滾動時閃爍。

規範

規範
CSSOM 檢視模組
# the-visualviewport-interface

瀏覽器相容性

另見

  • Web Viewports Explainer — 對 Web 視口概念的有用解釋,包括可視視口和佈局視口之間的區別。