UNPKG

5.44 kBPlain TextView Raw
1/**
2 * @description 工具函数集合
3 * @author wangfupeng
4 */
5
6class NavUA {
7 public _ua: string
8
9 // 是否为旧版 Edge
10 public isOldEdge: boolean
11
12 // 是否为 Firefox
13 public isFirefox: boolean
14
15 constructor() {
16 this._ua = navigator.userAgent
17
18 const math = this._ua.match(/(Edge?)\/(\d+)/)
19 this.isOldEdge = math && math[1] == 'Edge' && parseInt(math[2]) < 19 ? true : false
20
21 this.isFirefox =
22 /Firefox\/\d+/.test(this._ua) && !/Seamonkey\/\d+/.test(this._ua) ? true : false
23 }
24
25 // 是否为 IE
26 public isIE() {
27 return 'ActiveXObject' in window
28 }
29
30 // 是否为 webkit
31 public isWebkit() {
32 return /webkit/i.test(this._ua)
33 }
34}
35
36// 和 UA 相关的属性
37export const UA = new NavUA()
38
39/**
40 * 获取随机字符
41 * @param prefix 前缀
42 */
43export function getRandom(prefix: string = ''): string {
44 return prefix + Math.random().toString().slice(2)
45}
46
47/**
48 * 替换 html 特殊字符
49 * @param html html 字符串
50 */
51export function replaceHtmlSymbol(html: string) {
52 return html
53 .replace(/</gm, '&lt;')
54 .replace(/>/gm, '&gt;')
55 .replace(/"/gm, '&quot;')
56 .replace(/(\r\n|\r|\n)/g, '<br/>')
57}
58
59export function replaceSpecialSymbol(value: string) {
60 return value
61 .replace(/&lt;/gm, '<')
62 .replace(/&gt;/gm, '>')
63 .replace(/&quot;/gm, '"')
64}
65
66interface Obj {
67 [key: string]: unknown
68 [key: number]: unknown
69}
70interface ArrObj {
71 length: number
72 [key: number]: unknown
73}
74
75/**
76 * 遍历对象或数组,执行回调函数
77 * @param obj 对象或数组
78 * @param fn 回调函数 (key, val) => {...}
79 */
80export function forEach<T extends ArrObj, V = T[Extract<keyof T, number>]>(
81 obj: T,
82 fn: (key: string, value: V) => boolean | void
83): void
84export function forEach<T extends Obj>(
85 obj: T,
86 fn: (key: string, value: T[Extract<keyof T, string | number>]) => boolean | void
87): void
88export function forEach<T extends unknown[]>(
89 obj: T,
90 fn: (key: string, value: T[Extract<keyof T, number>]) => boolean | void
91): void
92export function forEach<T extends unknown[] | Obj | ArrObj>(
93 obj: T,
94 fn: (
95 key: string,
96 value: T[Extract<keyof T, number>] | T[Extract<keyof T, string>]
97 ) => boolean | void
98): void {
99 for (let key in obj) {
100 if (Object.prototype.hasOwnProperty.call(obj, key)) {
101 const result = fn(key, obj[key])
102 if (result === false) {
103 // 提前终止循环
104 break
105 }
106 }
107 }
108}
109
110/**
111 * 遍历类数组
112 * @param fakeArr 类数组
113 * @param fn 回调函数
114 */
115export function arrForEach<T extends { length: number; [key: number]: unknown }>(
116 fakeArr: T,
117 fn: (this: T, item: T[number], index: number) => boolean | unknown
118): void {
119 let i, item, result
120 const length = fakeArr.length || 0
121 for (i = 0; i < length; i++) {
122 item = fakeArr[i]
123 result = fn.call(fakeArr, item, i)
124 if (result === false) {
125 break
126 }
127 }
128}
129
130/**
131 * 节流
132 * @param fn 函数
133 * @param interval 间隔时间,毫秒
134 */
135
136export function throttle<C, T extends unknown[]>(
137 fn: (this: C, ...args: T) => unknown,
138 interval: number = 200
139) {
140 let flag = false
141 return function (this: C, ...args: T): void {
142 if (!flag) {
143 flag = true
144 setTimeout(() => {
145 flag = false
146 fn.call(this, ...args) // this 报语法错误,先用 null
147 }, interval)
148 }
149 }
150}
151
152/**
153 * 防抖
154 * @param fn 函数
155 * @param delay 间隔时间,毫秒
156 */
157export function debounce<C, T extends unknown[]>(
158 fn: (this: C, ...args: T) => void,
159 delay: number = 200
160): (this: C, ...args: T) => void {
161 let lastFn = 0
162 return function (...args: T) {
163 if (lastFn) {
164 window.clearTimeout(lastFn)
165 }
166 lastFn = window.setTimeout(() => {
167 lastFn = 0
168 fn.call(this, ...args) // this 报语法错误,先用 null
169 }, delay)
170 }
171}
172
173/**
174 * isFunction 是否是函数
175 * @param fn 函数
176 */
177export function isFunction(fn: any): fn is Function {
178 return typeof fn === 'function'
179}
180
181/**
182 * 引用与非引用值 深拷贝方法
183 * @param data
184 */
185export function deepClone<T>(data: T): T {
186 if (typeof data !== 'object' || typeof data == 'function' || data === null) {
187 return data
188 }
189
190 let item: any
191 if (Array.isArray(data)) {
192 item = []
193 }
194
195 if (!Array.isArray(data)) {
196 item = {}
197 }
198
199 for (let i in data) {
200 if (Object.prototype.hasOwnProperty.call(data, i)) {
201 item[i] = deepClone(data[i])
202 }
203 }
204
205 return item
206}
207
208/**
209 * 将可遍历的对象转换为数组
210 * @param data 可遍历的对象
211 */
212export function toArray<T>(data: T) {
213 return Array.prototype.slice.call(data)
214}
215
216/**
217 * 唯一id生成
218 * @param length 随机数长度
219 */
220export function getRandomCode() {
221 return Math.random().toString(36).slice(-5)
222}
223
224/**
225 * hex color 转换成 rgb
226 * @param hex string
227 */
228export function hexToRgb(hex: string) {
229 const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
230
231 if (result == null) return null
232
233 const colors = result.map(i => parseInt(i, 16))
234 const r = colors[1]
235 const g = colors[2]
236 const b = colors[3]
237
238 return `rgb(${r}, ${g}, ${b})`
239}