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