util.ts 5.3 KB

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