你会用JS获取你当前的网络状况吗?

公众号:程序员白特,欢迎一起交流学习~

我们知道,在Web端检测网速其实很简单,只需使用一个全局对象——navigation,让我们来看看它包含了哪些信息:


属性 描述 类型
downlink 有效带宽估算(单位:兆比特/秒) number
effectiveType 网络连接类型 slow-2g/2g/3g/4g
rtt 当前连接的往返时延评估 number
saveData 用户代理是否启用了数据节省选项 boolean

useNetwork

我们可以定制一个hook,以便获取当前网页的网络状态~必须包含以下要素:

  • 返回所需数据的ts类、监听网络变化的enum
  • 获取网络状态
  • 监听网络变化,并实时更新最新的网络状态.

第一步:所需的ts类型

描述一下NetworkState的各个参数:

  • since:记录检测的时间
  • oline:记录网络是否可用
  • rtt:记录延迟时间
  • downlink:记录下载速度
  • saveData:记录用户代理是否启用了数据节省模式
  • effectiveType:记录网络连接类型。
// hook返回的值
interface NetworkState {
  since?: Date;
  online?: boolean;
  rtt?: number;
  downlink?: number;
  saveData?: boolean;
  effectiveType?: string;
}

// 监听网络变化的事件名enum
enum NetworkEventType {
  ONLINE = 'online',
  OFFLINE = 'offline',
  CHANGE = 'change',
}

第二步:获取网络状态

function getConnection() {
  const nav = navigator as any;
  if (typeof nav !== 'object') return null;
  return nav.connection || nav.mozConnection || nav.webkitConnection;
}

function getConnectionProperty(): NetworkState {
  const c = getConnection();
  if (!c) return {};
  return {
    rtt: c.rtt,
    saveData: c.saveData,
    downlink: c.downlink,
    effectiveType: c.effectiveType,
  };
}

第三步:实时更新网络状态

unction useNetwork(): NetworkState {
  const [state, setState] = useState(() => {
    return {
      since: undefined,
      online: navigator?.onLine,
      ...getConnectionProperty(),
    };
  });

  useEffect(() => {
    const onOnline = () => {
      setState((prevState) => ({
        ...prevState,
        online: true,
        since: new Date(),
      }));
    };

    const onOffline = () => {
      setState((prevState) => ({
        ...prevState,
        online: false,
        since: new Date(),
      }));
    };

    const onConnectionChange = () => {
      setState((prevState) => ({
        ...prevState,
        ...getConnectionProperty(),
      }));
    };

    window.addEventListener(NetworkEventType.ONLINE, onOnline);
    window.addEventListener(NetworkEventType.OFFLINE, onOffline);

    const connection = getConnection();
    connection?.addEventListener(NetworkEventType.CHANGE, onConnectionChange);

    return () => {
      window.removeEventListener(NetworkEventType.ONLINE, onOnline);
      window.removeEventListener(NetworkEventType.OFFLINE, onOffline);
      connection?.removeEventListener(NetworkEventType.CHANGE, onConnectionChange);
    };
  }, []);

  return state;
}

完整代码

import { useEffect, useState } from 'react';

export interface NetworkState {
  since?: Date;
  online?: boolean;
  rtt?: number;
  downlink?: number;
  saveData?: boolean;
  effectiveType?: string;
}

enum NetworkEventType {
  ONLINE = 'online',
  OFFLINE = 'offline',
  CHANGE = 'change',
}

function getConnection() {
  const nav = navigator as any;
  if (typeof nav !== 'object') return null;
  return nav.connection || nav.mozConnection || nav.webkitConnection;
}

function getConnectionProperty(): NetworkState {
  const c = getConnection();
  if (!c) return {};
  return {
    rtt: c.rtt,
    saveData: c.saveData,
    downlink: c.downlink,
    effectiveType: c.effectiveType,
  };
}

function useNetwork(): NetworkState {
  const [state, setState] = useState(() => {
    return {
      since: undefined,
      online: navigator?.onLine,
      ...getConnectionProperty(),
    };
  });

  useEffect(() => {
    const onOnline = () => {
      setState((prevState) => ({
        ...prevState,
        online: true,
        since: new Date(),
      }));
    };

    const onOffline = () => {
      setState((prevState) => ({
        ...prevState,
        online: false,
        since: new Date(),
      }));
    };

    const onConnectionChange = () => {
      setState((prevState) => ({
        ...prevState,
        ...getConnectionProperty(),
      }));
    };

    window.addEventListener(NetworkEventType.ONLINE, onOnline);
    window.addEventListener(NetworkEventType.OFFLINE, onOffline);

    const connection = getConnection();
    connection?.addEventListener(NetworkEventType.CHANGE, onConnectionChange);

    return () => {
      window.removeEventListener(NetworkEventType.ONLINE, onOnline);
      window.removeEventListener(NetworkEventType.OFFLINE, onOffline);
      connection?.removeEventListener(NetworkEventType.CHANGE, onConnectionChange);
    };
  }, []);

  return state;
}

export default useNetwork;
#前端##我的实习求职记录##实习,投递多份简历没人回复怎么办##我的求职思考##如何判断面试是否凉了#
全部评论

相关推荐

11-09 01:22
已编辑
东南大学 Java
高级特工穿山甲:羡慕,我秋招有家企业在茶馆组织线下面试,约我过去“喝茶详谈”😢结果我去了发现原来是人家喝茶我看着
点赞 评论 收藏
分享
评论
点赞
1
分享
牛客网
牛客企业服务