@codady/utils 0.0.17 → 0.0.19
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/CHANGELOG.md +39 -0
- package/dist/utils.cjs.js +175 -10
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +175 -10
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +175 -10
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/modules.js +7 -1
- package/modules.ts +7 -1
- package/package.json +1 -1
- package/src/createEl.js +83 -0
- package/src/createEl.ts +80 -0
- package/src/deepClone.js +1 -1
- package/src/deepClone.ts +1 -1
- package/src/deepMerge.js +35 -9
- package/src/deepMerge.ts +37 -9
- package/src/getEl.js +38 -0
- package/src/getEl.ts +41 -0
- package/src/getEls.js +48 -0
- package/src/getEls.ts +48 -0
package/src/deepMerge.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since Last modified: 2025/12/
|
|
2
|
+
* @since Last modified: 2025/12/27 14:35:01
|
|
3
3
|
* @function deepMerge
|
|
4
4
|
* @description Deeply merges two data structures (Object, Array, Map, or Set) based on their types.
|
|
5
5
|
* This function recursively merges the properties or items of the target and source, depending on their types.
|
|
@@ -42,6 +42,10 @@ export interface DeepMergeOptions {
|
|
|
42
42
|
// Mode for handling array items
|
|
43
43
|
// 处理数组成员的模式
|
|
44
44
|
dataMode?: 'clear' | 'replace' | 'concat';
|
|
45
|
+
//如果source值=null,target如何处理,ignore表示不理会null保持target;preserve将覆盖target,delete将删除target(key)
|
|
46
|
+
nullBehavior?: 'ignore' | 'preserve' | 'delete';
|
|
47
|
+
//如果source值=undefined,target如何处理,ignore表示不理会undefined保持target;preserve将覆盖target,delete将删除target(key)
|
|
48
|
+
undefinedBehavior?: 'ignore' | 'preserve' | 'delete';
|
|
45
49
|
// Whether to append properties (for objects)
|
|
46
50
|
// 是否追加属性(针对对象)
|
|
47
51
|
inheritMissing?: boolean;
|
|
@@ -136,6 +140,10 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
|
|
|
136
140
|
// target是{}类型时,是否允许合并key=symbol的键值对。
|
|
137
141
|
useSymbol: true,
|
|
138
142
|
|
|
143
|
+
nullBehavior:'preserve',
|
|
144
|
+
|
|
145
|
+
undefinedBehavior:'preserve',
|
|
146
|
+
|
|
139
147
|
// Options passed to the deepClone function when targetClone is true
|
|
140
148
|
// 当targetClone为true时传递给deepClone函数的选项
|
|
141
149
|
deepClone: {},
|
|
@@ -230,18 +238,38 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
|
|
|
230
238
|
result = options.targetClone ? shallowCopy(target) : target;
|
|
231
239
|
|
|
232
240
|
for (let k in source) {
|
|
241
|
+
const _result = (result as any)[k],
|
|
242
|
+
_source = source[k];
|
|
233
243
|
if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
|
|
234
244
|
|
|
235
|
-
|
|
245
|
+
const resp = smartMerger(_result, _source, { ...opts, parent: result });
|
|
236
246
|
//resp={result,flag,type}
|
|
237
|
-
//flag=true
|
|
247
|
+
//flag=true表示类型一致(object/array/map/set)并完成了合并,false表示并没有合并需要直接赋值
|
|
238
248
|
if (!resp.flag) {
|
|
239
249
|
//类型不同则直接覆盖
|
|
240
|
-
|
|
241
|
-
|
|
250
|
+
let tmp = options.useEnable ? mergeEnableObject(_result, _source) : _source;
|
|
251
|
+
if (_result !== tmp && tmp === null) {
|
|
252
|
+
if (options.nullBehavior === 'ignore') {
|
|
253
|
+
//不处理
|
|
254
|
+
} else if (options.nullBehavior === 'delete') {
|
|
255
|
+
//删除属性
|
|
256
|
+
Reflect.deleteProperty(result, k);
|
|
257
|
+
} else {
|
|
258
|
+
//替换
|
|
259
|
+
(result as any)[k] = tmp;
|
|
260
|
+
}
|
|
261
|
+
} else if (_result !== tmp && tmp === undefined) {
|
|
262
|
+
if (options.undefinedBehavior === 'ignore') {
|
|
263
|
+
//不处理
|
|
264
|
+
} else if (options.undefinedBehavior === 'delete') {
|
|
265
|
+
//删除属性
|
|
266
|
+
Reflect.deleteProperty(result, k);
|
|
267
|
+
} else {
|
|
268
|
+
//替换
|
|
269
|
+
(result as any)[k] = _source;
|
|
270
|
+
}
|
|
242
271
|
} else {
|
|
243
|
-
|
|
244
|
-
(result as any)[k] = source[k];
|
|
272
|
+
(result as any)[k] = _source;
|
|
245
273
|
}
|
|
246
274
|
} else {
|
|
247
275
|
//类型相同
|
|
@@ -252,13 +280,13 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
|
|
|
252
280
|
}
|
|
253
281
|
} else {
|
|
254
282
|
//其他类型则直接覆盖
|
|
255
|
-
(result as any)[k] =
|
|
283
|
+
(result as any)[k] = _source;
|
|
256
284
|
}
|
|
257
285
|
}
|
|
258
286
|
|
|
259
287
|
} else if (source.hasOwnProperty(k) && !result.hasOwnProperty(k) && options.inheritMissing) {
|
|
260
288
|
//如果source有属性,result没有该属性,但是options允许追加属性则直接赋值
|
|
261
|
-
(result as any)[k] =
|
|
289
|
+
(result as any)[k] = _source;
|
|
262
290
|
}
|
|
263
291
|
}
|
|
264
292
|
//Symbol键直接追加,因为Symbol是唯一,结果同Object.assign
|
package/src/getEl.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/05 10:28:14
|
|
3
|
+
* @function getEl
|
|
4
|
+
* @description Get a DOM node (real or virtual). Supports obtaining nodes from various types (not just HTMLElement).
|
|
5
|
+
* @param {string|Node} obj - Can be a node selector (e.g., #id, .classname, NODENAME, [attribute]) or any node type (HTMLElement, Node, DocumentFragment, etc.).
|
|
6
|
+
* @param {Node|string} wrap - Parent node (or selector) from which to get the sub-node. Defaults to document.body.
|
|
7
|
+
* @returns {Node|null} Returns the matching node or null if not found.
|
|
8
|
+
* @example
|
|
9
|
+
* ax.getEl('#demo');
|
|
10
|
+
* <!-- returns a DOM node -->
|
|
11
|
+
*/
|
|
12
|
+
//简介:获得一个节点。支持获得一个真实节点或虚拟节点
|
|
13
|
+
//参数obj:可以是#id、.className、NODENAME、[attribute]等节点选择器或节点
|
|
14
|
+
//参数parent:父节点,从该节点获取子节点,默认document.body
|
|
15
|
+
//返回:一个节点或null
|
|
16
|
+
'use strict';
|
|
17
|
+
import getDataType from './getDataType';
|
|
18
|
+
const getEl = (obj, wrap = document.body) => {
|
|
19
|
+
let objType = getDataType(obj), parType = getDataType(wrap), parent = parType.includes('HTML') ? wrap : document.querySelector(wrap),
|
|
20
|
+
//如果parent是template节点,需要通过node.content.querySelector取得子节点
|
|
21
|
+
root = parent && parent instanceof HTMLTemplateElement ? parent.content : parent, result = null;
|
|
22
|
+
if (obj) {
|
|
23
|
+
if (objType.includes('HTML')) {
|
|
24
|
+
result = obj;
|
|
25
|
+
}
|
|
26
|
+
else if (objType === 'String') {
|
|
27
|
+
try {
|
|
28
|
+
result = (root || document).querySelector(obj.trim());
|
|
29
|
+
//可能会报错,报错则返回null
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
result = null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
export default getEl;
|
package/src/getEl.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/05 10:28:14
|
|
3
|
+
* @function getEl
|
|
4
|
+
* @description Get a DOM node (real or virtual). Supports obtaining nodes from various types (not just HTMLElement).
|
|
5
|
+
* @param {string|Node} obj - Can be a node selector (e.g., #id, .classname, NODENAME, [attribute]) or any node type (HTMLElement, Node, DocumentFragment, etc.).
|
|
6
|
+
* @param {Node|string} wrap - Parent node (or selector) from which to get the sub-node. Defaults to document.body.
|
|
7
|
+
* @returns {Node|null} Returns the matching node or null if not found.
|
|
8
|
+
* @example
|
|
9
|
+
* ax.getEl('#demo');
|
|
10
|
+
* <!-- returns a DOM node -->
|
|
11
|
+
*/
|
|
12
|
+
//简介:获得一个节点。支持获得一个真实节点或虚拟节点
|
|
13
|
+
//参数obj:可以是#id、.className、NODENAME、[attribute]等节点选择器或节点
|
|
14
|
+
//参数parent:父节点,从该节点获取子节点,默认document.body
|
|
15
|
+
//返回:一个节点或null
|
|
16
|
+
'use strict';
|
|
17
|
+
import getDataType from './getDataType';
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const getEl = (obj: string | Node | null, wrap: Node | string | null = document.body): Node | null => {
|
|
21
|
+
let objType = getDataType(obj),
|
|
22
|
+
parType = getDataType(wrap),
|
|
23
|
+
parent = parType.includes('HTML') ? wrap : document.querySelector(wrap as string),
|
|
24
|
+
//如果parent是template节点,需要通过node.content.querySelector取得子节点
|
|
25
|
+
root = parent && parent instanceof HTMLTemplateElement ? parent.content : parent,
|
|
26
|
+
result: Node | null = null;
|
|
27
|
+
if (obj) {
|
|
28
|
+
if (objType.includes('HTML')) {
|
|
29
|
+
result = (obj as Node);
|
|
30
|
+
} else if (objType === 'String') {
|
|
31
|
+
try {
|
|
32
|
+
result = (((root as Node) || document) as any).querySelector((obj as string).trim());
|
|
33
|
+
//可能会报错,报错则返回null
|
|
34
|
+
} catch {
|
|
35
|
+
result = null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
export default getEl;
|
package/src/getEls.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/05 10:29:34
|
|
3
|
+
* @function getEls
|
|
4
|
+
* @description Get the node array.
|
|
5
|
+
* @param {*} data - It can be a single node selector or a node array.
|
|
6
|
+
* @param {HTMLElement} parent - Parent node, get sub-node from this node, default document.body
|
|
7
|
+
* @returns {array} Return a node array.
|
|
8
|
+
* @example
|
|
9
|
+
* ax.getEls('#demo');
|
|
10
|
+
* <!--return [node]-->
|
|
11
|
+
* ax.getEls('#demo1,#demo2,#demo3');
|
|
12
|
+
* <!--return [node1,node2,node3]-->
|
|
13
|
+
* ax.getEls(['#demo1','#demo2,'#demo3']);
|
|
14
|
+
* <!--return [node1,node2,node3]-->
|
|
15
|
+
*/
|
|
16
|
+
//简介:获得节点数组。
|
|
17
|
+
//参数data:可以单个节点选择器,使用方法同getEl,也可以是以“,”分隔的多个选择器,也可以节点数组。
|
|
18
|
+
//参数parent:父节点,从该节点获取子节点,默认document。
|
|
19
|
+
//返回:一个节点数组。
|
|
20
|
+
'use strict';
|
|
21
|
+
import getDataType from './getDataType';
|
|
22
|
+
import getEl from './getEl';
|
|
23
|
+
import isEmpty from './isEmpty';
|
|
24
|
+
const getEls = (data, parent = document.body) => {
|
|
25
|
+
let type = getDataType(data), parentEl = getEl(parent), root = parentEl && parentEl instanceof HTMLTemplateElement ? parentEl.content : (parentEl || document), result = [];
|
|
26
|
+
//data为空直接返回空数组
|
|
27
|
+
if (isEmpty(data)) {
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
if (type.includes('HTML')) {
|
|
31
|
+
//一个节点
|
|
32
|
+
result.push(data);
|
|
33
|
+
}
|
|
34
|
+
else if (type === 'String') {
|
|
35
|
+
data = data.trim();
|
|
36
|
+
//以英文逗号作为节点选择器分隔符
|
|
37
|
+
result = data.split(',').map((k) => {
|
|
38
|
+
return [...root.querySelectorAll(k)];
|
|
39
|
+
}).flat();
|
|
40
|
+
}
|
|
41
|
+
else if (type === 'Array') {
|
|
42
|
+
result = data.map((k) => {
|
|
43
|
+
return getEl(k, parentEl);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return result.filter(Boolean);
|
|
47
|
+
};
|
|
48
|
+
export default getEls;
|
package/src/getEls.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/01/05 10:29:34
|
|
3
|
+
* @function getEls
|
|
4
|
+
* @description Get the node array.
|
|
5
|
+
* @param {*} data - It can be a single node selector or a node array.
|
|
6
|
+
* @param {HTMLElement} parent - Parent node, get sub-node from this node, default document.body
|
|
7
|
+
* @returns {array} Return a node array.
|
|
8
|
+
* @example
|
|
9
|
+
* ax.getEls('#demo');
|
|
10
|
+
* <!--return [node]-->
|
|
11
|
+
* ax.getEls('#demo1,#demo2,#demo3');
|
|
12
|
+
* <!--return [node1,node2,node3]-->
|
|
13
|
+
* ax.getEls(['#demo1','#demo2,'#demo3']);
|
|
14
|
+
* <!--return [node1,node2,node3]-->
|
|
15
|
+
*/
|
|
16
|
+
//简介:获得节点数组。
|
|
17
|
+
//参数data:可以单个节点选择器,使用方法同getEl,也可以是以“,”分隔的多个选择器,也可以节点数组。
|
|
18
|
+
//参数parent:父节点,从该节点获取子节点,默认document。
|
|
19
|
+
//返回:一个节点数组。
|
|
20
|
+
'use strict';
|
|
21
|
+
import getDataType from './getDataType';
|
|
22
|
+
import getEl from './getEl';
|
|
23
|
+
import isEmpty from './isEmpty';
|
|
24
|
+
|
|
25
|
+
const getEls = (data: Node | string | null | (Node | string)[], parent: Node | string | null = document.body): (Node | string)[] => {
|
|
26
|
+
let type = getDataType(data),
|
|
27
|
+
parentEl = getEl(parent),
|
|
28
|
+
root = parentEl && parentEl instanceof HTMLTemplateElement ? parentEl.content : (parentEl || document),
|
|
29
|
+
result: any[] = [];
|
|
30
|
+
//data为空直接返回空数组
|
|
31
|
+
if (isEmpty(data)) { return result; }
|
|
32
|
+
if (type.includes('HTML')) {
|
|
33
|
+
//一个节点
|
|
34
|
+
result.push(data);
|
|
35
|
+
} else if (type === 'String') {
|
|
36
|
+
data = (data as string).trim();
|
|
37
|
+
//以英文逗号作为节点选择器分隔符
|
|
38
|
+
result = data.split(',').map((k: any) => {
|
|
39
|
+
return [...(root as any).querySelectorAll(k)];
|
|
40
|
+
}).flat();
|
|
41
|
+
} else if (type === 'Array') {
|
|
42
|
+
result = (data as (Node | string)[]).map((k: any) => {
|
|
43
|
+
return getEl(k, parentEl);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return result.filter(Boolean);
|
|
47
|
+
}
|
|
48
|
+
export default getEls;
|