谷歌推出新提案Portals:Web上的無縫跳轉體驗

谷歌推出新提案Portals:Web上的無縫跳轉體驗


image.png



做者 | Yusuke Utsunomiya譯者 | 王強編輯 | 張之棟、王文婧想要了解新提案的 Portals API 是如何改善頁面跳轉用戶體驗的嗎?本文將主要對 Portals 的具體內容、Portals 在 Chrome Canary 中的試用、Portals 的規範等幾個方面進行詳細講解。若是你但願用戶在瀏覽自家網站時,可以在不一樣頁面跳轉得更加流暢,不妨來讀一讀這篇文章。react

確保頁面快速加載是提供良好用戶體驗的關鍵。可是咱們常常忽略的一個領域是頁面過渡,也就是用戶在頁面之間移動時所看到的內容。git

一項名爲 Portals 的 Web 平臺 API 新提案,可讓用戶在瀏覽網站時提高不一樣頁面間跳轉的流暢體驗,從而幫助實現這一目標。github

如下連接中的視頻展現了 Portals 的實際使用效果:https://storage.googleapis.com/web-dev-assets/hands-on-portals/portals_h264.mp4 web

Portals 帶來了哪些內容

單頁應用程序(SPA)提供了很好的頁面過渡效果,但代價是更高的構建複雜性。多頁面應用程序(MPA)的構建更容易一些,但結果會致使頁面之間跳轉時屏幕顯示空白內容。ajax

Portals 則取二者所長:同時具有 MPA 的低複雜性和 SPA 的無縫過渡效果。能夠將它們視爲一個<iframe>,其中能夠嵌入內容。但與<iframe>不一樣,它們還具備跳轉到其中內容上的功能。chrome

眼見爲實,請先來看看咱們去年在 Chrome 開發者峯會上展現的內容: https://youtu.be/Ai4aZ9Jbsysapi

使用經典跳轉時,用戶必須在等待時看着空白屏幕,直到瀏覽器渲染完目標頁面爲止。如今有了 Portals,用戶能夠在等待時體驗到動畫效果,而<portal>會預渲染內容並建立出無縫的跳轉體驗。跨域

在 Portals 誕生以前,咱們可使用<iframe>來預先渲染另外一個頁面。咱們還能夠添加動畫在頁面上移動這個 frame。可是<iframe>不能讓你跳轉到其中的內容上。Portals 彌補了這一空白,從而能夠實現一些有趣的用例。promise

在 Chrome Canary 中試用 Portals

要在 Chrome Canary 中試用 Portals,只需啓用一個實驗性標誌: chrome://flags/#enable-portals瀏覽器

目前在 Portals 實驗的早期階段,咱們還建議設置 --user-data-dir命令行標誌,使用徹底獨立的用戶數據目錄進行測試。啓用 Portals 後,在開發工具中確認你已經有了全新的 HTMLPortalElement。

image.png

讓咱們來看一個基本的例子。
// 用維基百科頁面建立一個 portal,而後嵌入它。
// (就像一個 iframe)。你也可使用<portal>標誌。
portal = document.createElement('portal');
portal.src = 'https://en.wikipedia.org/wiki/World_Wide_Web';
portal.style = '...';
document.body.appendChild(portal);

// 用戶觸碰預覽時(嵌入的 portal):
// 播放漂亮的動畫,例如展開……
// 實際跳轉完成後動畫結束。
portal.activate();

就這麼簡單。在開發工具控制檯中嘗試這段代碼,應該會打開維基百科頁面。

image.png

若是你想構建像咱們在 Chrome 開發者峯會上展現的那種效果,就像上面的視頻演示那樣,那麼能夠看看下面這段有趣的代碼。
// 添加一些過渡樣式
const style = document.createElement('style');
style.innerHTML = `
  portal {
    position:fixed;
    width: 100%;
    height: 100%;
    opacity: 0;
    box-shadow: 0 0 20px 10px #999;
    transform: scale(0.4);
    transform-origin: bottom left;
    bottom: 20px;
    left: 20px;
    animation-name: fade-in;
    animation-duration: 1s;
    animation-delay: 2s;
    animation-fill-mode: forwards;
  }
  .portal-transition {
    transition: transform 0.4s;
  }
  @media (prefers-reduced-motion: reduce) {
    .portal-transition {
      transition: transform 0.001s;
    }
  }
  .portal-reveal {
    transform: scale(1.0) translateX(-20px) translateY(20px);
  }
  @keyframes fade-in {
    0% { opacity: 0; }
    100% { opacity: 1; }
  }
`
;
const portal = document.createElement('portal');
// 跳轉到 WICG Portals spec 頁面
portal.src = 'https://wicg.github.io/portals/';
// 添加一個定義了過渡效果的類。考慮使用
// `prefers-reduced-motion` media query 來控制動畫。
// https://developers.google.com/web/updates/2019/03/prefers-reduced-motion
portal.classList.add('portal-transition');
portal.addEventListener('click'evt => {
  // 用戶交互時顯示 portal 的動畫
  portal.classList.add('portal-reveal');
});
portal.addEventListener('transitionend'evt => {
  if (evt.propertyName == 'transform') {
    // 過渡效果完成時激活這個 portal
    portal.activate();
  }
});
document.body.append(style, portal);
功能檢測也很容易,這樣就可使用 Portals 對網站進行漸進式加強。
if ('HTMLPortalElement' in window) {
  // 若是這個平臺有 Portals……
  const portal = document.createElement('portal');
  ...
}
若是你想快速體驗 Portal 的感受,請試試 uskay-portals-demo.glitch.me。請使用 Chrome Canary 訪問它並打開實驗性標誌!
  1. 輸入你要預覽的 URL。
  2. 而後,該頁面將做爲一個<portal>元素嵌入。
  3. 單擊預覽。
  4. 動畫播放後將激活預覽。

