feat: 添加设备类型
This commit is contained in:
@@ -2,27 +2,81 @@
|
|||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测当前设备是否为移动设备
|
* 设备类型枚举
|
||||||
*
|
|
||||||
* 判断逻辑:
|
|
||||||
* 1. User Agent 检测(移动设备标识)
|
|
||||||
* 2. 屏幕宽度检测(<= 768px)
|
|
||||||
* 3. 触摸屏检测(支持触摸事件)
|
|
||||||
*
|
|
||||||
* @returns {boolean} true 表示移动设备,false 表示桌面设备
|
|
||||||
*/
|
*/
|
||||||
const detectIsMobile = () => {
|
export const DeviceType = {
|
||||||
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
MOBILE: 'mobile',
|
||||||
const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
TABLET: 'tablet',
|
||||||
const isMobileUA = mobileRegex.test(userAgent);
|
DESKTOP: 'desktop',
|
||||||
const isMobileWidth = window.innerWidth <= 768;
|
|
||||||
const hasTouchScreen = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
||||||
|
|
||||||
return isMobileUA || (isMobileWidth && hasTouchScreen);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测设备类型
|
||||||
|
*
|
||||||
|
* 判断逻辑:
|
||||||
|
* - Mobile: 手机设备(iPhone、Android 手机等,宽度 <= 768px)
|
||||||
|
* - Tablet: 平板设备(iPad、Android 平板等,宽度 769px - 1024px)
|
||||||
|
* - Desktop: 桌面设备(PC、Mac 等,宽度 > 1024px)
|
||||||
|
*
|
||||||
|
* @returns {{ isMobile: boolean, isTablet: boolean, isDesktop: boolean, deviceType: string }}
|
||||||
|
*/
|
||||||
|
const detectDeviceType = () => {
|
||||||
|
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
||||||
|
const screenWidth = window.innerWidth;
|
||||||
|
|
||||||
|
// iPad 检测(包括 iPadOS 13+ 的 Safari,其 UA 不再包含 iPad)
|
||||||
|
const isIPad =
|
||||||
|
/iPad/i.test(userAgent) ||
|
||||||
|
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
||||||
|
|
||||||
|
// Android 平板检测(Android 设备但 UA 不包含 Mobile)
|
||||||
|
const isAndroidTablet = /Android/i.test(userAgent) && !/Mobile/i.test(userAgent);
|
||||||
|
|
||||||
|
// 手机 UA 检测(排除平板)
|
||||||
|
const mobileRegex = /iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
||||||
|
const isAndroidPhone = /Android/i.test(userAgent) && /Mobile/i.test(userAgent);
|
||||||
|
const isMobileUA = mobileRegex.test(userAgent) || isAndroidPhone;
|
||||||
|
|
||||||
|
// 触摸屏检测
|
||||||
|
const hasTouchScreen = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
||||||
|
|
||||||
|
// 综合判断设备类型
|
||||||
|
let isMobile = false;
|
||||||
|
let isTablet = false;
|
||||||
|
let isDesktop = false;
|
||||||
|
|
||||||
|
if (isIPad || isAndroidTablet) {
|
||||||
|
// UA 明确是平板
|
||||||
|
isTablet = true;
|
||||||
|
} else if (isMobileUA) {
|
||||||
|
// UA 明确是手机
|
||||||
|
isMobile = true;
|
||||||
|
} else if (screenWidth <= 768 && hasTouchScreen) {
|
||||||
|
// 小屏幕 + 触摸屏 = 手机
|
||||||
|
isMobile = true;
|
||||||
|
} else if (screenWidth > 768 && screenWidth <= 1024 && hasTouchScreen) {
|
||||||
|
// 中等屏幕 + 触摸屏 = 平板
|
||||||
|
isTablet = true;
|
||||||
|
} else {
|
||||||
|
// 其他情况为桌面设备
|
||||||
|
isDesktop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确定设备类型字符串
|
||||||
|
let deviceType = DeviceType.DESKTOP;
|
||||||
|
if (isMobile) deviceType = DeviceType.MOBILE;
|
||||||
|
else if (isTablet) deviceType = DeviceType.TABLET;
|
||||||
|
|
||||||
|
return { isMobile, isTablet, isDesktop, deviceType };
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialDeviceState = detectDeviceType();
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
isMobile: detectIsMobile(),
|
isMobile: initialDeviceState.isMobile,
|
||||||
|
isTablet: initialDeviceState.isTablet,
|
||||||
|
isDesktop: initialDeviceState.isDesktop,
|
||||||
|
deviceType: initialDeviceState.deviceType,
|
||||||
};
|
};
|
||||||
|
|
||||||
const deviceSlice = createSlice({
|
const deviceSlice = createSlice({
|
||||||
@@ -37,7 +91,11 @@ const deviceSlice = createSlice({
|
|||||||
* - 屏幕方向变化时调用(orientationchange)
|
* - 屏幕方向变化时调用(orientationchange)
|
||||||
*/
|
*/
|
||||||
updateScreenSize: (state) => {
|
updateScreenSize: (state) => {
|
||||||
state.isMobile = detectIsMobile();
|
const { isMobile, isTablet, isDesktop, deviceType } = detectDeviceType();
|
||||||
|
state.isMobile = isMobile;
|
||||||
|
state.isTablet = isTablet;
|
||||||
|
state.isDesktop = isDesktop;
|
||||||
|
state.deviceType = deviceType;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -47,6 +105,9 @@ export const { updateScreenSize } = deviceSlice.actions;
|
|||||||
|
|
||||||
// Selectors
|
// Selectors
|
||||||
export const selectIsMobile = (state) => state.device.isMobile;
|
export const selectIsMobile = (state) => state.device.isMobile;
|
||||||
|
export const selectIsTablet = (state) => state.device.isTablet;
|
||||||
|
export const selectIsDesktop = (state) => state.device.isDesktop;
|
||||||
|
export const selectDeviceType = (state) => state.device.deviceType;
|
||||||
|
|
||||||
// Reducer
|
// Reducer
|
||||||
export default deviceSlice.reducer;
|
export default deviceSlice.reducer;
|
||||||
|
|||||||
Reference in New Issue
Block a user