mazey 4.13.2 → 5.0.1

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/README.zh-CN.md CHANGED
@@ -1,269 +1,975 @@
1
- <!-- markdownlint-disable MD041 -->
1
+ [English](https://github.com/chengchuu/mazey/blob/main/README.md) | 简体中文
2
2
 
3
- ⚠️ Note: The document has expired, please check the latest [README.md](https://github.com/chengchuu/mazey/blob/release/v4/README.md).
3
+ # Mazey
4
4
 
5
- ⚠️ 注意: 此文档只适用于 v1.4.39 版本,[查看 v4.x 版本的文档](https://github.com/chengchuu/mazey/blob/release/v4/README.md)
5
+ [![npm version][npm-image]][npm-url]
6
+ [![l][l-image]][l-url]
6
7
 
7
- <!-- omit from toc -->
8
- # Mazey
8
+ [npm-image]: https://img.shields.io/npm/v/mazey
9
+ [npm-url]: https://npmjs.org/package/mazey
10
+ [l-image]: https://img.shields.io/npm/l/mazey
11
+ [l-url]: https://github.com/chengchuu/mazey
9
12
 
10
- 除除的 JavaScript 函数库,所有的方法都在线上项目中使用过。
11
-
12
- <!-- omit from toc -->
13
- ## 目录
14
-
15
- - [安装](#安装)
16
- - [使用](#使用)
17
- - [加载资源](#加载资源)
18
- - [存储数据](#存储数据)
19
- - [操作 DOM](#操作-dom)
20
- - [网站性能](#网站性能)
21
- - [公式计算](#公式计算)
22
- - [浏览器信息](#浏览器信息)
23
- - [安全边际](#安全边际)
24
- - [函数](#函数)
25
- - [调试](#调试)
26
- - [开发](#开发)
27
- - [参考](#参考)
13
+ Mazey 是一个面向日常前端开发的函数工具库。前端生态已有许多优秀的库,但项目通常仍会创建 `utils.js` 或 `common.js`,用于存放通用函数。在多个项目之间重复复制相似函数既烦琐,也难以维护。因此,我创建了 Mazey,并会持续更新,为前端开发提供可靠的通用工具。
28
14
 
29
15
  ## 安装
30
16
 
31
- 使用 [npm](https://www.npmjs.com/package/mazey/v/1.4.39) 安装 `mazey@1.4.39`:
17
+ 通过 [npm](https://www.npmjs.com/package/mazey) 安装 Mazey。
32
18
 
33
19
  ```bash
34
- npm install mazey@1.4.39 --save
20
+ npm install mazey
21
+ ```
22
+
23
+ 通过内容分发网络 (Content Delivery Network,CDN) 使用 Mazey。
24
+
25
+ ```html
26
+ <script src="https://cdn.jsdelivr.net/npm/mazey@latest/lib/mazey.min.js"></script>
35
27
  ```
36
28
 
29
+ 你也可以下载 [jsdelivr/lib/mazey.min.js](https://cdn.jsdelivr.net/npm/mazey@latest/lib/mazey.min.js),并自行托管该文件。
30
+
37
31
  ## 使用
38
32
 
39
- ### 加载资源
33
+ 下面的示例使用一个函数,判断某个值是否适合参与常规计算和比较。
40
34
 
41
- 加载 JavaScript:
35
+ 通过 [npm](https://www.npmjs.com/package/mazey) 导入。
42
36
 
43
37
  ```javascript
44
- import { loadScript } from "mazey";
38
+ import { isNumber } from "mazey";
39
+
40
+ const x = 123;
41
+ const y = "abc";
42
+ const z = Infinity;
43
+ isNumber(x); // 输出: true
44
+ isNumber(y); // 输出: false
45
+ isNumber(z, { isInfinityAsNumber: true }); // 输出: true
46
+ ```
47
+
48
+ 通过 CDN 导入。
49
+
50
+ ```html
51
+ <script src="https://cdn.jsdelivr.net/npm/mazey@latest/lib/mazey.min.js"></script>
52
+ <script>
53
+ const x = 123;
54
+ mazey.isNumber(x); // 输出: true
55
+ </script>
56
+ ```
57
+
58
+ ## API 示例
59
+
60
+ 下面列出一些手动维护的 API (应用程序编程接口) 示例。完整内容请查看
61
+ [完整 API 文档](https://chengchuu.github.io/mazey/api/)。
62
+
63
+ ### 目录
64
+
65
+ <!-- toc - begin -->
66
+ - [目录](#目录)
67
+ - [加载资源](#加载资源)
68
+ - [loadScript](#loadscript)
69
+ - [loadScriptIfUndefined](#loadscriptifundefined)
70
+ - [loadCSS](#loadcss)
71
+ - [loadImage](#loadimage)
72
+ - [windowLoaded](#windowloaded)
73
+ - [通用工具](#通用工具)
74
+ - [isNumber](#isnumber)
75
+ - [isJSONString](#isjsonstring)
76
+ - [isValidData](#isvaliddata)
77
+ - [genRndNumString](#genrndnumstring)
78
+ - [formatDate](#formatdate)
79
+ - [isValidDate](#isvaliddate)
80
+ - [generateCalendarVersion](#generatecalendarversion)
81
+ - [getDateDifference](#getdatedifference)
82
+ - [formatDurationFromMs](#formatdurationfromms)
83
+ - [deepCopy](#deepcopy)
84
+ - [deepFreeze](#deepfreeze)
85
+ - [debounce](#debounce)
86
+ - [throttle](#throttle)
87
+ - [convertCamelToKebab](#convertcameltokebab)
88
+ - [convertCamelToUnder](#convertcameltounder)
89
+ - [URL](#url)
90
+ - [getQueryParam](#getqueryparam)
91
+ - [getUrlParam](#geturlparam)
92
+ - [getHashQueryParam](#gethashqueryparam)
93
+ - [getDomain](#getdomain)
94
+ - [updateQueryParam](#updatequeryparam)
95
+ - [isValidUrl](#isvalidurl)
96
+ - [isValidHttpUrl](#isvalidhttpurl)
97
+ - [存储](#存储)
98
+ - [Cookie 工具](#cookie-工具)
99
+ - [Storage 工具](#storage-工具)
100
+ - [DOM](#dom)
101
+ - [Class 工具](#class-工具)
102
+ - [addStyle](#addstyle)
103
+ - [genStyleString](#genstylestring)
104
+ - [newLine](#newline)
105
+ - [计算与公式](#计算与公式)
106
+ - [inRate](#inrate)
107
+ - [longestComSubstring](#longestcomsubstring)
108
+ - [longestComSubsequence](#longestcomsubsequence)
109
+ - [浏览器信息](#浏览器信息)
110
+ - [getBrowserInfo](#getbrowserinfo)
111
+ - [isSafePWAEnv](#issafepwaenv)
112
+ - [Web 性能](#web-性能)
113
+ - [getPerformance](#getperformance)
114
+ - [调试](#调试)
115
+ - [genCustomConsole](#gencustomconsole)
116
+ - [开发环境](#开发环境)
117
+ - [脚本](#脚本)
118
+ - [返回值](#返回值)
119
+ <!-- toc - end -->
120
+
121
+ ### 加载资源
122
+
123
+ #### loadScript
124
+
125
+ 从服务器加载并执行 JavaScript 文件。
45
126
 
46
- loadScript({
47
- url: "https://example.com/path/example.js",
48
- id: "iamid", // 可选,script 标签 ID,默认无 ID
49
- timeout: 5000, // 可选,超时时间,默认 5000
50
- isDefer: false, // 可选,defer,默认 false
51
- })
127
+ 用法:
128
+
129
+ ```javascript
130
+ loadScript(
131
+ "http://example.com/static/js/plugin-2.1.1.min.js",
132
+ {
133
+ id: "iamid", // 可选,script 的 ID,默认不设置
134
+ timeout: 5000, // 可选,超时时间,默认 `5000`
135
+ }
136
+ )
52
137
  .then(
53
138
  res => {
54
- console.log(`加载 JavaScript 成功: ${res}`);
139
+ console.log(`加载 JavaScript 脚本: ${res}`);
55
140
  }
56
141
  )
57
142
  .catch(
58
143
  err => {
59
- console.error(`加载 JavaScript 失败: ${err}`)
144
+ console.error(`加载 JavaScript 脚本: ${err.message}`);
60
145
  }
61
146
  );
62
147
  ```
63
148
 
64
- 加载 CSS:
149
+ 输出:
150
+
151
+ ```text
152
+ 加载 JavaScript 脚本: loaded
153
+ ```
154
+
155
+ #### loadScriptIfUndefined
156
+
157
+ 当脚本尚未加载时,函数会通过指定 URL (统一资源定位符) 加载脚本。该函数使用 `window["attribute"]` 判断脚本是否已定义。
158
+
159
+ 用法:
65
160
 
66
161
  ```javascript
67
- import { loadCSS } from "mazey";
162
+ loadScriptIfUndefined("xyz", "https://example.com/lib/xyz.min.js")
163
+ .then(() => {
164
+ console.log("xyz 已加载。");
165
+ })
166
+ .catch(err => {
167
+ console.log("xyz 加载失败。", err);
168
+ });
169
+ ```
170
+
171
+ 输出:
172
+
173
+ ```text
174
+ xyz 已加载。
175
+ ```
176
+
177
+ #### loadCSS
178
+
179
+ 从服务器加载 CSS 文件。
68
180
 
69
- loadCSS({
70
- url: "https://example.com/path/example.css",
71
- id: "iamid", // 可选,link 标签 ID,默认无 ID
72
- })
181
+ 用法:
182
+
183
+ ```javascript
184
+ loadCSS(
185
+ "https://example.com/path/example.css",
186
+ {
187
+ id: "iamid", // 可选,link 的 ID,默认不设置
188
+ }
189
+ )
73
190
  .then(
74
191
  res => {
75
- console.log(`加载 CSS 成功: ${res}`);
192
+ console.log(`CSS 加载成功: ${res}`);
76
193
  }
77
194
  )
78
195
  .catch(
79
196
  err => {
80
- console.error(`加载 CSS 失败: ${err}`)
197
+ console.error(`CSS 加载失败: ${err.message}`)
81
198
  }
82
199
  );
83
200
  ```
84
201
 
85
- 判断页面是否加载完成(兼容浏览器 `load` 事件已经触发过的情况):
202
+ 输出:
203
+
204
+ ```text
205
+ CSS 加载成功: loaded
206
+ ```
207
+
208
+ #### loadImage
209
+
210
+ 从指定 URL 加载图片。
211
+
212
+ 目标图片会在后台加载。加载失败时,Promise (承诺对象) 会以错误对象进入 `reject` 状态。加载成功时,Promise 会以图片对象进入 `resolve` 状态。该方法适合预加载图片,也可以利用浏览器缓存实现图片懒加载。
213
+
214
+ 该方法不会把图片添加到文档对象模型 (Document Object Model,DOM)。
215
+
216
+ 用法:
86
217
 
87
218
  ```javascript
88
- import { loadCSS } from "mazey";
219
+ loadImage("https://example.com/example.png")
220
+ .then((img) => {
221
+ console.log(img);
222
+ })
223
+ .catch((err) => {
224
+ console.log(err);
225
+ });
226
+ ```
227
+
228
+ #### windowLoaded
229
+
230
+ 检查页面是否成功加载。即使浏览器已经触发 `load` 事件,该函数仍能正确处理。
231
+
232
+ 用法:
89
233
 
90
- windowLoaded({ timeout: 30 })
234
+ ```javascript
235
+ windowLoaded()
91
236
  .then(res => {
92
- console.log(`加载完成:${res}`); // 加载完成:load
237
+ console.log(`加载成功: ${res}`);
93
238
  })
94
239
  .catch(err => {
95
- console.log(`加载超时或失败:${err}`);
240
+ console.log(`加载超时或失败: ${err.message}`);
96
241
  });
97
242
  ```
98
243
 
99
- ### 存储数据
244
+ 输出:
245
+
246
+ ```text
247
+ 加载成功: load
248
+ ```
249
+
250
+ ### 通用工具
251
+
252
+ #### isNumber
253
+
254
+ 判断某个值是否为有效数字。
100
255
 
101
- Storage(兼容 JSON 格式,自动转换):
256
+ 用法:
102
257
 
103
258
  ```javascript
104
- import { setSessionStorage, getSessionStorage, setLocalStorage, getLocalStorage } from "mazey";
259
+ const ret1 = isNumber(123);
260
+ const ret2 = isNumber("123");
261
+ // 默认情况下,NaN 和 Infinity 不是有效数字
262
+ const ret3 = isNumber(Infinity);
263
+ const ret4 = isNumber(Infinity, { isInfinityAsNumber: true });
264
+ const ret5 = isNumber(NaN);
265
+ const ret6 = isNumber(NaN, { isNaNAsNumber: true, isInfinityAsNumber: true });
266
+ console.log(ret1, ret2, ret3, ret4, ret5, ret6);
267
+ ```
105
268
 
106
- setSessionStorage("test", "123");
107
- getSessionStorage("test"); // 123
108
- setLocalStorage("test", "123");
109
- getLocalStorage("test"); // 123
269
+ 输出:
270
+
271
+ ```text
272
+ true false false true false true
273
+ ```
274
+
275
+ #### isJSONString
276
+
277
+ 判断字符串是否为有效的 JSON 字符串。
278
+
279
+ 用法:
280
+
281
+ ```javascript
282
+ const ret1 = isJSONString(`['a', 'b', 'c']`);
283
+ const ret2 = isJSONString(`["a", "b", "c"]`);
284
+ console.log(ret1);
285
+ console.log(ret2);
286
+ ```
287
+
288
+ 输出:
289
+
290
+ ```text
291
+ false
292
+ true
293
+ ```
294
+
295
+ #### isValidData
296
+
297
+ 判断指定路径中的数据是否有效,并且是否等于预期值。
298
+
299
+ 用法:
300
+
301
+ ```javascript
302
+ const validData = {
303
+ a: {
304
+ b: {
305
+ c: 413
306
+ }
307
+ }
308
+ };
309
+ const isValidDataResA = isValidData(validData, ["a", "b", "c"], 2333);
310
+ const isValidDataResB = isValidData(validData, ["a", "b", "c"], 413);
311
+ const isValidDataResC = isValidData(validData, ["d", "d"], 413);
312
+ console.log("isValidDataResA:", isValidDataResA);
313
+ console.log("isValidDataResB:", isValidDataResB);
314
+ console.log("isValidDataResC:", isValidDataResC);
315
+ ```
316
+
317
+ 输出:
318
+
319
+ ```text
320
+ isValidDataResA: false
321
+ isValidDataResB: true
322
+ isValidDataResC: false
323
+ ```
324
+
325
+ #### genRndNumString
326
+
327
+ 生成指定长度的随机数字字符串。例如,`genRndNumString(7)` 可能返回 `"7658495"`。
328
+
329
+ 用法:
330
+
331
+ ```javascript
332
+ const ret1 = genRndNumString(4);
333
+ const ret2 = genRndNumString(7);
334
+ console.log(ret1);
335
+ console.log(ret2);
336
+ ```
337
+
338
+ 输出:
339
+
340
+ ```text
341
+ 9730
342
+ 2262490
343
+ ```
344
+
345
+ #### formatDate
346
+
347
+ 按照指定格式返回本地日期字符串。`HH` 表示 24 小时制,`hh` 表示 12 小时制,`a` 表示 `AM` 或 `PM`。
348
+
349
+ 用法:
350
+
351
+ ```javascript
352
+ const ret1 = formatDate();
353
+ const ret2 = formatDate("Tue Jan 11 2022 14:12:26 GMT+0800 (China Standard Time)", "yyyy-MM-dd hh:mm:ss a");
354
+ const ret3 = formatDate(1641881235000, "yyyy-MM-dd hh:mm:ss a");
355
+ const ret4 = formatDate(new Date(2014, 1, 11), "MM/dd/yyyy");
356
+ console.log("默认 formatDate 值:", ret1);
357
+ console.log("字符串 formatDate 值:", ret2);
358
+ console.log("数字 formatDate 值:", ret3);
359
+ console.log("Date formatDate 值:", ret4);
360
+ ```
361
+
362
+ 输出:
363
+
364
+ ```text
365
+ 默认 formatDate 值: 2023-01-11
366
+ 字符串 formatDate 值: 2022-01-11 02:12:26 PM
367
+ 数字 formatDate 值: 2022-01-11 02:07:15 PM
368
+ Date formatDate 值: 02/11/2014
110
369
  ```
111
370
 
112
- Cookie:
371
+ #### isValidDate
372
+
373
+ 检查未知值是否表示有效日期。函数接受 `Date` 实例、有限的毫秒时间戳、受支持的本地日期字符串,以及带有 `Z` 或数字时区偏移的 ISO 8601 字符串。
374
+
375
+ 字符串格式包括 `YYYY-MM-DD`、`YYYY-MM-DD HH:mm[:ss]` 和 `YYYY-MM-DDTHH:mm[:ss]`。使用 `T` 分隔的日期时间还可以包含 `Z` 或 `+HH:mm`、`-HH:mm` 时区偏移。带时区的字符串可以包含 1~3 位毫秒数字。
376
+
377
+ 函数会把结构化字符串解析为数字组件,并执行严格校验。因此,`"2020-02-30"` 等无效日历日期不会被转换为其他日期。
378
+
379
+ 用法:
113
380
 
114
381
  ```javascript
115
- import { setCookie, getCookie } from "mazey";
382
+ const ret1 = isValidDate(1577877720000);
383
+ const ret2 = isValidDate("2020-01-01 11:22");
384
+ const ret3 = isValidDate("2020-02-30");
385
+ const ret4 = isValidDate(new Date("invalid"));
386
+ console.log(ret1, ret2, ret3, ret4);
387
+ ```
388
+
389
+ 输出:
116
390
 
117
- setCookie("test", "123", 30, "example.com"); // key value day domain
118
- getCookie("test"); // 123
391
+ ```text
392
+ true true false false
119
393
  ```
120
394
 
121
- ### 操作 DOM
395
+ #### generateCalendarVersion
396
+
397
+ 按照本地时间生成日历版本字符串。其概念格式为 `yyyy.MMdd.HHmmss`。函数会删除每个数字段的前导零。处理后的结果兼容语义化版本 (SemVer)。
122
398
 
123
- 修改 `class`:
399
+ 在系统时钟正常前进时,版本会随日期和时间递增。该函数有意使用本地时间。因此,手动回拨时钟或夏令时回退可能生成更小的版本。
400
+
401
+ 用法:
124
402
 
125
403
  ```javascript
126
- import { hasClass, addClass, removeClass } from "mazey";
404
+ const version = generateCalendarVersion(
405
+ new Date(2026, 6, 11, 7, 40, 35)
406
+ );
407
+ console.log(version);
408
+ ```
409
+
410
+ 输出:
411
+
412
+ ```text
413
+ 2026.711.74035
414
+ ```
415
+
416
+ #### getDateDifference
417
+
418
+ 计算两个日期或时间戳之间的差值。默认返回完整秒数。`type: "d"` 返回完整天数,`type: "text"` 返回由天、小时、分钟和秒组成的英文文本。文本会省略值为 `0` 的单位。总时长为零时,函数返回 `"0 seconds"`。
419
+
420
+ `YYYY-MM-DD HH:mm:ss` 格式的字符串按本地时间解析。其他日期字符串使用运行环境原生的 `Date` 解析器。需要跨环境稳定解析时,请使用时间戳,或使用包含明确时区的 ISO 8601 字符串。结束时间早于开始时间,或任一日期无效时,函数返回空字符串。
421
+
422
+ 用法:
423
+
424
+ ```javascript
425
+ const days = getDateDifference(0, 90061000, { type: "d" });
426
+ const text = getDateDifference(0, 90061000, { type: "text" });
427
+ const compactText = getDateDifference(0, 90060000, { type: "text" });
428
+ const dateStringDays = getDateDifference(
429
+ "2020-03-28 00:09:27",
430
+ "2023-04-18 10:54:00",
431
+ { type: "d" }
432
+ );
433
+ console.log(days);
434
+ console.log(text);
435
+ console.log(compactText);
436
+ console.log(dateStringDays);
437
+ ```
438
+
439
+ 输出:
440
+
441
+ ```text
442
+ 1
443
+ 1 day 1 hour 1 minute 1 second
444
+ 1 day 1 hour 1 minute
445
+ 1116
446
+ ```
447
+
448
+ `getFriendlyInterval` 是 `getDateDifference` 的兼容别名。新代码建议使用 `getDateDifference`。
449
+
450
+ #### formatDurationFromMs
451
+
452
+ 将毫秒时长转换为适用的最大单位,包括秒、分钟、小时和天。结果最多保留 1 位小数。负数和非有限值返回 `"0 seconds"`。
453
+
454
+ 用法:
455
+
456
+ ```javascript
457
+ const ret1 = formatDurationFromMs(500);
458
+ const ret2 = formatDurationFromMs(90000);
459
+ const ret3 = formatDurationFromMs(3600000);
460
+ const ret4 = formatDurationFromMs(129600000);
461
+ console.log(ret1);
462
+ console.log(ret2);
463
+ console.log(ret3);
464
+ console.log(ret4);
465
+ ```
466
+
467
+ 输出:
468
+
469
+ ```text
470
+ 0.5 seconds
471
+ 1.5 minutes
472
+ 1 hour
473
+ 1.5 days
474
+ ```
475
+
476
+ #### deepCopy
477
+
478
+ 深度复制或克隆对象。
479
+
480
+ 用法:
481
+
482
+ ```javascript
483
+ const ret1 = deepCopy(["a", "b", "c"]);
484
+ const ret2 = deepCopy("abc");
485
+ console.log(ret1);
486
+ console.log(ret2);
487
+ ```
488
+
489
+ 输出:
490
+
491
+ ```text
492
+ ["a", "b", "c"]
493
+ abc
494
+ ```
495
+
496
+ #### deepFreeze
497
+
498
+ 递归冻结对象及其可枚举嵌套值。原始值和已经冻结的对象会原样返回。函数支持包含循环引用的对象。
499
+
500
+ 用法:
501
+
502
+ ```javascript
503
+ const config = deepFreeze({
504
+ api: {
505
+ timeout: 5000,
506
+ },
507
+ });
508
+
509
+ console.log(Object.isFrozen(config));
510
+ console.log(Object.isFrozen(config.api));
511
+ ```
512
+
513
+ 输出:
514
+
515
+ ```text
516
+ true
517
+ true
518
+ ```
519
+
520
+ #### debounce
521
+
522
+ 创建防抖函数。
523
+
524
+ 用法:
525
+
526
+ ```javascript
527
+ const foo = debounce(() => {
528
+ console.log("防抖函数会在 1,000 毫秒内仅执行一次,等待期间的其他调用不会生效。");
529
+ }, 1000, true);
530
+ ```
531
+
532
+ #### throttle
533
+
534
+ 创建节流函数。
535
+
536
+ 用法:
537
+
538
+ ```javascript
539
+ const foo = throttle(() => {
540
+ console.log("在每个 1,000 毫秒等待周期内,该函数最多执行一次。");
541
+ }, 1000, { leading: true });
542
+ ```
543
+
544
+ 参考资料: [Lodash](https://lodash.com/docs/4.17.15#throttle)
545
+
546
+ #### convertCamelToKebab
547
+
548
+ 将驼峰命名转换为短横线命名。
549
+
550
+ 用法:
551
+
552
+ ```javascript
553
+ const ret1 = convertCamelToKebab("ABC");
554
+ const ret2 = convertCamelToKebab("aBC");
555
+ console.log(ret1);
556
+ console.log(ret2);
557
+ ```
558
+
559
+ 输出:
560
+
561
+ ```text
562
+ a-b-c
563
+ a-b-c
564
+ ```
565
+
566
+ #### convertCamelToUnder
567
+
568
+ 将驼峰命名转换为下划线命名。
569
+
570
+ 用法:
571
+
572
+ ```javascript
573
+ const ret1 = convertCamelToUnder("ABC");
574
+ const ret2 = convertCamelToUnder("aBC");
575
+ console.log(ret1);
576
+ console.log(ret2);
577
+ ```
578
+
579
+ 输出:
580
+
581
+ ```text
582
+ a_b_c
583
+ a_b_c
584
+ ```
585
+
586
+ ### URL
127
587
 
588
+ #### getQueryParam
589
+
590
+ 从当前 Web URL 的查询字符串 (`location.search`) 中获取参数值。
591
+
592
+ 用法:
593
+
594
+ ```javascript
595
+ // http://example.com/?t1=1&t2=2&t3=3&t4=4#2333
596
+ // ?t1=1&t2=2&t3=3&t4=4
597
+ const p1 = getQueryParam("t3");
598
+ const p2 = getQueryParam("t4");
599
+ console.log(p1, p2);
600
+ ```
601
+
602
+ 输出:
603
+
604
+ ```text
605
+ 3 4
606
+ ```
607
+
608
+ #### getUrlParam
609
+
610
+ 从输入 URL 中获取指定查询参数的值。
611
+
612
+ 用法:
613
+
614
+ ```javascript
615
+ const p1 = getUrlParam("https://example.com/?t1=1&t2=2&t3=3&t4=4", "t3");
616
+ const p2 = getUrlParam("https://example.com/?t1=1&t2=2&t3=3&t4=4", "t4");
617
+ console.log(p1, p2);
618
+ ```
619
+
620
+ 输出:
621
+
622
+ ```text
623
+ 3 4
624
+ ```
625
+
626
+ #### getHashQueryParam
627
+
628
+ 从当前 Web URL 的哈希字符串 (`location.hash`) 中获取参数值。
629
+
630
+ 用法:
631
+
632
+ ```javascript
633
+ // http://example.com/?#2333?t1=1&t2=2&t3=3&t4=4
634
+ // #2333?t1=1&t2=2&t3=3&t4=4
635
+ const p1 = getHashQueryParam("t3");
636
+ const p2 = getHashQueryParam("t4");
637
+ console.log(p1, p2);
638
+ ```
639
+
640
+ 输出:
641
+
642
+ ```text
643
+ 3 4
644
+ ```
645
+
646
+ #### getDomain
647
+
648
+ 获取 URL 的域名,也可以组合返回其他部分。
649
+
650
+ 用法:
651
+
652
+ ```javascript
653
+ const ret1 = getDomain("http://example.com/?t1=1&t2=2&t3=3&t4=4");
654
+ const ret2 = getDomain("http://example.com/test/thanks?t1=1&t2=2&t3=3&t4=4", ["hostname", "pathname"]);
655
+ const ret3 = getDomain("http://example.com:7890/test/thanks", ["hostname"]);
656
+ const ret4 = getDomain("http://example.com:7890/test/thanks", ["host"]); // 包含端口
657
+ const ret5 = getDomain("http://example.com:7890/test/thanks", ["origin"]);
658
+ const ret6 = getDomain("http://example.com:7890/test/thanks?id=1", ["origin", "pathname", "search"]);
659
+ console.log(ret1);
660
+ console.log(ret2);
661
+ console.log(ret3);
662
+ console.log(ret4);
663
+ console.log(ret5);
664
+ console.log(ret6);
665
+ ```
666
+
667
+ 输出:
668
+
669
+ ```text
670
+ example.com
671
+ example.com/test/thanks
672
+ example.com
673
+ example.com:7890
674
+ http://example.com:7890
675
+ http://example.com:7890/test/thanks?id=1
676
+ ```
677
+
678
+ #### updateQueryParam
679
+
680
+ 更新输入 URL 中的查询参数值。
681
+
682
+ 用法:
683
+
684
+ ```javascript
685
+ const ret1 = updateQueryParam("http://example.com/?t1=1&t2=2&t3=3&t4=4", "t3", "three");
686
+ const ret2 = updateQueryParam("http://example.com/?t1=1&t2=2&t3=3&t4=4", "t4", "four");
687
+ console.log(ret1);
688
+ console.log(ret2);
689
+ ```
690
+
691
+ 输出:
692
+
693
+ ```text
694
+ http://example.com/?t1=1&t2=2&t3=three&t4=4
695
+ http://example.com/?t1=1&t2=2&t3=3&t4=four
696
+ ```
697
+
698
+ #### isValidUrl
699
+
700
+ 检查给定字符串是否为有效 URL,包括使用其他协议的 URL。
701
+
702
+ 用法:
703
+
704
+ ```javascript
705
+ const ret1 = isValidUrl("https://www.example.com");
706
+ const ret2 = isValidUrl("http://example.com/path/exx/ss");
707
+ const ret3 = isValidUrl("https://www.example.com/?q=hello&age=24#world");
708
+ const ret4 = isValidUrl("http://www.example.com/#world?id=9");
709
+ const ret5 = isValidUrl("ftp://example.com");
710
+ console.log(ret1, ret2, ret3, ret4, ret5);
711
+ ```
712
+
713
+ 输出:
714
+
715
+ ```text
716
+ true true true true true
717
+ ```
718
+
719
+ 如果只需检查 HTTP 或 HTTPS URL,建议使用 `isValidHttpUrl`。`isValidUrl` 会匹配所有协议 URL,包括 FTP 和其他非 HTTP 协议。
720
+
721
+ #### isValidHttpUrl
722
+
723
+ 检查给定字符串是否为有效的 HTTP 或 HTTPS URL。
724
+
725
+ 用法:
726
+
727
+ ```javascript
728
+ const ret1 = isValidHttpUrl("https://www.example.com");
729
+ const ret2 = isValidHttpUrl("http://example.com/path/exx/ss");
730
+ const ret3 = isValidHttpUrl("https://www.example.com/?q=hello&age=24#world");
731
+ const ret4 = isValidHttpUrl("http://www.example.com/#world?id=9");
732
+ const ret5 = isValidHttpUrl("ftp://example.com");
733
+ console.log(ret1, ret2, ret3, ret4, ret5);
734
+ ```
735
+
736
+ 输出:
737
+
738
+ ```text
739
+ true true true true false
740
+ ```
741
+
742
+ ### 存储
743
+
744
+ #### Cookie 工具
745
+
746
+ 操作 Cookie。
747
+
748
+ 用法:
749
+
750
+ ```javascript
751
+ setCookie("test", "123", 30, "example.com"); // 键、值、有效天数、域名
752
+ const ret = getCookie("test");
753
+ console.log(ret);
754
+ ```
755
+
756
+ 输出:
757
+
758
+ ```text
759
+ 123
760
+ ```
761
+
762
+ #### Storage 工具
763
+
764
+ 操作 Web Storage。函数适用于 JSON 数据,并会自动转换格式。
765
+
766
+ 用法:
767
+
768
+ ```javascript
769
+ setSessionStorage("test", "123");
770
+ const ret1 = getSessionStorage("test");
771
+ setLocalStorage("test", "123");
772
+ const ret2 = getLocalStorage("test");
773
+ console.log(ret1, ret2);
774
+
775
+ // 也可以按项目封装键名
776
+ const projectName = "mazey";
777
+ function mSetLocalStorage (key, value) {
778
+ return setLocalStorage(`${projectName}_${key}`, value);
779
+ }
780
+
781
+ function mGetLocalStorage (key) {
782
+ return getLocalStorage(`${projectName}_${key}`);
783
+ }
784
+ ```
785
+
786
+ 输出:
787
+
788
+ ```text
789
+ 123 123
790
+ ```
791
+
792
+ ### DOM
793
+
794
+ #### Class 工具
795
+
796
+ 操作元素的 `class`。
797
+
798
+ 用法:
799
+
800
+ ```javascript
128
801
  const dom = document.querySelector("#box");
129
802
 
130
803
  // 判断 class
131
804
  hasClass(dom, "test");
132
- // 增加 class
805
+ // 添加 class
133
806
  addClass(dom, "test");
134
807
  // 删除 class
135
808
  removeClass(dom, "test");
136
809
  ```
137
810
 
138
- 添加内联样式:
811
+ #### addStyle
812
+
813
+ 在 `<head>` 中添加 `<style>` 元素。
814
+
815
+ 用法:
816
+
817
+ 示例 1: 添加带有 `id` 的 `<style>`。重复调用会更新内容,不会添加新元素。
139
818
 
140
819
  ```javascript
141
- import { addInlineStyle } from "mazey";
820
+ import { addStyle } from "mazey";
142
821
 
143
- // 添加有 id 的内联样式,重复添加会更新内联样式而不是新增
144
- addInlineStyle({
145
- inlineStyle: `
146
- body {
147
- background-color: #333;
148
- }
149
- `,
150
- id: "test",
151
- });
152
- // <style id="test">
153
- // body {
154
- // background-color: #333;
155
- // }
156
- // </style>
157
-
158
- // 添加无 id 的内联样式,重复添加会新增内联样式
159
- addInlineStyle({
160
- inlineStyle: `
161
- body {
162
- background-color: #444;
163
- }
164
- `,
165
- });
166
- // <style>
167
- // body {
168
- // background-color: #444;
169
- // }
170
- // </style>
822
+ addStyle(
823
+ "body { background-color: #333; }",
824
+ { id: "test" }
825
+ );
826
+ ```
827
+
828
+ 输出:
829
+
830
+ ```html
831
+ <style id="test">body { background-color: #333; }</style>
171
832
  ```
172
833
 
173
- 添加自定义滚动条(适用于用 `transform` 移动的元素):
834
+ 示例 2: 添加不带 `id` 的 `<style>`。重复调用会添加新元素。
174
835
 
175
836
  ```javascript
176
- import { customScrollBarForTransformEle } from "mazey";
837
+ import { addStyle } from "mazey";
177
838
 
178
- // 使用类名
179
- customScrollBarForTransformEle({
180
- containerClassName: "i-am-container",
181
- imgBoxClassName: "i-am-img-father-i-can-transform",
182
- imgClassName: "i-am-img",
183
- });
839
+ addStyle("body { background-color: #444; }");
840
+ ```
184
841
 
185
- // 使用 Dom 对象
186
- customScrollBarForTransformEle({
187
- containerClassName: "i-am-container",
188
- imgBoxDom: document.querySelector(".i-am-img-father-i-can-transform"),
189
- imgDom: document.querySelector(".i-am-img-father-i-can-transform"),
190
- });
842
+ 输出:
191
843
 
192
- // 按需直接隐藏滚动条
193
- customScrollBarForTransformEle({
194
- containerClassName: "i-am-container",
195
- action: "hide",
196
- });
844
+ ```html
845
+ <style>body { background-color: #444; }</style>
197
846
  ```
198
847
 
199
- 计算适配容器宽度的图片的尺寸、距离顶部的距离:
848
+ 示例 3: 组合使用 `genStyleString` 和 `addStyle`,一次添加多条样式。
200
849
 
201
850
  ```javascript
202
- import { calcContainImageSizeAndPosition } from "mazey";
851
+ import { genStyleString, addStyle } from "mazey";
852
+
853
+ const xStyle = genStyleString(
854
+ ".footer>.x-wish>a:first-child" +
855
+ ",div.wish-flex>a[href^='https://github.com/chengchuu']" +
856
+ ",.m-hide",
857
+ [ "display: none" ]
858
+ );
859
+ const yStyle = genStyleString(
860
+ ".footer>.y-wish:before",
861
+ [
862
+ `content: 'Copyright (c) chengchuu'`,
863
+ "color: inherit",
864
+ "padding-inline-start: var(--y-wish-1_5)",
865
+ "padding-inline-end: var(--y-wish-1_5)",
866
+ "padding-top: var(--y-wish-1)",
867
+ "padding-bottom: var(--y-wish-1)",
868
+ ]
869
+ );
870
+ addStyle(xStyle + yStyle, { id: "z-style" });
871
+ ```
203
872
 
204
- // 如果高度不足以占满容器,使其垂直居中;如果高度比容器长,由上向下铺开
205
- calcContainImageSizeAndPosition({ oriImageWidth: 300, oriImageHeight: 300, viewportWidth: 375, viewportHeight: 812 });
206
- // {"targetImageWidth":375,"targetImageHeight":375,"top":218.5,"wPer":1.25}
873
+ 输出:
874
+
875
+ ```html
876
+ <style id="z-style">.footer>.x-wish>a:first-child,div.wish-flex>a[href^='https://github.com/chengchuu'],.m-hide{display: none;}.footer>.y-wish:before{content: 'Copyright (c) chengchuu';color: inherit;padding-inline-start: var(--y-wish-1_5);padding-inline-end: var(--y-wish-1_5);padding-top: var(--y-wish-1);padding-bottom: var(--y-wish-1);}</style>
207
877
  ```
208
878
 
209
- ### 网站性能
879
+ #### genStyleString
210
880
 
211
- 获取加载时间:
881
+ 根据参数生成样式字符串。第一个参数是查询选择器,第二个参数是样式数组。
212
882
 
213
- ```javascript
214
- import { getPerformance } from "mazey";
883
+ 用法:
215
884
 
216
- // camelCase:true(默认) 以驼峰形式返回数据 / false 以下划线形式返回数据
217
- getPerformance({ camelCase: true })
218
- .then(res => {
219
- console.log(JSON.stringify(res));
220
- // {"deviceType":"pc","network":"3g","unloadTime":0,"redirectTime":0,"dnsTime":0,"tcpTime":0,"responseTime":65,"downloadTime":1,"domreadyTime":369,"onloadTime":441,"whiteTime":94,"renderTime":441,"decodedBodySize":210,"encodedBodySize":210}
221
- })
222
- .catch(console.error);
885
+ ```javascript
886
+ const ret1 = genStyleString(".a", [ "color:red" ]);
887
+ const ret2 = genStyleString("#b", [ "color:red", "font-size:12px" ]);
888
+ console.log(ret1);
889
+ console.log(ret2);
223
890
  ```
224
891
 
225
- | 指标 | 字段 | 计算⽅法 |
226
- | --- | --- | --- |
227
- | * DNS 查询时间 | dns_time | domainLookupEnd - domainLookupStart |
228
- | * 服务器连接时间 | tcp_time | connectEnd - connectStart |
229
- | * 服务器响应时间 | response_time | responseStart - requestStart |
230
- | * ⽩屏时间 | white_time | responseStart - navigationStart |
231
- | * DomReady 总时间 | domready_time | domContentLoadedEventStart - navigationStart |
232
- | * 页面加载时间 | onload_time | loadEventStart - navigationStart |
233
- | * EventEnd 总时间 | render_time | loadEventEnd -navigationStart |
234
- | 上个⽂档卸载时间 | unload_time | unloadEventEnd - unloadEventStart |
235
- | 重定向时间 | redirect_time | redirectEnd - redirectStart |
236
- | 客户端⽩屏时间 | custom_white_time | renderTiming - navigationStart |
237
- | SSL连接时间 | ssl_time | connectEnd - secureConnectionStart |
238
- | ⽹⻚下载时间 | download_time | responseEnd - responseStart |
239
- | FCP | first_contentful_paint_time | firstPaintTime |
892
+ 输出:
240
893
 
241
- ### 公式计算
894
+ ```text
895
+ .a{color:red;}
896
+ #b{color:red;font-size:12px;}
897
+ ```
242
898
 
243
- 计算两个字符串的最长公共子串:
899
+ 下面的示例组合使用 `genStyleString` 和 `addStyle`,一次添加多条样式。
244
900
 
245
901
  ```javascript
246
- import { calLongestCommonSubstring } from "mazey";
902
+ import { genStyleString, addStyle } from "mazey";
903
+
904
+ const xStyle = genStyleString(
905
+ ".footer>.x-wish>a:first-child" +
906
+ ",div.wish-flex>a[href^='https://github.com/chengchuu']" +
907
+ ",.m-hide",
908
+ [ "display: none" ]
909
+ );
910
+ const yStyle = genStyleString(
911
+ ".footer>.y-wish:before",
912
+ [
913
+ `content: 'Copyright (c) chengchuu'`,
914
+ "color: inherit",
915
+ "padding-inline-start: var(--y-wish-1_5)",
916
+ "padding-inline-end: var(--y-wish-1_5)",
917
+ "padding-top: var(--y-wish-1)",
918
+ "padding-bottom: var(--y-wish-1)",
919
+ ]
920
+ );
921
+ addStyle(xStyle + yStyle, { id: "z-style" });
922
+ ```
247
923
 
248
- calLongestCommonSubstring("fish", "finish"); // 3
924
+ 输出:
925
+
926
+ ```html
927
+ <style id="z-style">.footer>.x-wish>a:first-child,div.wish-flex>a[href^='https://github.com/chengchuu'],.m-hide{display: none;}.footer>.y-wish:before{content: 'Copyright (c) chengchuu';color: inherit;padding-inline-start: var(--y-wish-1_5);padding-inline-end: var(--y-wish-1_5);padding-top: var(--y-wish-1);padding-bottom: var(--y-wish-1);}</style>
249
928
  ```
250
929
 
251
- 计算两个字符串的最长公共子序列:
930
+ #### newLine
931
+
932
+ 把文本中的换行符转换为 HTML 换行元素。
933
+
934
+ 用法:
252
935
 
253
936
  ```javascript
254
- import { calLongestCommonSubsequence } from "mazey";
937
+ const ret1 = newLine("a\nb\nc");
938
+ const ret2 = newLine("a\n\nbc");
939
+ console.log(ret1);
940
+ console.log(ret2);
941
+ ```
942
+
943
+ 输出:
255
944
 
256
- calLongestCommonSubsequence("fish", "finish"); // 4
945
+ ```text
946
+ a<br />b<br />c
947
+ a<br /><br />bc
257
948
  ```
258
949
 
259
- 命中概率(1% ~ 100%):
950
+ ### 计算与公式
951
+
952
+ #### inRate
953
+
954
+ 按照指定概率返回命中结果。有效概率范围为 1%~100%。
955
+
956
+ 用法:
260
957
 
261
958
  ```javascript
262
- import { inRate } from "mazey";
959
+ const ret = inRate(0.5); // 0.01~1,返回 true 或 false
960
+ console.log(ret);
961
+ ```
962
+
963
+ 输出:
964
+
965
+ ```text
966
+ true
967
+ ```
263
968
 
264
- inRate(0.5); // 0.01 ~ 1 true / false
969
+ 下面的示例测试概率精度。
265
970
 
266
- // 测试准确性
971
+ ```javascript
972
+ // 测试
267
973
  let trueCount = 0;
268
974
  let falseCount = 0;
269
975
  new Array(1000000).fill(0).forEach(() => {
@@ -276,88 +982,221 @@ new Array(1000000).fill(0).forEach(() => {
276
982
  console.log(trueCount, falseCount); // 499994 500006
277
983
  ```
278
984
 
279
- ### 浏览器信息
985
+ #### longestComSubstring
986
+
987
+ 计算两个字符串的最长公共子串长度。
988
+
989
+ 用法:
990
+
991
+ ```javascript
992
+ const ret = longestComSubstring("fish", "finish");
993
+ console.log(ret);
994
+ ```
995
+
996
+ 输出:
997
+
998
+ ```text
999
+ 3
1000
+ ```
1001
+
1002
+ #### longestComSubsequence
1003
+
1004
+ 计算两个字符串的最长公共子序列长度。
1005
+
1006
+ 用法:
280
1007
 
281
1008
  ```javascript
282
- import { getBrowserType } from "mazey";
1009
+ const ret = longestComSubsequence("fish", "finish");
1010
+ console.log(ret);
1011
+ ```
1012
+
1013
+ 输出:
283
1014
 
284
- getBrowserType(); // {"engine":"webkit","engineVs":"537.36","platform":"desktop","supporter":"chrome","supporterVs":"85.0.4183.121","system":"windows","systemVs":"10"}
285
- // 外壳和外壳版本 { shell: "wechat", shellVs: "20" } shell: wechat qq uc 360 2345 sougou liebao maxthon
1015
+ ```text
1016
+ 4
286
1017
  ```
287
1018
 
288
- ### 安全边际
1019
+ ### 浏览器信息
1020
+
1021
+ #### getBrowserInfo
1022
+
1023
+ 获取浏览器信息。
289
1024
 
290
- 判断是否是安全的 PWA 运行环境:
1025
+ 用法:
291
1026
 
292
1027
  ```javascript
293
- import { isSafePWAEnv } from "mazey";
1028
+ const ret = getBrowserInfo();
1029
+ console.log(ret);
1030
+ ```
294
1031
 
295
- isSafePWAEnv(); // true
1032
+ 输出:
1033
+
1034
+ ```text
1035
+ {"engine":"webkit","engineVs":"537.36","platform":"desktop","supporter":"chrome","supporterVs":"85.0.4183.121","system":"windows","systemVs":"10"}
296
1036
  ```
297
1037
 
298
- ### 函数
1038
+ 返回字段:
1039
+
1040
+ | 字段 | 说明 | 类型 | 可选值 |
1041
+ | :--- | :--- | :--- | :--- |
1042
+ | **system** | 操作系统 | string | android、ios、windows、macos、linux |
1043
+ | systemVs | 操作系统版本 | string | Windows: 2000、xp、2003、vista、7、8、8.1、10;macOS: ⋯⋯ |
1044
+ | platform | 平台 | string | desktop、mobile |
1045
+ | engine | 浏览器引擎 | string | webkit、gecko、presto、trident |
1046
+ | engineVs | 浏览器引擎版本 | string | - |
1047
+ | supporter | 浏览器 | string | edge、opera、chrome、safari、firefox、iexplore |
1048
+ | supporterVs | 浏览器版本 | string | - |
1049
+ | shell | 浏览器外壳 | string | 可选: wechat、qq_browser、qq_app、uc、360、2345、sougou、liebao、maxthon、bilibili |
1050
+ | shellVs | 浏览器外壳版本 | string | 可选,例如 `20` |
1051
+ | appleType | Apple 设备类型 | string | 可选: ipad、iphone、ipod、iwatch |
299
1052
 
300
- 防抖:
1053
+ 下面的示例判断当前环境是否为移动版 QQ。
301
1054
 
302
1055
  ```javascript
303
- import { debounce } from "mazey";
1056
+ const { system, shell } = getBrowserInfo();
1057
+ const isMobileQQ = ["android", "ios"].includes(system) && ["qq_browser", "qq_app"].includes(shell);
1058
+ ```
304
1059
 
305
- const foo = debounce(() => {
306
- console.log("执行 1 秒内再次执行无反应");
307
- }, 1000, { leading: true })
1060
+ #### isSafePWAEnv
1061
+
1062
+ 检查当前浏览器文档是否满足 PWA (渐进式 Web 应用) 的最低前提条件。这里只检查同步 JavaScript 能够识别的条件。函数会检查安全上下文和 Service Worker API 支持。文档还必须包含 Web App Manifest (Web 应用清单) 链接,而且 `href` 不能为空。
1063
+
1064
+ 该检查不会验证或请求 Manifest。它也不会验证 Service Worker 是否注册成功。该函数无法判断应用是否已经安装,也不保证浏览器会提供安装提示。不同浏览器还可能执行额外的安装策略。
1065
+
1066
+ 用法:
1067
+
1068
+ ```javascript
1069
+ const ret = isSafePWAEnv();
1070
+ console.log(ret);
1071
+ ```
1072
+
1073
+ 输出:
1074
+
1075
+ ```text
1076
+ true
308
1077
  ```
309
1078
 
310
- 判断是否是有效数字:
1079
+ ### Web 性能
1080
+
1081
+ #### getPerformance
1082
+
1083
+ 获取页面加载时间 (`PerformanceNavigationTiming`)。
1084
+
1085
+ 该函数使用 [`PerformanceNavigationTiming`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming) API 获取页面加载数据。与已弃用的 [`PerformanceTiming`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceTiming) API 相比,新 API 提供的数据更准确,也更详细。
1086
+
1087
+ 用法:
311
1088
 
312
1089
  ```javascript
313
- import { isNumber } from "mazey";
1090
+ // `camelCase: false` (默认值) 返回下划线格式 (`a_b`) 的数据
1091
+ // `camelCase: true` 返回驼峰格式 (`aB`) 的数据
1092
+ getPerformance()
1093
+ .then(res => {
1094
+ console.log(JSON.stringify(res));
1095
+ })
1096
+ .catch(console.error);
1097
+ ```
1098
+
1099
+ 输出:
314
1100
 
315
- isNumber(123); // true
316
- isNumber("123"); // false
317
- // 默认情况下 NaN、Infinity 不算有效数字
318
- isNumber(Infinity); // false
319
- isNumber(Infinity, { isUnFiniteAsNumber: true }); true
320
- isNumber(NaN); // false
321
- isNumber(NaN, { isNaNAsNumber: true, isUnFiniteAsNumber: true }); // true
1101
+ ```text
1102
+ {"source":"PerformanceNavigationTiming","os":"others","os_version":"","device_type":"pc","network":"4g","screen_direction":"","unload_time":0,"redirect_time":0,"dns_time":0,"tcp_time":0,"ssl_time":0,"response_time":2,"download_time":2,"first_paint_time":288,"first_contentful_paint_time":288,"dom_ready_time":0,"onload_time":0,"white_time":0,"render_time":0,"decoded_body_size":718,"encoded_body_size":718}
322
1103
  ```
323
1104
 
1105
+ 返回字段:
1106
+
1107
+ | 字段 | 说明 | 类型 | 计算方式 |
1108
+ | :--- | :--- | :--- | :--- |
1109
+ | dns_time | DNS 查询时间 | number | domainLookupEnd - domainLookupStart |
1110
+ | tcp_time | 连接协商时间 | number | connectEnd - connectStart |
1111
+ | response_time | 请求与响应时间 | number | responseStart - requestStart |
1112
+ | white_time | 白屏时间 | number | responseStart - navigationStart |
1113
+ | dom_ready_time | DOM 就绪时间 | number | domContentLoadedEventStart - navigationStart |
1114
+ | onload_time | 页面加载时间 | number | loadEventStart - navigationStart |
1115
+ | render_time | EventEnd 时间 | number | loadEventEnd - navigationStart |
1116
+ | unload_time | 页面卸载时间 | number | 可选: unloadEventEnd - unloadEventStart |
1117
+ | redirect_time | 重定向时间 | number | 可选: redirectEnd - redirectStart |
1118
+ | ssl_time | SSL 连接时间 | number | 可选: connectEnd - secureConnectionStart |
1119
+ | download_time | 下载时间 | number | 可选: responseEnd - responseStart |
1120
+
324
1121
  ### 调试
325
1122
 
326
- 自定义控制台打印(`console`):
1123
+ #### genCustomConsole
1124
+
1125
+ 创建带有自定义前缀的控制台 (`console`) 输出对象。
1126
+
1127
+ 用法:
327
1128
 
328
1129
  ```javascript
329
- import { genCustomConsole } from "mazey";
1130
+ const myConsole = genCustomConsole("MazeyLog:");
1131
+ myConsole.log("I am string.");
1132
+ myConsole.info("I am boolean.", true);
1133
+ myConsole.info("I am number.", 123, 456);
1134
+ myConsole.info("I am object.", { a: 123, b: 456});
1135
+ ```
1136
+
1137
+ 输出:
330
1138
 
331
- const myConsole = genCustomConsole({ prefix: "MazeyLog:" });
332
- myConsole.log("I am string."); // MazeyLog: I am string.
333
- myConsole.info("I am boolean.", true); // MazeyLog: I am boolean. true
334
- myConsole.info("I am number.", 123, 456); // MazeyLog: I am number. 123 456
335
- myConsole.info("I am object.", { a: 123, b: 456}); // MazeyLog: I am object. {a: 123, b: 456}
1139
+ ```text
1140
+ MazeyLog: I am string.
1141
+ MazeyLog: I am boolean. true
1142
+ MazeyLog: I am number. 123 456
1143
+ MazeyLog: I am object. {a: 123, b: 456}
336
1144
  ```
337
1145
 
338
- [更多接口>>](https://mazey.cn/t/m)
1146
+ ## 参与贡献
1147
+
1148
+ ### 开发环境
339
1149
 
340
- ## 开发
1150
+ | 依赖 | 版本 |
1151
+ | --- | --- |
1152
+ | Node.js | v22.21.1 |
1153
+ | TypeScript | v5.1.6 |
341
1154
 
342
- Development:
1155
+ ### 脚本
1156
+
1157
+ 安装依赖:
1158
+
1159
+ ```bash
1160
+ npm i
1161
+ ```
1162
+
1163
+ 启动开发环境:
343
1164
 
344
1165
  ```bash
345
1166
  npm run dev
346
1167
  ```
347
1168
 
348
- Build:
1169
+ 构建:
349
1170
 
350
1171
  ```bash
351
1172
  npm run build
352
1173
  ```
353
1174
 
354
- Document:
1175
+ 测试:
1176
+
1177
+ ```bash
1178
+ npm run test
1179
+ ```
1180
+
1181
+ 生成文档:
355
1182
 
356
1183
  ```bash
357
1184
  npm run docs
358
1185
  ```
359
1186
 
360
- ## 参考
1187
+ ### 返回值
1188
+
1189
+ | 值 | 说明 | 类型 |
1190
+ | :--- | :--- | :--- |
1191
+ | ok | 操作成功。 | string |
1192
+ | loaded | 资源已经加载。 | string |
1193
+ | failed | 发生错误。 | string |
1194
+ | defined | 值已定义。 | string |
1195
+ | undefined | 值未定义。 | string |
1196
+ | timeout | 操作超时。 | string |
1197
+ | true | 值为真。 | boolean |
1198
+ | false | 值为假。 | boolean |
1199
+
1200
+ ## 许可证
361
1201
 
362
- 1. [@babel/preset-env conflicts with @babel/plugin-transform-runtime when using core-js@3](https://github.com/babel/babel/issues/10271#issuecomment-528379505)
363
- 2. [@babel/plugin-transform-runtime](https://babeljs.io/docs/en/babel-plugin-transform-runtime)
1202
+ 本软件按照 [MIT 许可证](https://github.com/chengchuu/mazey/blob/main/LICENSE) 发布。