-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.tsx
More file actions
134 lines (113 loc) · 3.51 KB
/
Copy pathindex.tsx
File metadata and controls
134 lines (113 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import * as React from 'react'
let mqlMedia = window.matchMedia('(orientation: portrait)')
// 输出当前屏幕模式
const getUiMode = (mql: MediaQueryList | MediaQueryListEvent, widthMode: number) => {
// 竖屏
let isPortrait = mql.matches
// 设备宽
let compareScreenWidth = isPortrait ? Math.min(window.screen.width, window.screen.height) : Math.max(window.screen.width, window.screen.height)
// 网页宽
let compareInnerWitdh = isPortrait ? Math.min(window.innerWidth, window.innerHeight) : Math.max(window.innerWidth, window.innerHeight)
// 当屏幕宽与网页宽一致并且大于宽度断点,才认为是pc
let uiMode = compareScreenWidth <= compareInnerWitdh + 150 && compareScreenWidth > widthMode ? 'pc' : 'mobile'
return uiMode
}
const getIsPcMode = (uiMode: string) => uiMode === 'pc'
export const isPadWeixin = () => {
const userAgent = window.navigator.userAgent
const userAgentLowerCase = userAgent.toLocaleLowerCase()
return userAgentLowerCase.includes('micromessenger') && userAgentLowerCase.includes('ipad')
}
interface OptionsProps {
widthMode?: number,
/**
* iPad 微信使用 Mobile 模式
*/
isPadWechatMobile?: boolean
}
interface UIProps {
isPCMode?: boolean
}
interface UIState {
orientation: string
/**
* 单一模式。要么是pc,要么是Mobile
*/
isSingleMode: boolean
/**
* 屏幕断点,默认为 1000px
*/
widthMode: number,
/**
* 屏幕 UI 模式,值为 pc、mobile
*/
uiMode: string
/**
* 是否为 PC 模式
*/
isPCMode: boolean
}
export function withUiMode(Cmp: React.ComponentType, options: OptionsProps) {
return class WithUIRem extends React.Component<UIProps, UIState> {
constructor(props: UIProps) {
super(props)
// 需要转换的
let { widthMode = 1000, isPadWechatMobile = false } = options
let uiMode = 'mobile'
let isPCMode = false
let isSingleMode = false
if (isPadWechatMobile && isPadWeixin()) {
// 恒定 mobile
isSingleMode = true
} else if (!('onorientationchange' in window) || Math.min(window.screen.width, window.screen.height) >= widthMode) {
// 恒定 pc
isSingleMode = true
uiMode = 'pc'
isPCMode = true
} else if (Math.max(window.screen.width, window.screen.height) < widthMode) {
// 恒定 mobile
isSingleMode = true
} else {
// 横竖屏切换的
uiMode = getUiMode(mqlMedia, widthMode)
isPCMode = getIsPcMode(uiMode)
}
this.state = {
orientation: '',
isSingleMode,
widthMode,
uiMode: uiMode,
isPCMode: isPCMode,
}
}
componentDidMount() {
if (!this.state.isSingleMode) {
mqlMedia.addListener(this.changeUiMode)
}
}
componentWillUnmount() {
if (!this.state.isSingleMode) {
mqlMedia.removeListener(this.changeUiMode)
}
}
changeUiMode = (mqlEvent: MediaQueryListEvent) => {
const { uiMode, widthMode } = this.state
// 屏幕切换后,宽高改变可能不会立即触发
setTimeout(() => {
let newUiMode = getUiMode(mqlEvent, widthMode)
if (newUiMode !== uiMode) {
this.setState({
uiMode: newUiMode,
isPCMode: getIsPcMode(newUiMode)
})
}
}, 300);
}
render() {
return <Cmp {...this.state} {...this.props} />
}
}
}
export default (options: OptionsProps) => {
return (Cmp: React.ComponentType) => withUiMode(Cmp, options)
}