sculp-js 0.0.2 → 1.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/LICENSE.md +1 -1
- package/README.md +22 -1
- package/lib/cjs/array.js +32 -55
- package/lib/cjs/async.js +3 -3
- package/lib/cjs/clipboard.js +3 -3
- package/lib/cjs/cookie.js +5 -5
- package/lib/cjs/date.js +142 -24
- package/lib/cjs/dom.js +24 -10
- package/lib/cjs/download.js +9 -9
- package/lib/cjs/easing.js +1 -1
- package/lib/cjs/file.js +5 -4
- package/lib/cjs/func.js +160 -0
- package/lib/cjs/index.js +28 -2
- package/lib/cjs/number.js +82 -0
- package/lib/cjs/object.js +13 -11
- package/lib/cjs/path.js +1 -1
- package/lib/cjs/qs.js +5 -5
- package/lib/cjs/random.js +72 -0
- package/lib/cjs/string.js +40 -7
- package/lib/cjs/type.js +12 -2
- package/lib/cjs/unique.js +83 -0
- package/lib/cjs/url.js +1 -1
- package/lib/cjs/watermark.js +8 -9
- package/lib/es/array.js +33 -55
- package/lib/es/async.js +3 -3
- package/lib/es/clipboard.js +3 -3
- package/lib/es/cookie.js +5 -5
- package/lib/es/date.js +139 -25
- package/lib/es/dom.js +24 -11
- package/lib/es/download.js +9 -9
- package/lib/es/easing.js +1 -1
- package/lib/es/file.js +5 -4
- package/lib/es/func.js +154 -0
- package/lib/es/index.js +10 -6
- package/lib/es/number.js +77 -0
- package/lib/es/object.js +12 -10
- package/lib/es/path.js +1 -1
- package/lib/es/qs.js +5 -5
- package/lib/es/random.js +67 -0
- package/lib/es/string.js +40 -8
- package/lib/es/type.js +12 -3
- package/lib/es/unique.js +79 -0
- package/lib/es/url.js +1 -1
- package/lib/es/watermark.js +8 -9
- package/lib/index.d.ts +254 -80
- package/lib/umd/index.js +637 -132
- package/package.json +36 -12
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2020-present,
|
|
3
|
+
Copyright (c) 2020-present, chandq
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
[](https://github.com/chandq/sculp-js/actions/workflows/node.js.yml)
|
|
2
|
+
[](https://github.com/chandq/sculp-js)
|
|
3
|
+
[](https://nodejs.org/download/release/v12.0.0/)
|
|
4
|
+
[](https://nodejs.org/download/release/v12.0.0/)
|
|
5
|
+
[](https://github.com/chandq/sculp-js/blob/main/LICENSE.md)
|
|
6
|
+
[](https://npmcharts.com/compare/sculp-js?minimal=true)
|
|
7
|
+
|
|
1
8
|
# sculp-js
|
|
2
9
|
|
|
3
|
-
>
|
|
10
|
+
> TS + Rollup, 原生实现,不依赖任何第三方库,输出 esm、cjs、umd三种模块方式的产物
|
|
11
|
+
|
|
12
|
+
js 工具函数库, 包含类型判断模块:type, 数据处理模块:`array`、`object`、`string`、`number`,功能性模块:下载`download`、复制`clipboard`、`cookie`、日期`date`、qs、水印`watermark`, 文件处理模块:`file`,自定义悬浮提示模块: `tooltip`, dom处理模块:`dom`;
|
|
13
|
+
|
|
14
|
+
- Array
|
|
15
|
+
|
|
16
|
+
- arrayLike 判断类数组
|
|
17
|
+
- arrayEach 可中断的数组遍历, 支持倒序
|
|
18
|
+
- arrayEachAsync 异步遍历数组,可中断,支持倒序
|
|
19
|
+
- arrayInsertBefore 改变数组元素位置
|
|
20
|
+
- arrayRemove 数组删除指定元素
|
|
21
|
+
- deepTraversal 深度优先遍历函数, 支持continue、break,可定制id、children
|
|
22
|
+
- getTreeIds 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
|
|
23
|
+
|
|
24
|
+
## [API文档详情](https://chandq.github.io/sculp-js/)
|
package/lib/cjs/array.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -11,10 +11,11 @@ var type = require('./type.js');
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* 判断一个对象是否为类数组
|
|
14
|
+
*
|
|
14
15
|
* @param any
|
|
15
16
|
* @returns {boolean}
|
|
16
17
|
*/
|
|
17
|
-
|
|
18
|
+
function arrayLike(any) {
|
|
18
19
|
if (type.isArray(any))
|
|
19
20
|
return true;
|
|
20
21
|
if (type.isString(any))
|
|
@@ -22,34 +23,36 @@ const arrayLike = (any) => {
|
|
|
22
23
|
if (!type.isObject(any))
|
|
23
24
|
return false;
|
|
24
25
|
return object.objectHas(any, 'length');
|
|
25
|
-
}
|
|
26
|
+
}
|
|
26
27
|
/**
|
|
27
28
|
* 遍历数组,返回 false 中断遍历
|
|
29
|
+
*
|
|
28
30
|
* @param {ArrayLike<V>} array
|
|
29
31
|
* @param {(val: V, idx: number) => any} iterator
|
|
30
32
|
* @param reverse {boolean} 是否倒序
|
|
33
|
+
* @returns {*}
|
|
31
34
|
*/
|
|
32
|
-
|
|
35
|
+
function arrayEach(array, iterator, reverse = false) {
|
|
33
36
|
if (reverse) {
|
|
34
37
|
for (let idx = array.length - 1; idx >= 0; idx--) {
|
|
35
38
|
const val = array[idx];
|
|
36
|
-
if (iterator(val, idx) === false)
|
|
39
|
+
if (iterator(val, idx, array) === false)
|
|
37
40
|
break;
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
else {
|
|
41
44
|
for (let idx = 0; idx < array.length; idx++) {
|
|
42
45
|
const val = array[idx];
|
|
43
|
-
if (iterator(val, idx) === false)
|
|
46
|
+
if (iterator(val, idx, array) === false)
|
|
44
47
|
break;
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
|
-
}
|
|
50
|
+
}
|
|
48
51
|
/**
|
|
49
52
|
* 异步遍历数组,返回 false 中断遍历
|
|
50
|
-
* @param {ArrayLike<V>} array
|
|
51
|
-
* @param {(val: V, idx: number) => Promise<any>} iterator
|
|
52
|
-
* @param {boolean} reverse
|
|
53
|
+
* @param {ArrayLike<V>} array 数组
|
|
54
|
+
* @param {(val: V, idx: number) => Promise<any>} iterator 支持Promise类型的回调函数
|
|
55
|
+
* @param {boolean} reverse 是否反向遍历
|
|
53
56
|
*/
|
|
54
57
|
async function arrayEachAsync(array, iterator, reverse = false) {
|
|
55
58
|
if (reverse) {
|
|
@@ -72,15 +75,16 @@ async function arrayEachAsync(array, iterator, reverse = false) {
|
|
|
72
75
|
* @param {AnyArray} array
|
|
73
76
|
* @param {number} start
|
|
74
77
|
* @param {number} to
|
|
78
|
+
* @returns {*}
|
|
75
79
|
*/
|
|
76
|
-
|
|
80
|
+
function arrayInsertBefore(array, start, to) {
|
|
77
81
|
if (start === to || start + 1 === to)
|
|
78
82
|
return;
|
|
79
83
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
80
84
|
const [source] = array.splice(start, 1);
|
|
81
85
|
const insertIndex = to < start ? to : to - 1;
|
|
82
86
|
array.splice(insertIndex, 0, source);
|
|
83
|
-
}
|
|
87
|
+
}
|
|
84
88
|
/**
|
|
85
89
|
* 数组删除指定项目
|
|
86
90
|
* @param {V[]} array
|
|
@@ -101,17 +105,18 @@ function arrayRemove(array, expect) {
|
|
|
101
105
|
}
|
|
102
106
|
/**
|
|
103
107
|
* 自定义深度优先遍历函数(支持continue和break操作)
|
|
104
|
-
* @param {
|
|
105
|
-
* @param {
|
|
106
|
-
* @param {
|
|
107
|
-
* @param {boolean} isReverse
|
|
108
|
+
* @param {ArrayLike<V>} tree 树形数据
|
|
109
|
+
* @param {Function} iterator 迭代函数
|
|
110
|
+
* @param {string} children 定制子元素的key
|
|
111
|
+
* @param {boolean} isReverse 是否反向遍历
|
|
112
|
+
* @returns {*}
|
|
108
113
|
*/
|
|
109
|
-
|
|
114
|
+
function deepTraversal(tree, iterator, children = 'children', isReverse = false) {
|
|
110
115
|
let level = 0;
|
|
111
116
|
const walk = (arr, parent) => {
|
|
112
117
|
if (isReverse) {
|
|
113
118
|
for (let i = arr.length - 1; i >= 0; i--) {
|
|
114
|
-
const re = iterator(arr[i], i,
|
|
119
|
+
const re = iterator(arr[i], i, tree, parent, level);
|
|
115
120
|
if (re === 'break') {
|
|
116
121
|
break;
|
|
117
122
|
}
|
|
@@ -128,7 +133,7 @@ const deepTraversal = (deepList, iterator, children = 'children', isReverse = fa
|
|
|
128
133
|
}
|
|
129
134
|
else {
|
|
130
135
|
for (let i = 0; i < arr.length; i++) {
|
|
131
|
-
const re = iterator(arr[i], i,
|
|
136
|
+
const re = iterator(arr[i], i, tree, parent, level);
|
|
132
137
|
if (re === 'break') {
|
|
133
138
|
break;
|
|
134
139
|
}
|
|
@@ -144,14 +149,15 @@ const deepTraversal = (deepList, iterator, children = 'children', isReverse = fa
|
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
};
|
|
147
|
-
walk(
|
|
148
|
-
}
|
|
152
|
+
walk(tree, null);
|
|
153
|
+
}
|
|
149
154
|
/**
|
|
150
155
|
* 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
|
|
151
|
-
*
|
|
152
|
-
* @param {
|
|
153
|
-
* @param {
|
|
154
|
-
* @
|
|
156
|
+
*
|
|
157
|
+
* @param {ArrayLike<T>} tree - 树形数据
|
|
158
|
+
* @param {IdLike} nodeId - 元素ID
|
|
159
|
+
* @param {ITreeConf} config - 迭代配置项
|
|
160
|
+
* @returns {[IdLike[], ITreeItem<V>[]]} - 由parentId...childId, parentObject-childObject组成的二维数组
|
|
155
161
|
*/
|
|
156
162
|
function getTreeIds(tree, nodeId, config) {
|
|
157
163
|
const { children = 'children', id = 'id' } = config || {};
|
|
@@ -172,46 +178,17 @@ function getTreeIds(tree, nodeId, config) {
|
|
|
172
178
|
while (child && child.parentId) {
|
|
173
179
|
ids = [child.parentId, ...ids];
|
|
174
180
|
nodes = [child.parent, ...nodes];
|
|
175
|
-
child = flatArray.find(_ => _[id] === child.parentId);
|
|
181
|
+
child = flatArray.find(_ => _[id] === child.parentId); // eslint-disable-line
|
|
176
182
|
}
|
|
177
183
|
return [ids, nodes];
|
|
178
184
|
};
|
|
179
185
|
return getIds(toFlatArray(tree));
|
|
180
186
|
}
|
|
181
|
-
/**
|
|
182
|
-
* 异步ForEach函数
|
|
183
|
-
* @param {array} array
|
|
184
|
-
* @param {asyncFuntion} callback
|
|
185
|
-
* // asyncForEach 使用范例如下
|
|
186
|
-
// const start = async () => {
|
|
187
|
-
// await asyncForEach(result, async (item) => {
|
|
188
|
-
// await request(item);
|
|
189
|
-
// count++;
|
|
190
|
-
// });
|
|
191
|
-
|
|
192
|
-
// console.log('发送次数', count);
|
|
193
|
-
// }
|
|
194
|
-
|
|
195
|
-
// for await...of 使用范例如下
|
|
196
|
-
// const loadImages = async (images) => {
|
|
197
|
-
// for await (const item of images) {
|
|
198
|
-
// await request(item);
|
|
199
|
-
// count++;
|
|
200
|
-
// }
|
|
201
|
-
// }
|
|
202
|
-
* @return {*}
|
|
203
|
-
*/
|
|
204
|
-
async function asyncForEach(array, callback) {
|
|
205
|
-
for (let index = 0, len = array.length; index < len; index++) {
|
|
206
|
-
await callback(array[index], index, array);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
187
|
|
|
210
188
|
exports.arrayEach = arrayEach;
|
|
211
189
|
exports.arrayEachAsync = arrayEachAsync;
|
|
212
190
|
exports.arrayInsertBefore = arrayInsertBefore;
|
|
213
191
|
exports.arrayLike = arrayLike;
|
|
214
192
|
exports.arrayRemove = arrayRemove;
|
|
215
|
-
exports.asyncForEach = asyncForEach;
|
|
216
193
|
exports.deepTraversal = deepTraversal;
|
|
217
194
|
exports.getTreeIds = getTreeIds;
|
package/lib/cjs/async.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @param {number} timeout 等待时间,单位毫秒
|
|
12
12
|
* @returns {Promise<void>}
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
function wait(timeout = 1) {
|
|
15
15
|
return new Promise(resolve => setTimeout(resolve, timeout));
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
@@ -23,7 +23,7 @@ async function wait(timeout = 1) {
|
|
|
23
23
|
* @param {number} concurrency 并发数量,默认无限
|
|
24
24
|
* @returns {Promise<R[]>}
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
function asyncMap(list, mapper, concurrency = Infinity) {
|
|
27
27
|
return new Promise((resolve, reject) => {
|
|
28
28
|
const iterator = list[Symbol.iterator]();
|
|
29
29
|
const limit = Math.min(list.length, concurrency);
|
package/lib/cjs/clipboard.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -20,7 +20,7 @@ document.body.appendChild(textEl);
|
|
|
20
20
|
* 复制文本
|
|
21
21
|
* @param {string} text
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
function copyText(text) {
|
|
24
24
|
textEl.value = text;
|
|
25
25
|
textEl.focus({ preventScroll: true });
|
|
26
26
|
textEl.select();
|
|
@@ -31,6 +31,6 @@ const copyText = (text) => {
|
|
|
31
31
|
catch (err) {
|
|
32
32
|
// ignore
|
|
33
33
|
}
|
|
34
|
-
}
|
|
34
|
+
}
|
|
35
35
|
|
|
36
36
|
exports.copyText = copyText;
|
package/lib/cjs/cookie.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -13,7 +13,7 @@ var type = require('./type.js');
|
|
|
13
13
|
* @param {string} name
|
|
14
14
|
* @returns {string}
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
function cookieGet(name) {
|
|
17
17
|
const { cookie } = document;
|
|
18
18
|
if (!cookie)
|
|
19
19
|
return '';
|
|
@@ -25,14 +25,14 @@ const cookieGet = (name) => {
|
|
|
25
25
|
return decodeURIComponent(val);
|
|
26
26
|
}
|
|
27
27
|
return '';
|
|
28
|
-
}
|
|
28
|
+
}
|
|
29
29
|
/**
|
|
30
30
|
* 设置 cookie
|
|
31
31
|
* @param {string} name
|
|
32
32
|
* @param {string} value
|
|
33
33
|
* @param {number | Date} [maxAge]
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
function cookieSet(name, value, maxAge) {
|
|
36
36
|
const metas = [];
|
|
37
37
|
const EXPIRES = 'expires';
|
|
38
38
|
metas.push([name, encodeURIComponent(value)]);
|
|
@@ -51,7 +51,7 @@ const cookieSet = (name, value, maxAge) => {
|
|
|
51
51
|
return `${key}=${val}`;
|
|
52
52
|
})
|
|
53
53
|
.join(';');
|
|
54
|
-
}
|
|
54
|
+
}
|
|
55
55
|
/**
|
|
56
56
|
* 删除单个 cookie
|
|
57
57
|
* @param name cookie 名称
|
package/lib/cjs/date.js
CHANGED
|
@@ -1,11 +1,66 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
var type = require('./type.js');
|
|
10
|
+
|
|
11
|
+
const isValidDate = (any) => type.isDate(any) && !type.isNaN(any.getTime());
|
|
12
|
+
/* istanbul ignore next */
|
|
13
|
+
const guessDateSeparator = (value) => {
|
|
14
|
+
if (!type.isString(value))
|
|
15
|
+
return;
|
|
16
|
+
const value2 = value.replace(/-/g, '/');
|
|
17
|
+
return new Date(value2);
|
|
18
|
+
};
|
|
19
|
+
/* istanbul ignore next */
|
|
20
|
+
const guessDateTimezone = (value) => {
|
|
21
|
+
if (!type.isString(value))
|
|
22
|
+
return;
|
|
23
|
+
const re = /([+-])(\d\d)(\d\d)$/;
|
|
24
|
+
const matches = re.exec(value);
|
|
25
|
+
if (!matches)
|
|
26
|
+
return;
|
|
27
|
+
const value2 = value.replace(re, 'Z');
|
|
28
|
+
const d = new Date(value2);
|
|
29
|
+
if (!isValidDate(d))
|
|
30
|
+
return;
|
|
31
|
+
const [, flag, hours, minutes] = matches;
|
|
32
|
+
const hours2 = parseInt(hours, 10);
|
|
33
|
+
const minutes2 = parseInt(minutes, 10);
|
|
34
|
+
const offset = (a, b) => (flag === '+' ? a - b : a + b);
|
|
35
|
+
d.setHours(offset(d.getHours(), hours2));
|
|
36
|
+
d.setMinutes(offset(d.getMinutes(), minutes2));
|
|
37
|
+
return d;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* 解析为Date对象
|
|
41
|
+
* @param {DateValue} value - 可以是数值、字符串或 Date 对象
|
|
42
|
+
* @returns {Date} - 转换后的目标Date
|
|
43
|
+
*/
|
|
44
|
+
function dateParse(value) {
|
|
45
|
+
const d1 = new Date(value);
|
|
46
|
+
if (isValidDate(d1))
|
|
47
|
+
return d1;
|
|
48
|
+
// safari 浏览器的日期解析有问题
|
|
49
|
+
// new Date('2020-06-26 18:06:15') 返回值是一个非法日期对象
|
|
50
|
+
/* istanbul ignore next */
|
|
51
|
+
const d2 = guessDateSeparator(value);
|
|
52
|
+
/* istanbul ignore next */
|
|
53
|
+
if (isValidDate(d2))
|
|
54
|
+
return d2;
|
|
55
|
+
// safari 浏览器的日期解析有问题
|
|
56
|
+
// new Date('2020-06-26T18:06:15.000+0800') 返回值是一个非法日期对象
|
|
57
|
+
/* istanbul ignore next */
|
|
58
|
+
const d3 = guessDateTimezone(value);
|
|
59
|
+
/* istanbul ignore next */
|
|
60
|
+
if (isValidDate(d3))
|
|
61
|
+
return d3;
|
|
62
|
+
throw new SyntaxError(`${value.toString()} 不是一个合法的日期描述`);
|
|
63
|
+
}
|
|
9
64
|
/**
|
|
10
65
|
* 格式化为日期对象(带自定义格式化模板)
|
|
11
66
|
* @param {DateValue} value 可以是数值、字符串或 Date 对象
|
|
@@ -20,10 +75,69 @@
|
|
|
20
75
|
* - mm:分
|
|
21
76
|
* - ss:秒
|
|
22
77
|
* - SSS:毫秒
|
|
23
|
-
* - ww: 周
|
|
24
78
|
* @returns {string}
|
|
25
79
|
*/
|
|
26
|
-
const
|
|
80
|
+
// export const dateStringify = (value: DateValue, format = 'YYYY-MM-DD HH:mm:ss'): string => {
|
|
81
|
+
// const date = dateParse(value);
|
|
82
|
+
// let fmt = format;
|
|
83
|
+
// let ret;
|
|
84
|
+
// const opt: DateObj = {
|
|
85
|
+
// 'Y+': `${date.getFullYear()}`, // 年
|
|
86
|
+
// 'y+': `${date.getFullYear()}`, // 年
|
|
87
|
+
// 'M+': `${date.getMonth() + 1}`, // 月
|
|
88
|
+
// 'D+': `${date.getDate()}`, // 日
|
|
89
|
+
// 'd+': `${date.getDate()}`, // 日
|
|
90
|
+
// 'H+': `${date.getHours()}`, // 时
|
|
91
|
+
// 'm+': `${date.getMinutes()}`, // 分
|
|
92
|
+
// 's+': `${date.getSeconds()}`, // 秒
|
|
93
|
+
// 'S+': `${date.getMilliseconds()}` // 豪秒
|
|
94
|
+
// };
|
|
95
|
+
// for (const k in opt) {
|
|
96
|
+
// ret = new RegExp(`(${k})`).exec(fmt);
|
|
97
|
+
// if (ret) {
|
|
98
|
+
// fmt = fmt.replace(ret[1], ret[1].length === 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'));
|
|
99
|
+
// }
|
|
100
|
+
// }
|
|
101
|
+
// return fmt;
|
|
102
|
+
// };
|
|
103
|
+
/**
|
|
104
|
+
* 将日期转换为一天的开始时间,即0点0分0秒0毫秒
|
|
105
|
+
* @param {DateValue} value
|
|
106
|
+
* @returns {Date}
|
|
107
|
+
*/
|
|
108
|
+
function dateToStart(value) {
|
|
109
|
+
const d = dateParse(value);
|
|
110
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 将日期转换为一天的结束时间,即23点59分59秒999毫秒
|
|
114
|
+
* @param {DateValue} value
|
|
115
|
+
* @returns {Date}
|
|
116
|
+
*/
|
|
117
|
+
function dateToEnd(value) {
|
|
118
|
+
const d = dateToStart(value);
|
|
119
|
+
d.setDate(d.getDate() + 1);
|
|
120
|
+
return dateParse(d.getTime() - 1);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 格式化为日期对象(带自定义格式化模板)
|
|
124
|
+
* @param {Date} value - 可以是数值、字符串或 Date 对象
|
|
125
|
+
* @param {string} [format] - 模板,默认是 YYYY-MM-DD HH:mm:ss,模板字符:
|
|
126
|
+
* - YYYY:年
|
|
127
|
+
* - yyyy: 年
|
|
128
|
+
* - MM:月
|
|
129
|
+
* - DD:日
|
|
130
|
+
* - dd: 日
|
|
131
|
+
* - HH:时(24 小时制)
|
|
132
|
+
* - hh:时(12 小时制)
|
|
133
|
+
* - mm:分
|
|
134
|
+
* - ss:秒
|
|
135
|
+
* - SSS:毫秒
|
|
136
|
+
* - ww: 周
|
|
137
|
+
* @returns {string} 格式化后的日期字符串
|
|
138
|
+
*/
|
|
139
|
+
function formatDate(value, format = 'YYYY-MM-DD HH:mm:ss') {
|
|
140
|
+
const date = dateParse(value);
|
|
27
141
|
let fmt = format;
|
|
28
142
|
let ret;
|
|
29
143
|
const opt = {
|
|
@@ -46,39 +160,39 @@ const formatDate = (date = new Date(), format = 'YYYY-MM-DD HH:mm:ss') => {
|
|
|
46
160
|
}
|
|
47
161
|
}
|
|
48
162
|
return fmt;
|
|
49
|
-
}
|
|
163
|
+
}
|
|
50
164
|
/**
|
|
51
165
|
* 计算向前或向后N天的具体日期
|
|
52
|
-
* @param {string} strDate 参考日期
|
|
53
|
-
* @param {number} n 正数:向后推算;负数:向前推算
|
|
54
|
-
* @param {string} sep 日期格式的分隔符
|
|
55
|
-
* @
|
|
166
|
+
* @param {string} strDate - 参考日期
|
|
167
|
+
* @param {number} n - 正数:向后推算;负数:向前推算
|
|
168
|
+
* @param {string} sep - 日期格式的分隔符
|
|
169
|
+
* @returns {string} 计算后的目标日期
|
|
56
170
|
*/
|
|
57
171
|
function calculateDate(strDate, n, sep = '-') {
|
|
58
172
|
//strDate 为字符串日期 如:'2019-01-01' n为你要传入的参数,当前为0,前一天为-1,后一天为1
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
173
|
+
const dateArr = strDate.split(sep); //这边给定一个特定时间
|
|
174
|
+
const newDate = new Date(+dateArr[0], +dateArr[1] - 1, +dateArr[2]);
|
|
175
|
+
const befminuts = newDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(String(n)); //计算前几天用减,计算后几天用加,最后一个就是多少天的数量
|
|
176
|
+
const beforeDat = new Date();
|
|
63
177
|
beforeDat.setTime(befminuts);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
178
|
+
const befMonth = beforeDat.getMonth() + 1;
|
|
179
|
+
const mon = befMonth >= 10 ? befMonth : '0' + befMonth;
|
|
180
|
+
const befDate = beforeDat.getDate();
|
|
181
|
+
const da = befDate >= 10 ? befDate : '0' + befDate;
|
|
182
|
+
const finalNewDate = beforeDat.getFullYear() + '-' + mon + '-' + da;
|
|
69
183
|
return finalNewDate;
|
|
70
184
|
}
|
|
71
185
|
/**
|
|
72
186
|
* 计算向前或向后N天的具体时间日期
|
|
73
|
-
* @param {number} n 正数:向后推算;负数:向前推算
|
|
74
|
-
* @param {string} dateSep 日期分隔符
|
|
75
|
-
* @param {string} timeSep 时间分隔符
|
|
76
|
-
* @
|
|
187
|
+
* @param {number} n - 正数:向后推算;负数:向前推算
|
|
188
|
+
* @param {string} dateSep - 日期分隔符
|
|
189
|
+
* @param {string} timeSep - 时间分隔符
|
|
190
|
+
* @returns {string} 转换后的目标日期时间
|
|
77
191
|
*/
|
|
78
192
|
function calculateDateTime(n, dateSep = '-', timeSep = ':') {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
193
|
+
const date = new Date();
|
|
194
|
+
const separator1 = '-';
|
|
195
|
+
const separator2 = ':';
|
|
82
196
|
let year = date.getFullYear();
|
|
83
197
|
let month = date.getMonth() + 1;
|
|
84
198
|
let strDate = date.getDate() + n;
|
|
@@ -111,4 +225,8 @@ function calculateDateTime(n, dateSep = '-', timeSep = ':') {
|
|
|
111
225
|
|
|
112
226
|
exports.calculateDate = calculateDate;
|
|
113
227
|
exports.calculateDateTime = calculateDateTime;
|
|
228
|
+
exports.dateParse = dateParse;
|
|
229
|
+
exports.dateToEnd = dateToEnd;
|
|
230
|
+
exports.dateToStart = dateToStart;
|
|
114
231
|
exports.formatDate = formatDate;
|
|
232
|
+
exports.isValidDate = isValidDate;
|
package/lib/cjs/dom.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -18,11 +18,11 @@ var type = require('./type.js');
|
|
|
18
18
|
* @param {string} className
|
|
19
19
|
* @returns {boolean}
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
function hasClass(el, className) {
|
|
22
22
|
if (className.indexOf(' ') !== -1)
|
|
23
23
|
throw new Error('className should not contain space.');
|
|
24
24
|
return el.classList.contains(className);
|
|
25
|
-
}
|
|
25
|
+
}
|
|
26
26
|
const eachClassName = (classNames, func) => {
|
|
27
27
|
const classNameList = classNames.split(/\s+/g);
|
|
28
28
|
classNameList.forEach(func);
|
|
@@ -32,17 +32,17 @@ const eachClassName = (classNames, func) => {
|
|
|
32
32
|
* @param {HTMLElement} el
|
|
33
33
|
* @param {string} classNames
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
function addClass(el, classNames) {
|
|
36
36
|
eachClassName(classNames, className => el.classList.add(className));
|
|
37
|
-
}
|
|
37
|
+
}
|
|
38
38
|
/**
|
|
39
39
|
* 给元素移除样式名
|
|
40
40
|
* @param {HTMLElement} el
|
|
41
41
|
* @param {string} classNames
|
|
42
42
|
*/
|
|
43
|
-
|
|
43
|
+
function removeClass(el, classNames) {
|
|
44
44
|
eachClassName(classNames, className => el.classList.remove(className));
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
/**
|
|
47
47
|
* 设置元素样式
|
|
48
48
|
* @param {HTMLElement} el
|
|
@@ -61,12 +61,14 @@ const setStyle = (el, key, val) => {
|
|
|
61
61
|
};
|
|
62
62
|
/**
|
|
63
63
|
* 获取元素样式
|
|
64
|
-
* @param {HTMLElement} el
|
|
64
|
+
* @param {HTMLElement} el 元素
|
|
65
65
|
* @param {string} key
|
|
66
66
|
* @returns {string}
|
|
67
67
|
*/
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
function getStyle(el, key) {
|
|
69
|
+
return getComputedStyle(el).getPropertyValue(key);
|
|
70
|
+
}
|
|
71
|
+
function smoothScroll(options) {
|
|
70
72
|
return new Promise(resolve => {
|
|
71
73
|
const defaults = {
|
|
72
74
|
el: document,
|
|
@@ -141,8 +143,20 @@ function onDomReady(callback) {
|
|
|
141
143
|
domReadyCallbacks.push(callback);
|
|
142
144
|
}
|
|
143
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* 获取元素样式属性的计算值
|
|
148
|
+
* @param {HTMLElement} el
|
|
149
|
+
* @param {string} property
|
|
150
|
+
* @param {boolean} reNumber
|
|
151
|
+
* @returns {string|number}
|
|
152
|
+
*/
|
|
153
|
+
function getComputedCssVal(el, property, reNumber = true) {
|
|
154
|
+
const originVal = getComputedStyle(el).getPropertyValue(property) ?? '';
|
|
155
|
+
return reNumber ? Number(originVal.replace(/([0-9]*)(.*)/g, '$1')) : originVal;
|
|
156
|
+
}
|
|
144
157
|
|
|
145
158
|
exports.addClass = addClass;
|
|
159
|
+
exports.getComputedCssVal = getComputedCssVal;
|
|
146
160
|
exports.getStyle = getStyle;
|
|
147
161
|
exports.hasClass = hasClass;
|
|
148
162
|
exports.isDomReady = isDomReady;
|
package/lib/cjs/download.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -13,15 +13,15 @@ var url = require('./url.js');
|
|
|
13
13
|
* @param {string} url
|
|
14
14
|
* @param {LooseParams} params
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
function downloadURL(url$1, params) {
|
|
17
17
|
window.open(params ? url.urlSetParams(url$1, params) : url$1);
|
|
18
|
-
}
|
|
18
|
+
}
|
|
19
19
|
/**
|
|
20
20
|
* 通过 A 链接的方式下载
|
|
21
21
|
* @param {string} href
|
|
22
22
|
* @param {string} filename
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
function downloadHref(href, filename) {
|
|
25
25
|
const eleLink = document.createElement('a');
|
|
26
26
|
eleLink.download = filename;
|
|
27
27
|
eleLink.style.display = 'none';
|
|
@@ -29,17 +29,17 @@ const downloadHref = (href, filename) => {
|
|
|
29
29
|
document.body.appendChild(eleLink);
|
|
30
30
|
eleLink.click();
|
|
31
31
|
setTimeout(() => document.body.removeChild(eleLink));
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
33
|
/**
|
|
34
34
|
* 将大文件对象通过 A 链接的方式下载
|
|
35
35
|
* @param {Blob} blob
|
|
36
36
|
* @param {string} filename
|
|
37
37
|
*/
|
|
38
|
-
|
|
38
|
+
function downloadBlob(blob, filename) {
|
|
39
39
|
const objURL = URL.createObjectURL(blob);
|
|
40
40
|
downloadHref(objURL, filename);
|
|
41
41
|
setTimeout(() => URL.revokeObjectURL(objURL));
|
|
42
|
-
}
|
|
42
|
+
}
|
|
43
43
|
/**
|
|
44
44
|
* 将指定数据格式通过 A 链接的方式下载
|
|
45
45
|
* @param {AnyObject | AnyObject[]} data
|
|
@@ -47,7 +47,7 @@ const downloadBlob = (blob, filename) => {
|
|
|
47
47
|
* @param {string} filename
|
|
48
48
|
* @param {string[]} [headers]
|
|
49
49
|
*/
|
|
50
|
-
|
|
50
|
+
function downloadData(data, fileType, filename, headers) {
|
|
51
51
|
filename = filename.replace(`.${fileType}`, '') + `.${fileType}`;
|
|
52
52
|
if (fileType === 'json') {
|
|
53
53
|
const blob = new Blob([JSON.stringify(data, null, 4)]);
|
|
@@ -74,7 +74,7 @@ const downloadData = (data, fileType, filename, headers) => {
|
|
|
74
74
|
const href = 'data:' + MIMETypes[fileType] + ';charset=utf-8,\ufeff' + encodeURIComponent(headerStr + bodyStr);
|
|
75
75
|
downloadHref(href, filename);
|
|
76
76
|
}
|
|
77
|
-
}
|
|
77
|
+
}
|
|
78
78
|
|
|
79
79
|
exports.downloadBlob = downloadBlob;
|
|
80
80
|
exports.downloadData = downloadData;
|
package/lib/cjs/easing.js
CHANGED