瞭解 Portals API 提案如何改善導覽使用者體驗。
確保網頁載入速度快,是提供良好使用者體驗的關鍵。不過,我們經常忽略的一個領域是網頁轉場效果,也就是使用者在不同網頁之間移動時看到的內容。
新的網站平台 API 提案名為 Portals,旨在協助簡化使用者在網站中瀏覽的體驗。
瞭解 Portal 的實際應用情形:
入口網站可啟用的功能
單頁應用程式 (SPA) 可提供不錯的轉場效果,但建構成本較高。多頁應用程式 (MPA) 的建構作業較為簡單,但會導致頁面之間出現空白畫面。
入口網站可同時兼顧兩種優點:MPA 的低複雜度,以及 SPA 的無縫轉換。可將其視為 <iframe>
,因為它們允許嵌入,但與 <iframe>
不同的是,它們還提供導覽至內容的功能。
眼見為憑:請先查看我們在 2018 年 Chrome 開發人員高峰會中展示的內容:
使用傳統導覽功能時,使用者必須在空白畫面中等待,直到瀏覽器完成轉譯目的地為止。使用者可透過 Portals 體驗動畫,同時 <portal>
會預先轉譯內容,打造流暢的導覽體驗。
在 Portals 推出之前,我們可以使用 <iframe>
轉譯其他網頁。我們也可以新增動畫,讓框架在頁面中移動。但 <iframe>
無法讓您瀏覽其內容。入口網站可彌補這項差距,實現有趣的應用情境。
試用入口網站
透過 about://flags 啟用
如要試用 Chrome 85 以上版本中的 Portals,請切換實驗性標記:
- 為同源導覽啟用
about://flags/#enable-portals
旗標。 - 如要測試跨原始來源導覽,請另外啟用
about://flags/#enable-portals-cross-origin
標記。
在 Portals 實驗的初期階段,我們也建議您設定 --user-data-dir
指令列標記,為測試使用完全獨立的使用者資料目錄。啟用 Portals 後,請在開發人員工具中確認您有新的閃亮 HTMLPortalElement
。
實作入口網站
讓我們來看看基本實作範例。
// Create a portal with the wikipedia page, and embed it
// (like an iframe). You can also use the <portal> tag instead.
portal = document.createElement('portal');
portal.src = 'https://en.wikipedia.org/wiki/World_Wide_Web';
portal.style = '...';
document.body.appendChild(portal);
// When the user touches the preview (embedded portal):
// do fancy animation, e.g. expand …
// and finish by doing the actual transition.
// For the sake of simplicity, this snippet will navigate
// on the `onload` event of the Portals element.
portal.addEventListener('load', (evt) => {
portal.activate();
});
方法就是這麼簡單。請在開發人員工具控制台中試試這個程式碼,Wikipedia 頁面應該會開啟。
如果您想建構類似於我們在 Chrome 開發人員高峰會上展示的內容,並且運作方式與上述示範相同,那麼您會對下列程式碼片段感興趣。
// Adding some styles with transitions
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');
// Let's navigate into the WICG Portals spec page
portal.src = 'https://wicg.github.io/portals/';
// Add a class that defines the transition. Consider using
// `prefers-reduced-motion` media query to control the animation.
// https://developers.google.com/web/updates/2019/03/prefers-reduced-motion
portal.classList.add('portal-transition');
portal.addEventListener('click', (evt) => {
// Animate the portal once user interacts
portal.classList.add('portal-reveal');
});
portal.addEventListener('transitionend', (evt) => {
if (evt.propertyName == 'transform') {
// Activate the portal once the transition has completed
portal.activate();
}
});
document.body.append(style, portal);
您也可以輕鬆執行功能偵測,逐步改善使用 Portal 的網站。
if ('HTMLPortalElement' in window) {
// If this is a platform that have Portals...
const portal = document.createElement('portal');
...
}
如要快速體驗 Portals 的使用體驗,請試試 uskay-portals-demo.glitch.me。請務必使用 Chrome 85 以上版本存取,並開啟實驗性功能旗標!
- 輸入要預覽的網址。
- 網頁會以
<portal>
元素嵌入。 - 按一下預覽畫面。
- 動畫播放完畢後,系統會啟用預覽畫面。
查看規格
我們正積極在 Web Incubation Community Group (WICG) 討論Portals 規格。如要快速上手,請查看幾個重要情境。以下是三個您需要熟悉的重要功能:
<portal>
元素:HTML 元素本身。這個 API 非常簡單。它包含src
屬性、activate
函式和訊息介面 (postMessage
)。activate
會採用選用引數,在啟用時將資料傳遞至<portal>
。portalHost
介面:將portalHost
物件新增至window
物件。這樣就能檢查網頁是否以<portal>
元素嵌入。它也提供訊息介面 (postMessage
),可將訊息傳回主機。- PortalActivateEvent 介面:在
<portal>
啟用時觸發的事件。您可以使用名為adoptPredecessor
的簡潔函式,將前一頁擷取為<portal>
元素。這可讓您在兩個頁面之間建立流暢的導覽和組合體驗。
讓我們進一步探討基本使用模式。以下列舉 Portal 的功能 (僅列舉部分內容),以及相關程式碼範例。
自訂嵌入為 <portal>
元素時的樣式
// Detect whether this page is hosted in a portal
if (window.portalHost) {
// Customize the UI when being embedded as a portal
}
<portal>
元素和 portalHost
之間的訊息傳遞
// Send message to the portal element
const portal = document.querySelector('portal');
portal.postMessage({someKey: someValue}, ORIGIN);
// Receive message via window.portalHost
window.portalHost.addEventListener('message', (evt) => {
const data = evt.data.someKey;
// handle the event
});
啟用 <portal>
元素並接收 portalactivate
事件
// You can optionally add data to the argument of the activate function
portal.activate({data: {somekey: 'somevalue'}});
// The portal content will receive the portalactivate event
// when the activate happens
window.addEventListener('portalactivate', (evt) => {
// Data available as evt.data
const data = evt.data;
});
擷取前置項目
// Listen to the portalactivate event
window.addEventListener('portalactivate', (evt) => {
// ... and creatively use the predecessor
const portal = evt.adoptPredecessor();
document.querySelector('someElm').appendChild(portal);
});
知道你的網頁已採用前身網頁
// The activate function returns a Promise.
// When the promise resolves, it means that the portal has been activated.
// If this document was adopted by it, then window.portalHost will exist.
portal.activate().then(() => {
// Check if this document was adopted into a portal element.
if (window.portalHost) {
// You can start communicating with the portal element
// i.e. listen to messages
window.portalHost.addEventListener('message', (evt) => {
// handle the event
});
}
});
只要結合 Portal 支援的所有功能,就能打造出非常精彩的使用者體驗。舉例來說,下方示範影片展示了 Portal 如何在網站和第三方嵌入內容之間,提供順暢的使用者體驗。
用途和計畫
希望你喜歡這次的 Portal 簡介!期待你繼續大展身手!舉例來說,您可能想開始使用 Portal 進行非簡單的導覽,例如:從產品類別產品資訊頁面預先轉譯暢銷產品的網頁。
另外,Portal 可用於跨來源導覽,就像 <iframe>
一樣。因此,如果您有幾個互相參照的網站,也可以使用 Portals 在兩個網站之間建立無縫的導覽功能。這個跨來源用途是 Portal 的獨特功能,甚至可以改善 SPA 的使用者體驗。
歡迎踴躍提供意見
在 Chrome 85 以上版本中,您可以開始嘗試使用 Portal。社群提供的意見對於新 API 的設計至關重要,歡迎您試用並提供寶貴意見!如有任何功能要求或意見回饋,請前往 WICG GitHub 存放區。