前端学堂
学有所用

portal网络上的无缝导航

确保页面快速加载是提供良好用户体验的关键。但是我们经常忽略的一个方面是页面过渡,即用户在页面之间移动时看到的内容。

一种新的网络平台API的提议称为门户旨在与此帮助通过简化,因为用户浏览体验您的网站。

门户目前处于试验阶段,但是您今天可以通过参与原始试用在您的站点上使用它们。

哪些门户网站启用了

单页应用程序(SPA)提供了很好的过渡,但以构建复杂性为代价。多页面应用程序(MPA)的构建要容易得多,但是最终导致页面之间出现空白屏幕。

门户网站提供了两全其美的优势:MPA的低复杂性和SPA的无缝过渡。可以考虑将它们视为iframe,因为它们允许嵌入,但是与不同iframe,它们还具有导航到其内容的功能。

试用门户网站

起源试验阶段期间启用支持

可以在Chrome 85中使用Portal进行原产地试用。该原产地试用预计将在Chrome 86中结束。

Origin试用版使您可以尝试新功能,并向Web标准社区提供有关其可用性,实用性和有效性的反馈。有关更多信息,请参见《针对Web开发人员Origin Trials指南》。要注册此试用版或其他原始试用版,请访问注册页面

注册原产地

  1. 要求您提供来源令牌
  2. 将令牌添加到您的页面。有两种方法可以做到这一点:
    • origin-trial 在每个页面的开头添加标签。例如,这可能类似于:
    • 如果可以配置服务器,则还可以使用Origin-TrialHTTP标头添加令牌。结果响应标头应类似于:
      Origin-Trial: TOKEN_GOES_HERE

通过chrome//flag启用:

通过翻转实验性标志来试用Chrome 85或86中的Portal chrome://flags/#enable-portals。在Portal实验的早期阶段,我们还建议通过设置--user-data-dir 命令行标志来使用完全独立的用户数据目录进行测试 。启用门户后,请在DevTools中确认您拥有新的Shiny HTMLPortalElement

DevTools控制台的屏幕快照,显示HTMLPortalElement

实施门户网站

让我们来看一个基本的实现示例。

// Create a portal with the wikipedia page, and embed it
// (like an iframe). You can also use the  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
portal.activate();

就这么简单。在DevTools控制台中尝试此代码,应该会打开Wikipedia页面。

预览门户样式演示的gif

如果您想构建像我们在Chrome Dev Summit上展示的一样的东西,就像上面的演示一样工作,那么下面的代码片段将很有趣。

// 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');
  ...
}

如果您想快速体验Portal的感觉,请尝试使用 uskay-portals-demo.glitch.me。确保使用Chrome 85或86访问它并打开实验性标志

  1. 输入您要预览的URL。
  2. 然后将页面作为元素嵌入。
  3. 单击预览。
  4. 动画播放后将激活预览。

使用Portal的故障演示的gif效果

我们正在积极讨论 Web孵化社区组(WICG)中的Portal规范。为了快速起步,请看一些 关键方案。这些是您熟悉的三个重要功能:

  • 元素: HTML元素本身。该API非常简单。它由src属性,activate函数和消息传递接口(postMessage)组成。activate接受一个可选参数,以在激活时将数据传递给。
  • portalHost接口:将一个portalHost对象到window对象。这使您可以检查页面是否作为元素嵌入。它还提供了用于将消息传递postMessage回主机的接口。
  • PortalActivateEvent接口:激活后触发的事件。有一个叫作整洁的函数adoptPredecessor,您可以使用它来检索上一页作为元素。这使您可以在两个页面之间创建无缝导航和组合体验。

让我们超越基本的使用模式。

 

下面看看基本使用模式以外的内容。以下是 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 如何在网站和第三方嵌入内容之间实现无缝的用户体验。

对这个演示感兴趣吗?可以在 GitHub 上 fork 它,并构建你自己的版本

赞(0) 打赏

微信扫码成为我的经纪人,不定期福利,一起分享哦!

未经允许不得转载:前端学堂 » portal网络上的无缝导航

谢谢您的支持,我不吃不喝也要定时更新!

支付宝扫一扫打赏

微信扫一扫打赏