image.png

查看規範咱們正在 Web 孵化社區組(WICG)中積極討論 Portals 的規範。要跟上最新的節奏,請看一下 explainer。如下是你須要熟悉的三個重要功能:
  • <portal>元素:HTML 元素自己。該 API 很是簡單。它由 src 屬性、activate 函數和消息傳遞接口(postMessage)組成。activate 帶有一個可選參數,以在激活時將數據傳遞給<portal>
  • portalHost接口:將一個 portalHost 對象添加到 window 對象。這使你能夠檢查頁面是否做爲<portal>元素嵌入。它還提供了用於將消息傳遞(postMessage)返回主機的接口。
  • PortalActivateEvent接口:激活<portal>時將觸發的事件。有一個整潔的函數,名爲 adoptPredecessor,你能夠用它將上一頁做爲一個<portal>元素取回。這使你能夠在兩個頁面之間建立無縫跳轉和組合式體驗。

下面看看基本使用模式之外的內容。如下是 Portals 能夠實現的內容詳細列表及示例代碼。

當嵌入爲元素時自定義樣式

// 檢查該頁面是否由一個 portal 託管
if (window.portalHost) {
  // 嵌入爲 portal 時自定義 UI
}

元素和 portalHost 之間的消息傳遞

// 向 portal 元素髮送消息
const portal = document.querySelector('portal');
portal.postMessage({someKey: someValue}, ORIGIN);

// 經過 window.portalHost 接收消息
window.portalHost.addEventListener('message'evt => {
  const data = evt.data.someKey;
  // 處理事件
});

激活元素並接收 portalactivate 事件

// 你能夠選擇向激活函數的參數添加數據
portal.activate({data: {'somekey''somevalue'}});

// 激活時 portal 內容會接收 portalactivate 事件
window.addEventListener('portalactivate'evt => {
  // 數據做爲 evt.data 可用
  const data = evt.data;
});

獲取前頁

// 偵聽 portalactivate 事件
window.addEventListener('portalactivate'evt => {
  // ……創新地使用前頁
  const portal = evt.adoptPredecessor();
  document.querySelector('someElm').appendChild(portal);
});

知道你的頁面已被視爲前頁

// 激活函數返回一個 Promise.
// 當 promise 解析時, 意味着 portal 已被激活。
// 若是該文檔被其採用,則會存在 window.portalHost。
portal.activate().then(_ => {
  // 檢查該文檔是否被 portal 元素採納。
  if (window.portalHost) {
    // 能夠開始與 portal 元素通訊
    // 如偵聽消息
    window.portalHost.addEventListener('message'evt => {
      // 處理事件
    });
  }
});

經過組合 Portals 支持的全部這些功能,你能夠構建很是精美的用戶體驗。例如,下面演示了 Portal 如何在網站和第三方嵌入內容之間實現無縫的用戶體驗: https://youtu.be/4JkipxFVE9k

對這個演示感興趣嗎?能夠在 GitHub 上 fork 它,並構建你本身的版本: https://github.com/WICG/portals/tree/master/demos/portal-embed-demo

用例和計劃

咱們但願你喜歡這篇關於 Portals 的簡短介紹!咱們火燒眉毛想看看你們能作出些什麼內容。你可能想要開始使用 Portals 進行很是規跳轉,好比,從產品類別列表頁面中預渲染最暢銷產品頁面。

另外一件重要的事情是,Portals 能夠像<iframe>同樣用於跨域跳轉。所以,若是你有多個相互交叉引用的網站,還可使用 Portals 在兩個不一樣的網站之間建立無縫跳轉。這是 Portals 的獨特用例,甚至能夠改善 SPA 的用戶體驗。

歡迎反饋

Portals 提案仍處於早期階段,所以並不是一切都能正常工做(這就是它位於實驗性標誌後的緣由)。也就是說,它已準備好在 Chrome Canary 中進行實驗。社區的反饋對於新 API 的設計相當重要,所以請嘗試一下,並告訴咱們你的想法!你能夠在 Chromium 錯誤跟蹤器上檢查當前的限制條件。若是你有任何功能要求或反饋,請轉到 WICG GitHub 倉庫: https://github.com/WICG/portals/issues

原文連接:

https://web.dev/hands-on-portals/閱讀 4342分享收藏贊在看23寫下你的留言精選留言。°Ler2多年前用uc有一個鼠標懸停預覽的功能,懸停某個連接就會出現和這個同樣的功能。firegnu1一樓的那是早期ajax的實現.:D1谷歌666哦~Brandonxiang1支持,但願全部瀏覽器跟進Xheldon
相關文章
相關標籤/搜索