你会用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;
#前端##我的实习求职记录##实习,投递多份简历没人回复怎么办##我的求职思考##如何判断面试是否凉了#