在 PWA 中,可以通过检查页面是否由 PWA 启动来实现特定功能(例如隐藏导航栏或显示不同的 UI)。以下是常见的方法来判断页面是否由 PWA 启动:


方法 1:使用 window.matchMedia

通过检测 display-mode 来判断页面启动方式。

示例代码:

if (window.matchMedia('(display-mode: standalone)').matches) {
  console.log('当前页面是以 PWA 模式启动的');
} else {
  console.log('当前页面是以浏览器模式启动的');
}
  • 解释
    • standalone 表示以 PWA 模式启动。
    • 其他可能的模式:
      • fullscreen:全屏启动。
      • minimal-ui:最小 UI 模式。
      • 默认是 browser,表示在普通浏览器中运行。

方法 2:检查 navigator.standalone

对于 iOS 设备,可以使用 navigator.standalone 属性。

示例代码:

if (window.navigator.standalone) {
  console.log('当前页面是以 PWA 模式启动的 (iOS)');
} else {
  console.log('当前页面是以浏览器模式启动的 (iOS)');
}
  • 解释
    • navigator.standalone 是 iOS Safari 的特有属性,返回 true 表示当前页面是以 PWA 模式启动。

方法 3:检测 window.location.referrer

通过检测 referrer,可以间接判断是否由某些 PWA 环境触发。

示例代码:

if (document.referrer === '') {
  console.log('当前页面可能是直接由 PWA 启动的');
} else {
  console.log('当前页面是从其他页面跳转来的');
}
  • 解释
    • 如果 referrer 为空且同时满足其他条件,可能是从主屏幕启动的。

方法 4:在 Service Worker 中传递状态

可以通过 Service Worker 为页面添加标记来标识启动来源。

示例代码:

  1. 在 Service Worker 中传递标记

    self.addEventListener('fetch', (event) => {
      const url = new URL(event.request.url);
      if (url.pathname === '/') {
        const modifiedRequest = new Request(event.request, {
          headers: new Headers({
            ...event.request.headers,
            'X-PWA-Start': 'true',
          }),
        });
        event.respondWith(fetch(modifiedRequest));
      }
    });
    
  2. 在页面中读取标记

    fetch('/')
      .then((response) => {
        if (response.headers.get('X-PWA-Start') === 'true') {
          console.log('当前页面是通过 PWA 启动的');
        }
      });
    

方法 5:结合 URL 参数

如果 PWA 应用的入口是通过 start_url 指定的,可以在 manifest.jsonstart_url 中添加特定的参数来标识启动来源。

修改 manifest.json

{
  "start_url": "/?pwa=true",
  "display": "standalone",
  ...
}

在页面中检查参数:

const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('pwa') === 'true') {
  console.log('当前页面是以 PWA 模式启动的');
}

方法 6:综合检测

在实际项目中,可以结合以上多种方法来提高判断的准确性:

function isPWAMode() {
  const isStandalone =
    window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone;
  const hasPWATag = document.referrer === '' || new URLSearchParams(window.location.search).has('pwa');
  return isStandalone || hasPWATag;
}

if (isPWAMode()) {
  console.log('当前页面是以 PWA 模式启动的');
} else {
  console.log('当前页面是以浏览器模式启动的');
}

总结

以上方法可以单独使用,也可以结合起来提高判断准确性。

一般情况下,使用 window.matchMedia 是最推荐的方法,因为它直接针对 PWA 的显示模式。对于更复杂的应用场景,可以结合 Service Worker 和 URL 参数。