mazey 1.4.39 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -1,13 +1,13 @@
1
- /* Deal */
1
+ /* Mazey */
2
2
 
3
3
  /**
4
4
  * @method calLongestCommonSubstring
5
- * @description 计算两个字符串的最长公共子串
6
- * @param {String} aStr 字符串
7
- * @param {String} bStr 字符串
8
- * @return {Number} 长度
5
+ * @description Computes the longest common substring of two strings.
6
+ * @param {string} aStr String
7
+ * @param {string} bStr String
8
+ * @return {number} Length
9
9
  */
10
- export function calLongestCommonSubstring(aStr: any, bStr: any) {
10
+ export function calLongestCommonSubstring(aStr = '', bStr = ''): number {
11
11
  const aLen = aStr.length;
12
12
  const bLen = bStr.length;
13
13
  // 创建二维数组并且深拷贝
@@ -33,11 +33,11 @@ export function calLongestCommonSubstring(aStr: any, bStr: any) {
33
33
  /**
34
34
  * @method calLongestCommonSubsequence
35
35
  * @description 计算两个字符串的最长公共子序列
36
- * @param {String} aStr 字符串
37
- * @param {String} bStr 字符串
38
- * @return {Number} 长度
36
+ * @param {string} aStr 字符串
37
+ * @param {string} bStr 字符串
38
+ * @return {number} 长度
39
39
  */
40
- export function calLongestCommonSubsequence(aStr: any, bStr: any) {
40
+ export function calLongestCommonSubsequence(aStr = '', bStr = ''): number {
41
41
  const aLen = aStr.length;
42
42
  const bLen = bStr.length;
43
43
  // 创建二维数组并且深拷贝
@@ -70,111 +70,124 @@ export function calLongestCommonSubsequence(aStr: any, bStr: any) {
70
70
  }
71
71
 
72
72
  /**
73
- * @method join
74
- * @description 将一系列值连接成固定字符分隔的字符串 123,456 => 123 - 456。
75
- * @param {String} joinStr 连接值的字符串。
76
- * @param {Rest} ...rest 需要连接的值 。
73
+ * @method getQueryParam
74
+ * @description Get the query param's value of the current Web URL(`location.search`).
75
+ * @param {string} param Query param.
76
+ * @return {string} value
77
77
  * */
78
- export function join(joinStr: any, ...rest: any[]) {
79
- let ret = '';
80
- const len = joinStr.length;
81
- for (const v of rest) {
82
- if (v) {
83
- ret += `${joinStr}${v}`;
84
- }
85
- }
86
- if (ret) {
87
- ret = ret.substring(len);
78
+ export function getQueryParam(param = ''): string {
79
+ const reg = new RegExp('(^|&)' + param + '=([^&]*)(&|$)');
80
+ const r = location.search.substr(1).match(reg);
81
+ if (r !== null) {
82
+ return decodeURIComponent(unescape(r[2]));
88
83
  }
89
- return ret;
84
+ return '';
90
85
  }
91
86
 
92
87
  /**
93
- * @method renderTable
94
- * @description 渲染表格
95
- * @param {DOM Object} tbID
96
- * @param {Array} data
97
- * @param {Array} property
98
- */
99
- export function renderTable(tbID = null, data = [], property = []) {
100
- const TBODY: any = document.querySelector(`#${tbID} tbody`);
101
- function mNullToNA(str: any) {
102
- return str === null ? 'N.A.' : str;
103
- }
104
- let content = '';
105
- TBODY.innerHTML = '';
106
- // 无数据
107
- if (!data.length) {
108
- content = `<tr><td colspan="${property.length}">无数据</td></tr>`;
109
- } else {
110
- for (let [i, max] = [0, data.length]; i < max; ++i) {
111
- const item = data[i];
112
- content += '<tr>';
113
- for (let [i, max] = [0, property.length]; i < max; ++i) {
114
- content += `<td>${mNullToNA(item[property[i]])}</td>`;
115
- }
116
- content += '</tr>';
88
+ * @method getUrlParam
89
+ * @description Get the query param's value of the input URL.
90
+ * @param {string} url URL string.
91
+ * @param {string} param Query param.
92
+ * @return {string} value
93
+ * */
94
+ export function getUrlParam(url = '', param = ''): string {
95
+ const result: any = {};
96
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
97
+ url.replace(/\??(\w+)=([^&]*)&?/g, function (a, k, v): any {
98
+ if (result[k] !== undefined) {
99
+ const t = result[k];
100
+ result[k] = [].concat(t, v);
101
+ } else {
102
+ result[k] = v;
117
103
  }
104
+ });
105
+ // if (param === undefined) {
106
+ // return result;
107
+ // } else {
108
+ // return result[param] || '';
109
+ // }
110
+ return result[param] || '';
111
+ }
112
+
113
+ /**
114
+ * @method updateQueryParam
115
+ * @description Update the query param's value of the input URL.
116
+ * @param {string} url URL string.
117
+ * @param {string} param Query param.
118
+ * @param {string} value Param's value.
119
+ * @return {string} URL.
120
+ * */
121
+ export function updateQueryParam(url = '', param = '', value = ''): string {
122
+ const re = new RegExp('([?&])' + param + '=.*?(&|$)', 'i');
123
+ const separator = url.indexOf('?') !== -1 ? '&' : '?';
124
+ if (url.match(re)) {
125
+ return url.replace(re, '$1' + param + '=' + value + '$2');
126
+ } else {
127
+ return url + separator + param + '=' + value;
118
128
  }
119
- TBODY.innerHTML = content;
120
129
  }
121
130
 
122
131
  /**
123
132
  * @method getHashQueryParam
124
- * @description 获取地址栏 hash 后面的参数。
125
- * @param {String} param 获取参数的名字。
133
+ * @description Get the hash query param's value of the current Web URL(`location.hash`).
134
+ * @param {string} param Query param.
135
+ * @return {string} value
126
136
  */
127
- export function getHashQueryParam(param: string) {
128
- const hashs = window.location.hash.split('?');
137
+ export function getHashQueryParam(param = ''): string {
138
+ const hashs = location.hash.split('?');
129
139
  if (hashs.length === 1) {
130
- return null;
140
+ return '';
131
141
  }
132
142
  const reg = new RegExp(`(^|&)${param}=([^&]*)(&|$)`);
133
143
  const ret = hashs[1].match(reg);
134
- return ret ? ret[2] : null;
144
+ return ret ? ret[2] : '';
145
+ }
146
+
147
+ /**
148
+ * @method getDomain
149
+ * @description Get the domain of URL, and other params.
150
+ * @param {string} url
151
+ * @param {array} rules Object.keys(location), ['href', 'protocol', 'host', 'hostname', 'port', 'pathname', 'search', 'hash'], ['hostname', 'pathname'] = 'km.mazey.net/plugins/servlet/mobile'
152
+ * */
153
+ export function getDomain(url = '', rules = ['hostname']): string {
154
+ const aEl: any = document.createElement('a');
155
+ aEl.href = url;
156
+ return rules.reduce((ret, v) => {
157
+ ret += aEl[v];
158
+ return ret;
159
+ }, '');
135
160
  }
136
161
 
137
162
  /**
138
163
  * @method camelCaseToKebabCase
139
- * @description 驼峰转连接线。
140
- * @param {String} camelCase
164
+ * @description Transfer CamelCase to KebabCase.
165
+ * @param {string} camelCase 'aBC' or 'ABC'
166
+ * @return {string} 'a-b-c'
141
167
  * */
142
- export function camelCaseToKebabCase(camelCase: string) {
168
+ export function camelCaseToKebabCase(camelCase = ''): string {
143
169
  const kebabCase = camelCase.replace(/([A-Z])/g, '-$1').toLowerCase();
144
170
  return kebabCase[0] === '-' ? kebabCase.substr(1) : kebabCase;
145
171
  }
146
172
 
147
173
  /**
148
174
  * @method camelCase2Underscore
149
- * @description 驼峰转下划线。
150
- * @param {String} camelCase
175
+ * @description Transfer CamelCase to Underscore.
176
+ * @param {string} camelCase 'aBC' or 'ABC'
177
+ * @return {string} 'a_b_c'
151
178
  * */
152
- export function camelCase2Underscore(camelCase: string) {
179
+ export function camelCase2Underscore(camelCase = ''): string {
153
180
  const kebabCase = camelCase.replace(/([A-Z])/g, '_$1').toLowerCase();
154
181
  return kebabCase[0] === '_' ? kebabCase.substr(1) : kebabCase;
155
182
  }
156
183
 
157
184
  /**
158
- * @method getDomain
159
- * @description 获取地址中的域名(及其他参数)。
160
- * @param {String} url
161
- * @param {Array} rules ['hostname', 'pathname'] = 'km.mazey.net/plugins/servlet/mobile'
162
- * */
163
- export function getDomain({ url = '', rules = ['hostname'] } = {}) {
164
- const aEl: any = document.createElement('a');
165
- aEl.href = url;
166
- return rules.reduce((ret, v, index) => {
167
- ret += aEl[v];
168
- return ret;
169
- }, '');
170
- }
171
-
172
- /**
173
- * @method trim
174
- * @description 去除左右空格。
175
- * @param {String} str 需要去除两边空格的字符串。
185
+ * @method mTrim
186
+ * @description Remove leading and trailing whitespace or specified characters from string.
187
+ * @param {string} str The string to trim.
188
+ * @return {string} Trimmed string.
176
189
  * */
177
- export function trim(str: string) {
190
+ export function mTrim(str = ''): string {
178
191
  str = str.replace(/^\s+/, ''); // 去除头部空格
179
192
  let end = str.length - 1;
180
193
  const ws = /\s/;
@@ -186,10 +199,11 @@ export function trim(str: string) {
186
199
 
187
200
  /**
188
201
  * @method newLine
189
- * @description html换行。
190
- * @param {String} str
202
+ * @description Make a newline of HTML.
203
+ * @param {string} str The string to make a newline.
204
+ * @return {string} A newline with `<br />`.
191
205
  * */
192
- export function newLine(str: string) {
206
+ export function newLine(str = ''): string {
193
207
  if (!str) {
194
208
  return '';
195
209
  }
@@ -199,21 +213,38 @@ export function newLine(str: string) {
199
213
 
200
214
  /**
201
215
  * @method deepCopyObject
202
- * @description 对象深拷贝。
203
- * @param {Object} obj 被拷贝的对象。
204
- * @return {Object}
216
+ * @description Clone Object deeply.
217
+ * @param {object} obj The value to clone.
218
+ * @return {object} Returns the deep cloned value.
205
219
  * */
206
- export function deepCopyObject(obj: any) {
220
+ export function deepCopyObject(obj: any): any {
207
221
  return JSON.parse(JSON.stringify(obj));
208
222
  }
209
223
 
224
+ /**
225
+ * @method isJsonString
226
+ * @description Check whether it is a valid JSON string.
227
+ * @param {string} str The string to check.
228
+ * @return {boolean} Return the result of checking.
229
+ * */
230
+ export function isJsonString(str = ''): boolean {
231
+ try {
232
+ if (typeof JSON.parse(str) === 'object') {
233
+ return true;
234
+ }
235
+ } catch (e) {
236
+ /* pass */
237
+ }
238
+ return false;
239
+ }
240
+
210
241
  /**
211
242
  * @method generateRndNum
212
- * @description 生成随机数 mGenerateRndNum(7) => 7658495。
213
- * @param {Number} n 随机数的长度
214
- * @return {String}
243
+ * @description Produce a random string of number, `generateRndNum(7)` => '7658495'.
244
+ * @param {number} n Length
245
+ * @return {string} Return the random string.
215
246
  * */
216
- export function generateRndNum(n: number) {
247
+ export function generateRndNum(n = 5): string {
217
248
  let ret = '';
218
249
  while (n--) {
219
250
  ret += Math.floor(Math.random() * 10);
@@ -224,72 +255,42 @@ export function generateRndNum(n: number) {
224
255
  /**
225
256
  * @method generateUniqueNum
226
257
  * @description 根据时间生成唯一标志的数字 mGenerateUniqueNum() => 1538324722364123。
227
- * @param {Number} n 随机数的长度
258
+ * @param {number} n 随机数的长度
228
259
  * */
229
- export function generateUniqueNum(n: number) {
260
+ export function generateUniqueNum(n = 3): string {
230
261
  const [now, rnd] = [mNow(), generateRndNum(n || 3)];
231
262
  return now + rnd;
232
263
  }
233
264
 
234
- /**
235
- * @method resetForm
236
- * @description 重置表单输入值为原始(空)状态。
237
- * @param {String} rest name1,name2,name3...NAME属性,可以多个。
238
- * */
239
- export function resetForm(...rest: any[]) {
240
- for (let i = 0; i < rest.length; i++) {
241
- const tagMz: any = document.getElementsByName(rest[i])[0]; // tag object
242
- const tagNameMz = tagMz.tagName.toLowerCase(); // tag name
243
- if (tagNameMz === 'input') {
244
- tagMz.value = '';
245
- } else if (tagNameMz === 'select') {
246
- tagMz.options[0].selected = true;
247
- }
248
- }
249
- }
250
-
251
265
  /**
252
266
  * @method floatToPercent
253
267
  * @description 浮点数转为百分比 0.2 => 20%。
254
- * @param {Number} num 浮点数
255
- * @param {Number} fixSize 保留几位浮点数
268
+ * @param {number} num 浮点数
269
+ * @param {number} fixSize 保留几位浮点数
256
270
  * */
257
- export function floatToPercent(num: any, fixSize = 0): string {
271
+ export function floatToPercent(num = 0, fixSize = 0): string {
272
+ let ret = '';
258
273
  if (fixSize) {
259
- num = (num * 100).toFixed(fixSize);
274
+ ret = (num * 100).toFixed(fixSize);
260
275
  } else {
261
- num = Math.floor(num * 100);
276
+ ret = String(Math.floor(num * 100));
262
277
  }
263
- return `${num}%`;
278
+ return `${ret}%`;
264
279
  }
265
280
 
266
281
  /**
267
282
  * @method floatFixed
268
283
  * @description 浮点数保留指定位。
269
284
  * */
270
- export function floatFixed(num: any, size: any) {
285
+ export function floatFixed(num: string, size = 0): string {
271
286
  return parseFloat(num).toFixed(size);
272
287
  }
273
288
 
274
- /**
275
- * @method compatibleExist
276
- * @description 不存在返回 ——。
277
- * */
278
- export function compatibleExist(instance: string, replaceStr: string) {
279
- let ret = '';
280
- try {
281
- ret = instance || replaceStr || '——';
282
- } catch (e) {
283
- ret = '——';
284
- }
285
- return ret;
286
- }
287
-
288
289
  /**
289
290
  * @method cancelBubble
290
291
  * @description 阻止冒泡。
291
292
  * */
292
- export function cancelBubble(e: any) {
293
+ export function cancelBubble(e: any): void {
293
294
  const ev = e || window.event;
294
295
  if (ev.stopPropagation) {
295
296
  // W3C
@@ -303,7 +304,7 @@ export function cancelBubble(e: any) {
303
304
  /**
304
305
  * @method hasClass
305
306
  * */
306
- export function hasClass(obj: any, cls: string) {
307
+ export function hasClass(obj: any, cls: string): boolean {
307
308
  const oriCls = obj.className; // 获取对象的class值
308
309
  const oriClsArr = oriCls.split(/\s+/); // 分隔空格转换成数组
309
310
  for (let i = 0; i < oriClsArr.length; i++) {
@@ -317,7 +318,7 @@ export function hasClass(obj: any, cls: string) {
317
318
  /**
318
319
  * @method addClass
319
320
  * */
320
- export function addClass(obj: any, cls: string) {
321
+ export function addClass(obj: any, cls: string): void {
321
322
  const oriCls = obj.className;
322
323
  let space = '';
323
324
  let newCls = ''; // 获取对象的class值
@@ -331,7 +332,7 @@ export function addClass(obj: any, cls: string) {
331
332
  /**
332
333
  * @method removeClass
333
334
  * */
334
- export function removeClass(obj: any, cls: string) {
335
+ export function removeClass(obj: any, cls: string): void {
335
336
  const oriCls = obj.className;
336
337
  let newCls; // 获取对象的class值
337
338
  newCls = ' ' + oriCls + ' '; // 前后加空格
@@ -345,7 +346,7 @@ export function removeClass(obj: any, cls: string) {
345
346
  * @method throttle
346
347
  * @description 节流。
347
348
  * */
348
- export function throttle(func: any, wait: number, options: any) {
349
+ export function throttle(func: any, wait: number, options: any): any {
349
350
  // timeout: setTimeout Handle
350
351
  // previous: 上次时间戳
351
352
  let context: any = null;
@@ -392,7 +393,7 @@ export function throttle(func: any, wait: number, options: any) {
392
393
  * @method debounce
393
394
  * @description 去抖。
394
395
  * */
395
- export function debounce(func: any, wait: number, immediate: any) {
396
+ export function debounce(func: any, wait: number, immediate: any): any {
396
397
  let context: any = null;
397
398
  let timeout: any = null;
398
399
  let timestamp: any = null;
@@ -431,12 +432,12 @@ export function debounce(func: any, wait: number, immediate: any) {
431
432
  /**
432
433
  * @method friendlyInterval
433
434
  * @description 获取间隔时间。
434
- * @param {Number/Date} start 开始时间戳 1585325367122
435
- * @param {Number/Date} end 结束时间戳 1585325367122
436
- * @type {String} type 返回类型 d: 2(天) text: 2 天 4 时...
437
- * @return {String/Number} 取决于 type
435
+ * @param {number/Date} start 开始时间戳 1585325367122
436
+ * @param {number/Date} end 结束时间戳 1585325367122
437
+ * @type {string} type 返回类型 d: 2(天) text: 2 天 4 时...
438
+ * @return {String/number} 取决于 type
438
439
  * */
439
- export function friendlyInterval({ start = 0, end = 0, type = 'd' } = {}) {
440
+ export function friendlyInterval({ start = 0, end = 0, type = 'd' } = {}): number | string {
440
441
  if (!isNumber(start)) start = new Date(start).getTime();
441
442
  if (!isNumber(end)) end = new Date(end).getTime();
442
443
  const t = end - start;
@@ -468,10 +469,10 @@ export function friendlyInterval({ start = 0, end = 0, type = 'd' } = {}) {
468
469
  /**
469
470
  * @method isNumber
470
471
  * @description 判断是否有效数字
471
- * @param {Any} num 被判断的值
472
- * @param {Boolean} isNaNAsNumber 是否 NaN 算数字(默认不算)
473
- * @param {Boolean} isUnFiniteAsNumber 是否 无限 算数字(默认不算)
474
- * @return {Boolean} true 是数字
472
+ * @param {*} num 被判断的值
473
+ * @param {boolean} isNaNAsNumber 是否 NaN 算数字(默认不算)
474
+ * @param {boolean} isUnFiniteAsNumber 是否 无限 算数字(默认不算)
475
+ * @return {boolean} true 是数字
475
476
  */
476
477
  export function isNumber(num: any, { isNaNAsNumber = false, isUnFiniteAsNumber = false } = {}): boolean {
477
478
  let ret = true;
@@ -492,85 +493,12 @@ export function isNumber(num: any, { isNaNAsNumber = false, isUnFiniteAsNumber =
492
493
  return ret;
493
494
  }
494
495
 
495
- /**
496
- * @method updateQueryStringParameter
497
- * @description 替换或添加地址栏参数。
498
- * */
499
- export function updateQueryStringParameter(uri: string, key: string, value: string) {
500
- const re = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');
501
- const separator = uri.indexOf('?') !== -1 ? '&' : '?';
502
- if (uri.match(re)) {
503
- return uri.replace(re, '$1' + key + '=' + value + '$2');
504
- } else {
505
- return uri + separator + key + '=' + value;
506
- }
507
- }
508
-
509
- /**
510
- * @method isJsonString
511
- * @description 判断是否合法 JSON 字符串。
512
- * */
513
- export function isJsonString(str: string) {
514
- try {
515
- if (typeof JSON.parse(str) === 'object') {
516
- return true;
517
- }
518
- } catch (e) {
519
- /* pass */
520
- }
521
- return false;
522
- }
523
-
524
- /**
525
- * @method getUrlParam
526
- * @description 链接参数
527
- * @param {String} sUrl 链接
528
- * @param {String} sKey 参数
529
- * */
530
- export function getUrlParam(sUrl: string, sKey: string) {
531
- const result: any = {};
532
- sUrl.replace(/\??(\w+)=([^&]*)&?/g, function (a, k, v): any {
533
- if (result[k] !== undefined) {
534
- const t = result[k];
535
- result[k] = [].concat(t, v);
536
- } else {
537
- result[k] = v;
538
- }
539
- });
540
- if (sKey === undefined) {
541
- return result;
542
- } else {
543
- return result[sKey] || '';
544
- }
545
- }
546
-
547
- /**
548
- * @method getSearchQueryParam
549
- * @description 地址栏参数。
550
- * */
551
- export function getSearchQueryParam(name: string) {
552
- const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
553
- const r = window.location.search.substr(1).match(reg);
554
- if (r != null) {
555
- return decodeURIComponent(unescape(r[2]));
556
- }
557
- return null;
558
- }
559
-
560
- /**
561
- * @method getQueryParam
562
- * @description 地址栏参数,getSearchQueryParam 的别名。
563
- * */
564
- export function getQueryParam(name: string) {
565
- return getSearchQueryParam(name);
566
- }
567
-
568
496
  /**
569
497
  * @method doFn
570
498
  * @description 执行有效函数
571
- * @param {Function} fn 等待被执行的未知是否有效的函数
499
+ * @param {function} fn 等待被执行的未知是否有效的函数
572
500
  * */
573
- export function doFn(fn: any, ...params: any[]) {
501
+ export function doFn(fn: any, ...params: any[]): any {
574
502
  let ret = null;
575
503
  if (fn && typeof fn === 'function') {
576
504
  ret = fn(...params);
@@ -581,10 +509,10 @@ export function doFn(fn: any, ...params: any[]) {
581
509
  /**
582
510
  * @method setSessionStorage
583
511
  * @description 存储数据到 sessionStorage
584
- * @param {String} key 键
585
- * @param {String} value 值
512
+ * @param {string} key 键
513
+ * @param {string} value 值
586
514
  * */
587
- export function setSessionStorage(key: string, value: any = null) {
515
+ export function setSessionStorage(key: string, value: any = null): void {
588
516
  if (key) {
589
517
  sessionStorage.setItem(key, JSON.stringify(value));
590
518
  }
@@ -593,10 +521,10 @@ export function setSessionStorage(key: string, value: any = null) {
593
521
  /**
594
522
  * @method getSessionStorage
595
523
  * @description 存储数据到 sessionStorage
596
- * @param {String} key 键
597
- * @return {Any} 返回值
524
+ * @param {string} key 键
525
+ * @return {*} 返回值
598
526
  * */
599
- export function getSessionStorage(key: string) {
527
+ export function getSessionStorage(key: string): any {
600
528
  let ret = null;
601
529
  if (key) {
602
530
  const value = sessionStorage.getItem(key);
@@ -610,10 +538,10 @@ export function getSessionStorage(key: string) {
610
538
  /**
611
539
  * @method setLocalStorage
612
540
  * @description 存储数据到 localStorage
613
- * @param {String} key 键
614
- * @param {String} value 值
541
+ * @param {string} key 键
542
+ * @param {string} value 值
615
543
  * */
616
- export function setLocalStorage(key: string, value: any = null) {
544
+ export function setLocalStorage(key: string, value: any = null): void {
617
545
  if (key) {
618
546
  localStorage.setItem(key, JSON.stringify(value));
619
547
  }
@@ -622,10 +550,10 @@ export function setLocalStorage(key: string, value: any = null) {
622
550
  /**
623
551
  * @method getLocalStorage
624
552
  * @description 存储数据到 localStorage
625
- * @param {String} key 键
626
- * @return {Any} 返回值
553
+ * @param {string} key 键
554
+ * @return {*} 返回值
627
555
  * */
628
- export function getLocalStorage(key: string) {
556
+ export function getLocalStorage(key: string): any {
629
557
  let ret = null;
630
558
  if (key) {
631
559
  const value = localStorage.getItem(key);
@@ -639,11 +567,11 @@ export function getLocalStorage(key: string) {
639
567
  /**
640
568
  * @method loadCSS
641
569
  * @description 动态加载css文件
642
- * @param {String} url -- css资源路径
643
- * @param {String} id -- link标签id
644
- * @return {Promise<Boolean>} true -- 加载成功
570
+ * @param {string} url -- css资源路径
571
+ * @param {string} id -- link标签id
572
+ * @return {Promise<boolean>} true -- 加载成功
645
573
  */
646
- export function loadCSS({ url = '', id = '' } = {}) {
574
+ export function loadCSS({ url = '', id = '' } = {}): Promise<any> {
647
575
  let success: any = null;
648
576
  let fail: any = null;
649
577
  const status = new Promise((resolve, reject) => {
@@ -739,7 +667,7 @@ export function loadCSS({ url = '', id = '' } = {}) {
739
667
  // The value of `ex.name` is changed from "NS_ERROR_DOM_SECURITY_ERR"
740
668
  // to "SecurityError" since Firefox 13.0. But Firefox is less than 9.0
741
669
  // in here, So it is ok to just rely on "NS_ERROR_DOM_SECURITY_ERR"
742
- if (ex.name === 'NS_ERROR_DOM_SECURITY_ERR') {
670
+ if ((ex as any).name === 'NS_ERROR_DOM_SECURITY_ERR') {
743
671
  isLoaded = true;
744
672
  }
745
673
  }
@@ -760,14 +688,14 @@ export function loadCSS({ url = '', id = '' } = {}) {
760
688
  /**
761
689
  * @method loadScript
762
690
  * @description 动态加载js文件
763
- * @param {String} url -- js资源路径
764
- * @param {String} id -- DOM ID
765
- * @param {Function} callback -- 加载后回调函数
766
- * @param {Number} timeout -- 超时时长
767
- * @param {Boolean} isDefer -- 是否添加 defer 标签
768
- * @return {Promise<Boolean>} -- true 成功
691
+ * @param {string} url -- js资源路径
692
+ * @param {string} id -- DOM ID
693
+ * @param {function} callback -- 加载后回调函数
694
+ * @param {number} timeout -- 超时时长
695
+ * @param {boolean} isDefer -- 是否添加 defer 标签
696
+ * @return {Promise<boolean>} -- true 成功
769
697
  */
770
- export function loadScript({ url = '', id = '', callback = function () { /* pass */ }, timeout = 5000, isDefer = false } = {}): any {
698
+ export function loadScript({ url = '', id = '', callback = function () { /* pass */ }, timeout = 5000, isDefer = false } = {}): Promise<any> {
771
699
  let success: any = null;
772
700
  let fail: any = null;
773
701
  const script: any = document.createElement('script');
@@ -810,7 +738,7 @@ export function loadScript({ url = '', id = '', callback = function () { /* pass
810
738
  * @method mNow
811
739
  * @description 获取时间戳
812
740
  */
813
- export function mNow() {
741
+ export function mNow(): number {
814
742
  let ret = 0;
815
743
  if (Date.now) {
816
744
  ret = Date.now();
@@ -824,7 +752,7 @@ export function mNow() {
824
752
  * @method setCookie
825
753
  * @description 设置 Cookie
826
754
  */
827
- export function setCookie(name: string, value: string, days: number, domain: string) {
755
+ export function setCookie(name: string, value: string, days: number, domain: string): void {
828
756
  let domainParts, expires;
829
757
  let date: any;
830
758
  if (days) {
@@ -866,7 +794,7 @@ export function setCookie(name: string, value: string, days: number, domain: str
866
794
  * @method getCookie
867
795
  * @description 获取 Cookie
868
796
  */
869
- export function getCookie(name: string) {
797
+ export function getCookie(name: string): string {
870
798
  const nameEQ = name + "=";
871
799
  const ca = document.cookie.split(';');
872
800
  for (let i = 0; i < ca.length; i++) {
@@ -876,16 +804,16 @@ export function getCookie(name: string) {
876
804
  }
877
805
  if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
878
806
  }
879
- return null;
807
+ return '';
880
808
  }
881
809
 
882
810
  /**
883
811
  * @method getPerformance
884
812
  * @description 获取页面加载相关的各项数据
885
- * @param {Boolean} camelCase -- true(默认) 以驼峰形式返回数据 false 以下划线形式返回数据
886
- * @return {Promise<Object>} 加载数据
813
+ * @param {boolean} camelCase -- true(默认) 以驼峰形式返回数据 false 以下划线形式返回数据
814
+ * @return {Promise<object>} 加载数据
887
815
  */
888
- export function getPerformance({ camelCase = true } = {}) {
816
+ export function getPerformance({ camelCase = true } = {}): Promise<any> {
889
817
  let success: any;
890
818
  let fail: any;
891
819
  const status = new Promise((resolve, reject) => {
@@ -926,7 +854,7 @@ export function getPerformance({ camelCase = true } = {}) {
926
854
  console.error('paint');
927
855
  }
928
856
  } catch (e) {
929
- console.error(e.message);
857
+ console.error((e as any).message);
930
858
  }
931
859
  // 获取加载时间
932
860
  if (
@@ -1092,8 +1020,8 @@ export function getPerformance({ camelCase = true } = {}) {
1092
1020
  /**
1093
1021
  * @method inRate
1094
1022
  * @description 百分位概率
1095
- * @param {Number} rate -- 0.1 ~ 1 => 1% ~ 100%
1096
- * @return {Boolean} true 命中
1023
+ * @param {number} rate -- 0.1 ~ 1 => 1% ~ 100%
1024
+ * @return {boolean} true 命中
1097
1025
  */
1098
1026
  export function inRate(rate: number): boolean {
1099
1027
  if(Math.random() < rate) {
@@ -1105,7 +1033,7 @@ export function inRate(rate: number): boolean {
1105
1033
  /**
1106
1034
  * @method isSafePWAEnv
1107
1035
  * @description 判断是否是安全的 PWA 环境
1108
- * @return {Boolean} true 是
1036
+ * @return {boolean} true 是
1109
1037
  */
1110
1038
  export function isSafePWAEnv(): boolean {
1111
1039
  // 判断是否支持 async await
@@ -1132,7 +1060,7 @@ export function isSafePWAEnv(): boolean {
1132
1060
  return false;
1133
1061
  }
1134
1062
  // 浏览器信息
1135
- const BrowserType = getBrowserType();
1063
+ const BrowserType = getBrowserInfo();
1136
1064
  if (
1137
1065
  ('serviceWorker' in navigator) &&
1138
1066
  isSupportAsyncAwait() &&
@@ -1148,11 +1076,11 @@ export function isSafePWAEnv(): boolean {
1148
1076
  }
1149
1077
 
1150
1078
  /**
1151
- * @method getBrowserType
1079
+ * @method getBrowserInfo
1152
1080
  * @description 返回浏览器信息 https://github.com/JowayYoung/juejin-code/blob/master/browser-type.js
1153
- * @return {Object} 浏览器信息
1081
+ * @return {object} 浏览器信息
1154
1082
  */
1155
- export function getBrowserType(): any {
1083
+ export function getBrowserInfo(): any {
1156
1084
  try {
1157
1085
  // 权重:系统 + 系统版本 > 平台 > 内核 + 载体 + 内核版本 + 载体版本 > 外壳 + 外壳版本
1158
1086
  const ua: any = navigator.userAgent.toLowerCase();
@@ -1162,7 +1090,9 @@ export function getBrowserType(): any {
1162
1090
  .replace(/[^0-9|_.]/g, "")
1163
1091
  .replace(/_/g, ".");
1164
1092
  // 系统
1165
- let system = "unknow";
1093
+ let system = '';
1094
+ // Apple device type.
1095
+ let appleType = '';
1166
1096
  if (testUa(/windows|win32|win64|wow32|wow64/g)) {
1167
1097
  system = "windows"; // windows系统
1168
1098
  } else if (testUa(/macintosh|macintel/g)) {
@@ -1173,9 +1103,18 @@ export function getBrowserType(): any {
1173
1103
  system = "android"; // android系统
1174
1104
  } else if (testUa(/ios|iphone|ipad|ipod|iwatch/g)) {
1175
1105
  system = "ios"; // ios系统
1106
+ if (testUa(/iphone/g)) {
1107
+ appleType = 'iphone';
1108
+ } else if (testUa(/ipad/g)) {
1109
+ appleType = 'ipad';
1110
+ } else if (testUa(/iwatch/g)) {
1111
+ appleType = 'iwatch';
1112
+ } else if (testUa(/ipod/g)) {
1113
+ appleType = 'ipod';
1114
+ }
1176
1115
  }
1177
1116
  // 系统版本
1178
- let systemVs = "unknow";
1117
+ let systemVs = '';
1179
1118
  if (system === "windows") {
1180
1119
  if (testUa(/windows nt 5.0|windows 2000/g)) {
1181
1120
  systemVs = "2000";
@@ -1202,15 +1141,15 @@ export function getBrowserType(): any {
1202
1141
  systemVs = testVs(/os [\d._]+/g);
1203
1142
  }
1204
1143
  // 平台
1205
- let platform = "unknow";
1144
+ let platform = '';
1206
1145
  if (system === "windows" || system === "macos" || system === "linux") {
1207
1146
  platform = "desktop"; // 桌面端
1208
1147
  } else if (system === "android" || system === "ios" || testUa(/mobile/g)) {
1209
1148
  platform = "mobile"; // 移动端
1210
1149
  }
1211
1150
  // 内核和载体
1212
- let engine = "unknow";
1213
- let supporter = "unknow";
1151
+ let engine = '';
1152
+ let supporter = '';
1214
1153
  if (testUa(/applewebkit/g)) {
1215
1154
  engine = "webkit"; // webkit内核
1216
1155
  if (testUa(/edge/g)) {
@@ -1233,7 +1172,7 @@ export function getBrowserType(): any {
1233
1172
  supporter = "iexplore"; // iexplore浏览器
1234
1173
  }
1235
1174
  // 内核版本
1236
- let engineVs = "unknow";
1175
+ let engineVs = '';
1237
1176
  if (engine === "webkit") {
1238
1177
  engineVs = testVs(/applewebkit\/[\d._]+/g);
1239
1178
  } else if (engine === "gecko") {
@@ -1244,7 +1183,7 @@ export function getBrowserType(): any {
1244
1183
  engineVs = testVs(/trident\/[\d._]+/g);
1245
1184
  }
1246
1185
  // 载体版本
1247
- let supporterVs = "unknow";
1186
+ let supporterVs = '';
1248
1187
  if (supporter === "chrome") {
1249
1188
  supporterVs = testVs(/chrome\/[\d._]+/g);
1250
1189
  } else if (supporter === "safari") {
@@ -1259,14 +1198,16 @@ export function getBrowserType(): any {
1259
1198
  supporterVs = testVs(/edge\/[\d._]+/g);
1260
1199
  }
1261
1200
  // 外壳和外壳版本
1262
- let shell = "none";
1263
- let shellVs = "unknow";
1201
+ let shell = '';
1202
+ let shellVs = '';
1264
1203
  if (testUa(/micromessenger/g)) {
1265
1204
  shell = "wechat"; // 微信浏览器
1266
1205
  shellVs = testVs(/micromessenger\/[\d._]+/g);
1267
1206
  } else if (testUa(/qqbrowser/g)) {
1268
- shell = "qq"; // QQ浏览器
1207
+ shell = "qq_browser"; // QQ Browser
1269
1208
  shellVs = testVs(/qqbrowser\/[\d._]+/g);
1209
+ } else if (testUa(/\sqq/g)) {
1210
+ shell = "qq_app"; // QQ APP
1270
1211
  } else if (testUa(/ucbrowser/g)) {
1271
1212
  shell = "uc"; // UC浏览器
1272
1213
  shellVs = testVs(/ucbrowser\/[\d._]+/g);
@@ -1282,6 +1223,8 @@ export function getBrowserType(): any {
1282
1223
  } else if (testUa(/maxthon/g)) {
1283
1224
  shell = "maxthon"; // 遨游浏览器
1284
1225
  shellVs = testVs(/maxthon\/[\d._]+/g);
1226
+ } else if (testUa(/biliapp/g)) {
1227
+ shell = "bilibili"; // 哔哩哔哩
1285
1228
  }
1286
1229
  return Object.assign({
1287
1230
  engine, // webkit gecko presto trident
@@ -1290,10 +1233,11 @@ export function getBrowserType(): any {
1290
1233
  supporter, // chrome safari firefox opera iexplore edge
1291
1234
  supporterVs,
1292
1235
  system, // windows macos linux android ios
1293
- systemVs
1294
- }, shell === "none" ? {} : {
1236
+ systemVs,
1237
+ }, {
1295
1238
  shell, // wechat qq uc 360 2345 sougou liebao maxthon
1296
- shellVs
1239
+ shellVs,
1240
+ appleType,
1297
1241
  });
1298
1242
  } catch (err) {
1299
1243
  return {};
@@ -1303,8 +1247,8 @@ export function getBrowserType(): any {
1303
1247
  /**
1304
1248
  * @method clearHtml
1305
1249
  * @description 去除HTML标签
1306
- * @param {String} string 带html标签的字符串
1307
- * @return {String} 字符串
1250
+ * @param {string} string 带html标签的字符串
1251
+ * @return {string} 字符串
1308
1252
  */
1309
1253
  export function clearHtml (string = ''): string {
1310
1254
  return string.replace(/<\/?.+?>/g, '').replace(/[\r\n]/g, '');
@@ -1313,10 +1257,10 @@ export function clearHtml (string = ''): string {
1313
1257
  /**
1314
1258
  * @method cutCHSString
1315
1259
  * @description 截取字符串,中文算2个字节
1316
- * @param {String} str 要截取的字符串
1317
- * @param {Number} len
1318
- * @param {Boolean} hasDot
1319
- * @returns {String} 返回截取后的字符串
1260
+ * @param {string} str 要截取的字符串
1261
+ * @param {number} len
1262
+ * @param {boolean} hasDot
1263
+ * @returns {string} 返回截取后的字符串
1320
1264
  */
1321
1265
  export function cutCHSString(str = '', len = str.length, hasDot = false): string {
1322
1266
  if (str == '' || !str) {
@@ -1351,7 +1295,7 @@ export function cutCHSString(str = '', len = str.length, hasDot = false): string
1351
1295
  /**
1352
1296
  * @method windowLoaded
1353
1297
  * @description 页面加载完成
1354
- * @param {Number} timeout 超时时间 / 单位:秒
1298
+ * @param {number} timeout 超时时间 / 单位:秒
1355
1299
  * @return {Promise<string>} document is loaded? 'complete' 'load' / 'timeout'
1356
1300
  */
1357
1301
  export function windowLoaded({ timeout = 90 } = {}): Promise<string> {
@@ -1374,9 +1318,9 @@ export function windowLoaded({ timeout = 90 } = {}): Promise<string> {
1374
1318
  /**
1375
1319
  * @method addInlineStyle
1376
1320
  * @description 添加内联样式
1377
- * @param {String} inlineStyle 内联样式字符串
1378
- * @param {String} id <style> 标签的 ID
1379
- * @return {Boolean} 添加成功/失败
1321
+ * @param {string} inlineStyle 内联样式字符串
1322
+ * @param {string} id <style> 标签的 ID
1323
+ * @return {boolean} 添加成功/失败
1380
1324
  */
1381
1325
  export function addInlineStyle({ inlineStyle = '', id = '' } = {}): boolean {
1382
1326
  if (!inlineStyle) {
@@ -1409,224 +1353,14 @@ export function addInlineStyle({ inlineStyle = '', id = '' } = {}): boolean {
1409
1353
  return true;
1410
1354
  }
1411
1355
 
1412
- /**
1413
- * @method customScrollBarForTransformEle
1414
- * @description 为进行变换(transform)的元素设置滚动条
1415
- * @param {String} containerClassName 进行变换(transform)的元素↓的容器(Father)的类名
1416
- * @param {String} imgBoxClassName 图片的容器(transform It's YOU!)的类名
1417
- * @param {String} imgBoxDom 图片的容器 Dom 对象
1418
- * @param {String} imgClassName 图片的类名
1419
- * @param {Object} imgDom 图片 Dom 对象
1420
- * @param {String} action 操作类型 hide 隐藏指定 `containerClassName` 滚动条
1421
- * @param {String} customStyle 滚动条的定制样式,会覆盖默认样式
1422
- * @return {Boolean} 设置成功
1423
- */
1424
- export function customScrollBarForTransformEle({ containerClassName = '', imgBoxClassName = '', imgBoxDom = null, imgClassName = '', imgDom = null, action = '', customStyle = '' } = {}): boolean {
1425
- // 变量
1426
- const barIsHideId = 'bar-is-hide';
1427
- const barTopId = 'bar-top';
1428
- const barBottomId = 'bar-bottom';
1429
- if (action === 'hide') {
1430
- addInlineStyle({
1431
- inlineStyle: `
1432
- .${containerClassName}::after {
1433
- display: none;
1434
- }
1435
- `,
1436
- id: barIsHideId,
1437
- });
1438
- return true;
1439
- }
1440
- setTimeout(() => {
1441
- // 样式初始化
1442
- addInlineStyle({
1443
- inlineStyle: `
1444
- .${containerClassName}::after {
1445
- content: ' ';
1446
- position: fixed;
1447
- top: 0;
1448
- right: 2px;
1449
- min-height: 0vh;
1450
- max-height: 100vh;
1451
- width: 6px;
1452
- border-radius: 3px;
1453
- box-shadow: inset 0 0 6px rgba(0,0,0,.3);
1454
- -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
1455
- background-color: rgb(109, 108, 109);
1456
- ${customStyle}
1457
- }
1458
- `,
1459
- id: 'bar-init'
1460
- });
1461
- const imgInstance = imgDom || document.querySelector(`.${imgClassName}`);
1462
- if (!imgInstance) {
1463
- console.warn('Need element\'s Dom instance.');
1464
- return false;
1465
- }
1466
- const imgBoxInstance = imgBoxDom || document.querySelector(`.${imgBoxClassName}`);
1467
- if (!imgBoxInstance) {
1468
- console.warn('Need element box\'s Dom instance.');
1469
- return false;
1470
- }
1471
- const Box2ToRes = getBox2To();
1472
- // console.log('获取图片距离顶部的距离', Box2ToRes);
1473
- const ImgHeightRes = getImgHeight();
1474
- // console.log('获取图片的高度', ImgHeightRes);
1475
- const WindowHeightRes = getWindowHeight();
1476
- // console.log('获取窗口的高度', WindowHeightRes);
1477
- const TopOverflowPercentRes = getTopOverflowPercent();
1478
- // console.log('获取顶部溢出的百分比', TopOverflowPercentRes);
1479
- const BottomOverflowPercentRes = getBottomOverflowPercent();
1480
- // console.log('获取顶部溢出的百分比', BottomOverflowPercentRes);
1481
- const hideBarRes = hideBar();
1482
- // console.log('如果都是 0 ,隐藏滚动条', hideBarRes);
1483
- if (!hideBarRes) {
1484
- setBarTop();
1485
- // const setBarTopRes = setBarTop();
1486
- // console.log('设置顶部状态栏', setBarTopRes);
1487
- setBarBottom();
1488
- // const setBarBottomRes = setBarBottom();
1489
- // console.log('设置底部状态栏', setBarBottomRes);
1490
- }
1491
- // 获取图片距离顶部的距离
1492
- function getBox2To () {
1493
- const translates = window.getComputedStyle(imgBoxInstance as any, null).transform;
1494
- const tanslateY = parseFloat(translates.substring(6).split(',')[5]);
1495
- return tanslateY;
1496
- }
1497
- // 获取图片的高度
1498
- function getImgHeight () {
1499
- return (imgInstance)?.clientHeight;
1500
- }
1501
- // 获取窗口的高度
1502
- function getWindowHeight () {
1503
- return (document.querySelector(`.${containerClassName}`) as any).clientHeight; // window.outerHeight;
1504
- }
1505
- // 获取顶部溢出的百分比
1506
- function getTopOverflowPercent () {
1507
- let box2To = Box2ToRes;
1508
- if (box2To >= 0) {
1509
- box2To = 0;
1510
- }
1511
- box2To = Math.abs(box2To);
1512
- // 图片高度
1513
- const imgHeight = ImgHeightRes;
1514
- const per = floatToPercent(box2To/(imgHeight as any), 2);
1515
- return {
1516
- box2To,
1517
- per,
1518
- };
1519
- }
1520
- // 获取底部溢出的百分比
1521
- function getBottomOverflowPercent () {
1522
- // 窗口高度
1523
- const windowHeight = WindowHeightRes;
1524
- // 图片高度
1525
- const imgHeight = ImgHeightRes;
1526
- // 上面溢出的高度
1527
- const box2To = Box2ToRes;
1528
- // 底部
1529
- const remindImageHeight = windowHeight - box2To;
1530
- let box2ToBottom = (imgHeight as any) - remindImageHeight;
1531
- if (box2ToBottom <= 0) {
1532
- box2ToBottom = 0;
1533
- }
1534
- const per = floatToPercent(box2ToBottom/(imgHeight as any), 2);
1535
- return {
1536
- box2ToBottom,
1537
- per,
1538
- };
1539
- }
1540
- // 如果都是 0 ,隐藏滚动条
1541
- function hideBar () {
1542
- const { box2To } = TopOverflowPercentRes;
1543
- const { box2ToBottom } = BottomOverflowPercentRes;
1544
- if (!box2To && !box2ToBottom) {
1545
- return addInlineStyle({
1546
- inlineStyle: `
1547
- .${containerClassName}::after {
1548
- display: none;
1549
- }
1550
- `,
1551
- id: barIsHideId
1552
- });
1553
- } else {
1554
- addInlineStyle({
1555
- inlineStyle: `
1556
- .${containerClassName}::after {
1557
- display: block;
1558
- }
1559
- `,
1560
- id: barIsHideId
1561
- });
1562
- }
1563
- return false;
1564
- }
1565
- // 设置顶部状态栏
1566
- function setBarTop () {
1567
- const { per } = TopOverflowPercentRes;
1568
- return addInlineStyle({
1569
- inlineStyle: `
1570
- .${containerClassName}::after {
1571
- top: ${per};
1572
- }
1573
- `,
1574
- id: barTopId
1575
- });
1576
- }
1577
- // 设置底部状态栏
1578
- function setBarBottom () {
1579
- const { per } = BottomOverflowPercentRes;
1580
- return addInlineStyle({
1581
- inlineStyle: `
1582
- .${containerClassName}::after {
1583
- bottom: ${per};
1584
- }
1585
- `,
1586
- id: barBottomId
1587
- });
1588
- }
1589
- }, 25);
1590
- return true;
1591
- }
1592
-
1593
-
1594
- /**
1595
- * @method calcContainImageSizeAndPosition
1596
- * @description 计算适配容器宽度的图片的尺寸、距离顶部的距离。如果高度不足以占满容器,使其垂直居中;如果高度比容器长,由上向下铺开。
1597
- * @param {Number} oriImageWidth 图片原始宽度
1598
- * @param {Number} oriImageHeight 图片原始高度
1599
- * @param {Number} viewportWidth 可视窗口宽度
1600
- * @param {Number} viewportHeight 可视窗口高度
1601
- * @return {Object} 结果 {"targetImageWidth":375,"targetImageHeight":375,"top":218.5,"wPer":1.25}
1602
- */
1603
- export function calcContainImageSizeAndPosition({ oriImageWidth = 0, oriImageHeight = 0, viewportWidth = 0, viewportHeight = 0 } = {}): any {
1604
- const targetImageWidth = viewportWidth;
1605
- let [ targetImageHeight, top, wPer ] = [ 0, 0, 0 ];
1606
- // 比例
1607
- wPer = viewportWidth / oriImageWidth; // 1.+ 1.1 1.5
1608
- targetImageHeight = oriImageHeight * wPer;
1609
- if (targetImageHeight < viewportHeight) {
1610
- const doubleGap = viewportHeight - targetImageHeight;
1611
- top = doubleGap / 2;
1612
- }
1613
- return {
1614
- targetImageWidth,
1615
- targetImageHeight,
1616
- top,
1617
- wPer,
1618
- };
1619
- }
1620
-
1621
1356
  /**
1622
1357
  * @method genCustomConsole
1623
1358
  * @description 生成自定义控制台打印
1624
- * @param {String} prefix 前缀
1625
- * @param {Function} allowFn 允许打印的判断函数
1626
- * @return {Object} 新实例
1359
+ * @param {string} prefix 前缀
1360
+ * @param {function} allowFn 允许打印的判断函数
1361
+ * @return {object} 新实例
1627
1362
  */
1628
1363
  export function genCustomConsole({ prefix = '' } = {}): any {
1629
- // ...
1630
1364
  const methods = ['log', 'info', 'warn', 'error'];
1631
1365
  const newConsole = Object.create(null);
1632
1366
  methods.forEach(method => {