You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SvelteKit纯客户端应用中全局管理在线/离线状态?

SvelteKit PWA 全局在线/离线状态管理最优方案

直接用SvelteKit原生的stores就行,完全没必要用Session或Cookies——在线状态是实时变化的,不需要持久化存储,浏览器本身的navigator.onLine就能提供初始状态,结合stores的响应式特性,刚好能实现全局共享、自动同步的需求。

具体实现步骤

1. 封装全局网络状态Store

在$lib/stores/目录下新建network.js,把监听逻辑写在这里,只需要一次:

import { writable } from 'svelte/store';

// 初始化状态为当前浏览器在线状态
const isOnline = writable(navigator.onLine);

// 绑定在线/离线事件,自动更新store
function setupNetworkListeners() {
  const updateOnline = () => isOnline.set(true);
  const updateOffline = () => isOnline.set(false);

  window.addEventListener('online', updateOnline);
  window.addEventListener('offline', updateOffline);

  // 页面卸载时清理监听,避免内存泄漏
  window.addEventListener('beforeunload', () => {
    window.removeEventListener('online', updateOnline);
    window.removeEventListener('offline', updateOffline);
  });
}

// 可选:添加心跳检测(解决navigator.onLine误判问题)
// 定时请求静态资源验证真实网络连通性
function setupHeartbeat() {
  const checkInterval = setInterval(async () => {
    try {
      const response = await fetch('/favicon.ico', { method: 'HEAD' });
      isOnline.set(response.ok);
    } catch {
      isOnline.set(false);
    }
  }, 5000); // 每5秒检测一次

  window.addEventListener('beforeunload', () => clearInterval(checkInterval));
}

// 初始化监听和心跳检测
setupNetworkListeners();
setupHeartbeat();

export { isOnline };

2. 全局UI统一处理(顶部菜单、背景图)

在根布局+layout.svelte里导入store,利用Svelte的响应式特性直接绑定样式:

<script>
  import { isOnline } from '$lib/stores/network.js';
</script>

<!-- 顶部菜单 -->
<header class:offline={!$isOnline}>
  <nav>
    <!-- 菜单内容 -->
  </nav>
</header>

<!-- 全局页面容器 -->
<div class="page-wrapper" class:offline-bg={!$isOnline}>
  <slot />
</div>

<style>
  header {
    background-color: #165DFF;
    transition: background-color 0.3s ease;
  }
  /* 离线时菜单背景色 */
  header.offline {
    background-color: #F53F3F;
  }

  .page-wrapper {
    min-height: 100vh;
    transition: background-image 0.3s ease;
  }
  /* 离线时全局背景图 */
  .page-wrapper.offline-bg {
    background-image: url('/offline-bg.png');
    background-size: cover;
    background-position: center;
  }
</style>

3. 局部组件控制(按钮禁用)

在需要的页面/组件里直接使用$isOnline状态控制按钮状态:

<script>
  import { isOnline } from '$lib/stores/network.js';
</script>

<form>
  <input type="text" placeholder="输入内容" />
  <!-- 离线时禁用提交按钮 -->
  <button type="submit" disabled={!$isOnline}>
    {$isOnline ? '提交' : '离线状态无法提交'}
  </button>
</form>

<style>
  button:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
</style>

为什么不用Session/Cookies?

  • 在线状态是实时临时状态,不需要持久化存储,页面刷新后浏览器会自动返回当前真实状态,store会重新初始化
  • Session/Cookies是用来存储用户身份、偏好等持久化数据的,用在这里完全是冗余操作,反而会增加不必要的复杂度

内容的提问来源于stack exchange,提问作者ZAky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:15:19