@codady/utils 0.0.18 → 0.0.20

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 CHANGED
@@ -3,6 +3,25 @@
3
3
  All changes to Utils including new features, updates, and removals are documented here.
4
4
 
5
5
 
6
+
7
+ ## [v0.0.19] - 2025-1-5
8
+
9
+ ### Distribution Files
10
+ * **JS**: https://unpkg.com/@codady/utils@0.0.19/dist/js/utils.js
11
+ * **Zip**:https://unpkg.com/@codady/utils@0.0.19/dist.zip
12
+
13
+ ### Changes
14
+
15
+ #### Fixed
16
+ * Null
17
+
18
+ #### Added
19
+ * Added the functions `getEl`, `getEls`, and `createEl`.新增`getEl`、`getEls`和`ceateEl`函数。
20
+
21
+
22
+ #### Removed
23
+ * Null
24
+
6
25
  ## [v0.0.18] - 2025-12-27
7
26
 
8
27
  ### Distribution Files
package/dist/utils.cjs.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2025-12-27 14:35:7
3
+ * @since Last modified: 2026-1-5 10:51:1
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.18
5
+ * @version 0.0.20
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -761,6 +761,146 @@ const deepMerge = (target, source, opts = {}) => {
761
761
  return smartMerger(target, source, options).result;
762
762
  };
763
763
 
764
+ const getEl = (obj, wrap = document.body) => {
765
+ let objType = getDataType(obj), parType = getDataType(wrap), parent = parType.includes('HTML') ? wrap : document.querySelector(wrap),
766
+ //如果parent是template节点,需要通过node.content.querySelector取得子节点
767
+ root = parent && parent instanceof HTMLTemplateElement ? parent.content : parent, result = null;
768
+ if (obj) {
769
+ if (objType.includes('HTML')) {
770
+ result = obj;
771
+ }
772
+ else if (objType === 'String') {
773
+ try {
774
+ result = (root || document).querySelector(obj.trim());
775
+ //可能会报错,报错则返回null
776
+ }
777
+ catch {
778
+ result = null;
779
+ }
780
+ }
781
+ }
782
+ return result;
783
+ };
784
+
785
+ const isEmpty = (data) => {
786
+ let type = getDataType(data), flag;
787
+ if (!data) {
788
+ //0,'',false,undefined,null
789
+ flag = true;
790
+ }
791
+ else {
792
+ //function(){}|()=>{}
793
+ //[null]|[undefined]|['']|[""]
794
+ //[]|{}
795
+ //Symbol()|Symbol.for()
796
+ //Set,Map
797
+ //Date/Regex
798
+ flag = (type === 'Object') ? (Object.keys(data).length === 0) :
799
+ (type === 'Array') ? data.join('') === '' :
800
+ (type === 'Function') ? (data.toString().replace(/\s+/g, '').match(/{.*}/g)[0] === '{}') :
801
+ (type === 'Symbol') ? (data.toString().replace(/\s+/g, '').match(/\(.*\)/g)[0] === '()') :
802
+ (type === 'Set' || type === 'Map') ? data.size === 0 :
803
+ type === 'Date' ? isNaN(data.getTime()) :
804
+ type === 'RegExp' ? data.source === '' :
805
+ type === 'ArrayBuffer' ? data.byteLength === 0 :
806
+ (type === 'NodeList' || type === 'HTMLCollection') ? data.length === 0 :
807
+ ('length' in data && typeof data.length === 'number') ? data.length === 0 :
808
+ ('size' in data && typeof data.size === 'number') ? data.size === 0 :
809
+ (type === 'Error' || data instanceof Error) ? data.message === '' :
810
+ (type.includes('Array') && (['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array'].includes(type))) ? data.length === 0 :
811
+ false;
812
+ }
813
+ return flag;
814
+ };
815
+
816
+ const getEls = (data, parent = document.body) => {
817
+ let type = getDataType(data), parentEl = getEl(parent), root = parentEl && parentEl instanceof HTMLTemplateElement ? parentEl.content : (parentEl || document), result = [];
818
+ //data为空直接返回空数组
819
+ if (isEmpty(data)) {
820
+ return result;
821
+ }
822
+ if (type.includes('HTML')) {
823
+ //一个节点
824
+ result.push(data);
825
+ }
826
+ else if (type === 'String') {
827
+ data = data.trim();
828
+ //以英文逗号作为节点选择器分隔符
829
+ result = data.split(',').map((k) => {
830
+ return [...root.querySelectorAll(k)];
831
+ }).flat();
832
+ }
833
+ else if (type === 'Array') {
834
+ result = data.map((k) => {
835
+ return getEl(k, parentEl);
836
+ });
837
+ }
838
+ return result.filter(Boolean);
839
+ };
840
+
841
+ const createEl = (name, attrs, content) => {
842
+ //默认为div
843
+ name = name || 'div';
844
+ //统一大小写
845
+ let rootName = name.toUpperCase().trim(), rootEl = document.createElement(rootName), attrsType = getDataType(attrs), loop = (host, data) => {
846
+ if (data === '' || data === null || data === undefined) {
847
+ //为空、未定义则不再执行
848
+ return false;
849
+ }
850
+ let dataType = getDataType(data);
851
+ //template是DocumentFragment类型不能用insertAdjacentHTML
852
+ if (rootName === 'TEMPLATE') {
853
+ host.innerHTML = data.toString();
854
+ }
855
+ else {
856
+ if (dataType === 'Array' && data.length > 0) {
857
+ //节点数组
858
+ //data.forEach((i: T_obj) => loop(el, i));
859
+ for (let k of data) {
860
+ let childType = getDataType(k);
861
+ if (childType.includes('HTML')) {
862
+ //是个节点
863
+ host.appendChild(k);
864
+ }
865
+ else {
866
+ //是个对象{name:'',attrs:{},content:''}
867
+ let child = createEl(k.name, k.attrs, k.content);
868
+ child && host.appendChild(child);
869
+ }
870
+ }
871
+ }
872
+ else if (dataType.includes('HTML')) {
873
+ //HTML节点
874
+ host.appendChild(data);
875
+ }
876
+ else if (dataType === 'String' && data.trim().startsWith('#') && data.trim().length > 1) {
877
+ //是字符串且是#id选择器,则取其文本
878
+ let el = getEl(data);
879
+ if (!el)
880
+ return;
881
+ //如果是template模板节点则需要特殊处理
882
+ el.nodeName === 'TEMPLATE' ? host.appendChild(el.content.cloneNode(true)) : host.insertAdjacentHTML('beforeEnd', el.innerHTML);
883
+ }
884
+ else {
885
+ //字符串数字等
886
+ host.insertAdjacentHTML('beforeEnd', data);
887
+ }
888
+ }
889
+ };
890
+ //添加属性
891
+ if (attrs && attrsType === 'Object') {
892
+ for (let k in attrs) {
893
+ //注意,attrs[k]可能是一个{}或[],不一定是字符串
894
+ // JSON.stringify可以将所有格式的数据都转成文本,会忽略函数和节点数据
895
+ //字符串则不需要stringify,否则会将字符串的引号也一并输出
896
+ attrs.hasOwnProperty(k) && rootEl.setAttribute(k, typeof attrs[k] === 'string' ? attrs[k] : JSON.stringify(attrs[k]));
897
+ }
898
+ }
899
+ //执行循环创建子节点
900
+ loop(rootEl, content);
901
+ return rootEl;
902
+ };
903
+
764
904
  const utils = {
765
905
  //executeStr,
766
906
  getDataType,
@@ -779,6 +919,9 @@ const utils = {
779
919
  deepMerge,
780
920
  shallowCopy,
781
921
  copyObjectWithSymbol,
922
+ getEl,
923
+ getEls,
924
+ createEl,
782
925
  };
783
926
 
784
927
  module.exports = utils;
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-27 14:35:7
2
+ * @since Last modified: 2026-1-5 10:51:1
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.18
4
+ * @version 0.0.20
5
5
  * @author AXUI development team <3217728223@qq.com>
6
6
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
7
7
  * @see {@link https://www.axui.cn|Official website}
@@ -12,4 +12,4 @@
12
12
  * @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
13
13
  * @license MIT license
14
14
  */
15
- "use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let o,n=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...a,parent:e});o=t}else if("Array"===r&&a.cloneArray)o=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,a),deepClone(o,{...a,parent:e}));o=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));o=t}else if("Date"===r&&a.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,n=!1;return a.onAfterClone?.({output:o,input:e,type:r,cloned:n,parent:a.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:o={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const n={};for(let s of a)n[s]=function(...a){const n={},l=e.length;switch(s){case"push":case"unshift":n.addedItems=[...a];break;case"pop":n.poppedItem=e[l-1];break;case"shift":n.shiftedItem=e[0];break;case"splice":const[t,r]=a,o=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-o:r;n.deletedItems=e.slice(o,o+s);break;case"sort":case"reverse":n.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,p=void 0===a[2]?l:a[2];n.oldItems=e.slice(i,p),n.start=i,n.end=p}t?.(n);const i=Array.prototype[s].apply(e,a),p={value:i,key:s,args:a,context:n,target:e,...o};return r?.(p),i};return n},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],o=getDataType(e),n=o.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=n.includes("html")?"element":n;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,o)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return o},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:o={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"add":{const[t]=n;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=n;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:o={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"set":{const[t,r]=n;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=n;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let o,n,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(n=deepMergeObjects(e,t,a),o="Object"):"Array"===s&&"Array"===l?(n=deepMergeArrays(e,t,a),o="Array"):"Set"===s&&"Set"===l?(n=deepMergeSets(e,t,a),o="Set"):"Map"===s&&"Map"===l?(n=deepMergeMaps(e,t,a),o="Map"):(i=!1,n=e),a?.onAfterMerge?.({result:n,target:e,source:t,targetType:s,sourceType:l,mergeType:o,parent:r.parent}),{result:n,flag:i,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),o=getDataType(t);if("Object"!==a||"Object"!==o)return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=n.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],o=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,o,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=o;else{let t=n.useEnable?mergeEnableObject(a,o):o;a!==t&&null===t?"ignore"===n.nullBehavior||("delete"===n.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===n.undefinedBehavior||("delete"===n.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=o):s[e]=o}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&n.inheritMissing&&(s[e]=o)}if(n.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...a,parent:o}).flag||(o[e]=t[e])}else"concat"===a.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Map([...e]):e;for(const[e,n]of t.entries())if(o.has(e)){const t=o.get(e),r=n,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,n);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...o],r=[...t],n=smartMerger(e,r,a);o.clear();for(let e of n.result)o.add(e)}else if("concat"===a.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,a).result},utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol};module.exports=utils;
15
+ "use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let n,o=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const n of r)t[n]=deepClone(e[n],{...a,parent:e});n=t}else if("Array"===r&&a.cloneArray)n=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,a),deepClone(n,{...a,parent:e}));n=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));n=t}else if("Date"===r&&a.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,o=!1;return a.onAfterClone?.({output:n,input:e,type:r,cloned:o,parent:a.parent}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:n={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const o={};for(let s of a)o[s]=function(...a){const o={},l=e.length;switch(s){case"push":case"unshift":o.addedItems=[...a];break;case"pop":o.poppedItem=e[l-1];break;case"shift":o.shiftedItem=e[0];break;case"splice":const[t,r]=a,n=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-n:r;o.deletedItems=e.slice(n,n+s);break;case"sort":case"reverse":o.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,c=void 0===a[2]?l:a[2];o.oldItems=e.slice(i,c),o.start=i,o.end=c}t?.(o);const i=Array.prototype[s].apply(e,a),c={value:i,key:s,args:a,context:o,target:e,...n};return r?.(c),i};return o},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],n=getDataType(e),o=n.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=o.includes("html")?"element":o;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,n)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return n},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:n={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:n={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let n,o,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(o=deepMergeObjects(e,t,a),n="Object"):"Array"===s&&"Array"===l?(o=deepMergeArrays(e,t,a),n="Array"):"Set"===s&&"Set"===l?(o=deepMergeSets(e,t,a),n="Set"):"Map"===s&&"Map"===l?(o=deepMergeMaps(e,t,a),n="Map"):(i=!1,o=e),a?.onAfterMerge?.({result:o,target:e,source:t,targetType:s,sourceType:l,mergeType:n,parent:r.parent}),{result:o,flag:i,mergeType:n}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),n=getDataType(t);if("Object"!==a||"Object"!==n)return e;const o=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=o.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],n=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,n,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=n;else{let t=o.useEnable?mergeEnableObject(a,n):n;a!==t&&null===t?"ignore"===o.nullBehavior||("delete"===o.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===o.undefinedBehavior||("delete"===o.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=n):s[e]=n}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&o.inheritMissing&&(s[e]=n)}if(o.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),n=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=n.length));e++){smartMerger(n[e],t[e],{...a,parent:n}).flag||(n[e]=t[e])}else"concat"===a.dataMode||(n.length=0),n.push(...t);return n},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Map([...e]):e;for(const[e,o]of t.entries())if(n.has(e)){const t=n.get(e),r=o,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&n.set(e,s.result):n.set(e,r)}else r.inheritMissing&&n.set(e,o);return n},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...n],r=[...t],o=smartMerger(e,r,a);n.clear();for(let e of o.result)n.add(e)}else if("concat"===a.dataMode)for(let e of t)n.add(e);else{n.clear();for(let e of t)n.add(e)}return n};return smartMerger(e,t,a).result},getEl=(e,t=document.body)=>{let r=getDataType(e),a=getDataType(t).includes("HTML")?t:document.querySelector(t),n=a&&a instanceof HTMLTemplateElement?a.content:a,o=null;if(e)if(r.includes("HTML"))o=e;else if("String"===r)try{o=(n||document).querySelector(e.trim())}catch{o=null}return o},isEmpty=e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t},getEls=(e,t=document.body)=>{let r=getDataType(e),a=getEl(t),n=a&&a instanceof HTMLTemplateElement?a.content:a||document,o=[];return isEmpty(e)?o:(r.includes("HTML")?o.push(e):"String"===r?o=(e=e.trim()).split(",").map(e=>[...n.querySelectorAll(e)]).flat():"Array"===r&&(o=e.map(e=>getEl(e,a))),o.filter(Boolean))},createEl=(e,t,r)=>{let a=(e=e||"div").toUpperCase().trim(),n=document.createElement(a),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&n.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===a)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(n,r),n},utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:getEls,createEl:createEl};module.exports=utils;
package/dist/utils.esm.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2025-12-27 14:35:7
3
+ * @since Last modified: 2026-1-5 10:51:1
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.18
5
+ * @version 0.0.20
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -759,6 +759,146 @@ const deepMerge = (target, source, opts = {}) => {
759
759
  return smartMerger(target, source, options).result;
760
760
  };
761
761
 
762
+ const getEl = (obj, wrap = document.body) => {
763
+ let objType = getDataType(obj), parType = getDataType(wrap), parent = parType.includes('HTML') ? wrap : document.querySelector(wrap),
764
+ //如果parent是template节点,需要通过node.content.querySelector取得子节点
765
+ root = parent && parent instanceof HTMLTemplateElement ? parent.content : parent, result = null;
766
+ if (obj) {
767
+ if (objType.includes('HTML')) {
768
+ result = obj;
769
+ }
770
+ else if (objType === 'String') {
771
+ try {
772
+ result = (root || document).querySelector(obj.trim());
773
+ //可能会报错,报错则返回null
774
+ }
775
+ catch {
776
+ result = null;
777
+ }
778
+ }
779
+ }
780
+ return result;
781
+ };
782
+
783
+ const isEmpty = (data) => {
784
+ let type = getDataType(data), flag;
785
+ if (!data) {
786
+ //0,'',false,undefined,null
787
+ flag = true;
788
+ }
789
+ else {
790
+ //function(){}|()=>{}
791
+ //[null]|[undefined]|['']|[""]
792
+ //[]|{}
793
+ //Symbol()|Symbol.for()
794
+ //Set,Map
795
+ //Date/Regex
796
+ flag = (type === 'Object') ? (Object.keys(data).length === 0) :
797
+ (type === 'Array') ? data.join('') === '' :
798
+ (type === 'Function') ? (data.toString().replace(/\s+/g, '').match(/{.*}/g)[0] === '{}') :
799
+ (type === 'Symbol') ? (data.toString().replace(/\s+/g, '').match(/\(.*\)/g)[0] === '()') :
800
+ (type === 'Set' || type === 'Map') ? data.size === 0 :
801
+ type === 'Date' ? isNaN(data.getTime()) :
802
+ type === 'RegExp' ? data.source === '' :
803
+ type === 'ArrayBuffer' ? data.byteLength === 0 :
804
+ (type === 'NodeList' || type === 'HTMLCollection') ? data.length === 0 :
805
+ ('length' in data && typeof data.length === 'number') ? data.length === 0 :
806
+ ('size' in data && typeof data.size === 'number') ? data.size === 0 :
807
+ (type === 'Error' || data instanceof Error) ? data.message === '' :
808
+ (type.includes('Array') && (['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array'].includes(type))) ? data.length === 0 :
809
+ false;
810
+ }
811
+ return flag;
812
+ };
813
+
814
+ const getEls = (data, parent = document.body) => {
815
+ let type = getDataType(data), parentEl = getEl(parent), root = parentEl && parentEl instanceof HTMLTemplateElement ? parentEl.content : (parentEl || document), result = [];
816
+ //data为空直接返回空数组
817
+ if (isEmpty(data)) {
818
+ return result;
819
+ }
820
+ if (type.includes('HTML')) {
821
+ //一个节点
822
+ result.push(data);
823
+ }
824
+ else if (type === 'String') {
825
+ data = data.trim();
826
+ //以英文逗号作为节点选择器分隔符
827
+ result = data.split(',').map((k) => {
828
+ return [...root.querySelectorAll(k)];
829
+ }).flat();
830
+ }
831
+ else if (type === 'Array') {
832
+ result = data.map((k) => {
833
+ return getEl(k, parentEl);
834
+ });
835
+ }
836
+ return result.filter(Boolean);
837
+ };
838
+
839
+ const createEl = (name, attrs, content) => {
840
+ //默认为div
841
+ name = name || 'div';
842
+ //统一大小写
843
+ let rootName = name.toUpperCase().trim(), rootEl = document.createElement(rootName), attrsType = getDataType(attrs), loop = (host, data) => {
844
+ if (data === '' || data === null || data === undefined) {
845
+ //为空、未定义则不再执行
846
+ return false;
847
+ }
848
+ let dataType = getDataType(data);
849
+ //template是DocumentFragment类型不能用insertAdjacentHTML
850
+ if (rootName === 'TEMPLATE') {
851
+ host.innerHTML = data.toString();
852
+ }
853
+ else {
854
+ if (dataType === 'Array' && data.length > 0) {
855
+ //节点数组
856
+ //data.forEach((i: T_obj) => loop(el, i));
857
+ for (let k of data) {
858
+ let childType = getDataType(k);
859
+ if (childType.includes('HTML')) {
860
+ //是个节点
861
+ host.appendChild(k);
862
+ }
863
+ else {
864
+ //是个对象{name:'',attrs:{},content:''}
865
+ let child = createEl(k.name, k.attrs, k.content);
866
+ child && host.appendChild(child);
867
+ }
868
+ }
869
+ }
870
+ else if (dataType.includes('HTML')) {
871
+ //HTML节点
872
+ host.appendChild(data);
873
+ }
874
+ else if (dataType === 'String' && data.trim().startsWith('#') && data.trim().length > 1) {
875
+ //是字符串且是#id选择器,则取其文本
876
+ let el = getEl(data);
877
+ if (!el)
878
+ return;
879
+ //如果是template模板节点则需要特殊处理
880
+ el.nodeName === 'TEMPLATE' ? host.appendChild(el.content.cloneNode(true)) : host.insertAdjacentHTML('beforeEnd', el.innerHTML);
881
+ }
882
+ else {
883
+ //字符串数字等
884
+ host.insertAdjacentHTML('beforeEnd', data);
885
+ }
886
+ }
887
+ };
888
+ //添加属性
889
+ if (attrs && attrsType === 'Object') {
890
+ for (let k in attrs) {
891
+ //注意,attrs[k]可能是一个{}或[],不一定是字符串
892
+ // JSON.stringify可以将所有格式的数据都转成文本,会忽略函数和节点数据
893
+ //字符串则不需要stringify,否则会将字符串的引号也一并输出
894
+ attrs.hasOwnProperty(k) && rootEl.setAttribute(k, typeof attrs[k] === 'string' ? attrs[k] : JSON.stringify(attrs[k]));
895
+ }
896
+ }
897
+ //执行循环创建子节点
898
+ loop(rootEl, content);
899
+ return rootEl;
900
+ };
901
+
762
902
  const utils = {
763
903
  //executeStr,
764
904
  getDataType,
@@ -777,6 +917,9 @@ const utils = {
777
917
  deepMerge,
778
918
  shallowCopy,
779
919
  copyObjectWithSymbol,
920
+ getEl,
921
+ getEls,
922
+ createEl,
780
923
  };
781
924
 
782
925
  export { utils as default };
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-27 14:35:7
2
+ * @since Last modified: 2026-1-5 10:51:1
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.18
4
+ * @version 0.0.20
5
5
  * @author AXUI development team <3217728223@qq.com>
6
6
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
7
7
  * @see {@link https://www.axui.cn|Official website}
@@ -12,4 +12,4 @@
12
12
  * @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
13
13
  * @license MIT license
14
14
  */
15
- const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let o,n=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...a,parent:e});o=t}else if("Array"===r&&a.cloneArray)o=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,a),deepClone(o,{...a,parent:e}));o=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));o=t}else if("Date"===r&&a.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,n=!1;return a.onAfterClone?.({output:o,input:e,type:r,cloned:n,parent:a.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:o={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const n={};for(let s of a)n[s]=function(...a){const n={},l=e.length;switch(s){case"push":case"unshift":n.addedItems=[...a];break;case"pop":n.poppedItem=e[l-1];break;case"shift":n.shiftedItem=e[0];break;case"splice":const[t,r]=a,o=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-o:r;n.deletedItems=e.slice(o,o+s);break;case"sort":case"reverse":n.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,p=void 0===a[2]?l:a[2];n.oldItems=e.slice(i,p),n.start=i,n.end=p}t?.(n);const i=Array.prototype[s].apply(e,a),p={value:i,key:s,args:a,context:n,target:e,...o};return r?.(p),i};return n},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],o=getDataType(e),n=o.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=n.includes("html")?"element":n;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,o)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return o},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:o={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"add":{const[t]=n;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=n;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:o={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"set":{const[t,r]=n;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=n;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let o,n,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(n=deepMergeObjects(e,t,a),o="Object"):"Array"===s&&"Array"===l?(n=deepMergeArrays(e,t,a),o="Array"):"Set"===s&&"Set"===l?(n=deepMergeSets(e,t,a),o="Set"):"Map"===s&&"Map"===l?(n=deepMergeMaps(e,t,a),o="Map"):(i=!1,n=e),a?.onAfterMerge?.({result:n,target:e,source:t,targetType:s,sourceType:l,mergeType:o,parent:r.parent}),{result:n,flag:i,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),o=getDataType(t);if("Object"!==a||"Object"!==o)return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=n.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],o=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,o,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=o;else{let t=n.useEnable?mergeEnableObject(a,o):o;a!==t&&null===t?"ignore"===n.nullBehavior||("delete"===n.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===n.undefinedBehavior||("delete"===n.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=o):s[e]=o}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&n.inheritMissing&&(s[e]=o)}if(n.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...a,parent:o}).flag||(o[e]=t[e])}else"concat"===a.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Map([...e]):e;for(const[e,n]of t.entries())if(o.has(e)){const t=o.get(e),r=n,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,n);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...o],r=[...t],n=smartMerger(e,r,a);o.clear();for(let e of n.result)o.add(e)}else if("concat"===a.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,a).result},utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol};export{utils as default};
15
+ const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let n,o=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const n of r)t[n]=deepClone(e[n],{...a,parent:e});n=t}else if("Array"===r&&a.cloneArray)n=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,a),deepClone(n,{...a,parent:e}));n=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));n=t}else if("Date"===r&&a.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,o=!1;return a.onAfterClone?.({output:n,input:e,type:r,cloned:o,parent:a.parent}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:n={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const o={};for(let s of a)o[s]=function(...a){const o={},l=e.length;switch(s){case"push":case"unshift":o.addedItems=[...a];break;case"pop":o.poppedItem=e[l-1];break;case"shift":o.shiftedItem=e[0];break;case"splice":const[t,r]=a,n=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-n:r;o.deletedItems=e.slice(n,n+s);break;case"sort":case"reverse":o.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=a[1]||0,c=void 0===a[2]?l:a[2];o.oldItems=e.slice(i,c),o.start=i,o.end=c}t?.(o);const i=Array.prototype[s].apply(e,a),c={value:i,key:s,args:a,context:o,target:e,...n};return r?.(c),i};return o},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],n=getDataType(e),o=n.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=o.includes("html")?"element":o;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,n)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return n},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:n={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)setMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:n={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const o={},createWrappedMethod=a=>function(...o){const s={};switch(a){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,o),i={method:a,result:l,args:o,context:s,target:e,...n};return r(i),l};for(const e of a)mapMutableMethods.includes(e)&&(o[e]=createWrappedMethod(e));return Object.defineProperty(o,"target",{get:()=>e,enumerable:!1,configurable:!1}),o},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let n,o,s=getDataType(e),l=getDataType(t),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(o=deepMergeObjects(e,t,a),n="Object"):"Array"===s&&"Array"===l?(o=deepMergeArrays(e,t,a),n="Array"):"Set"===s&&"Set"===l?(o=deepMergeSets(e,t,a),n="Set"):"Map"===s&&"Map"===l?(o=deepMergeMaps(e,t,a),n="Map"):(i=!1,o=e),a?.onAfterMerge?.({result:o,target:e,source:t,targetType:s,sourceType:l,mergeType:n,parent:r.parent}),{result:o,flag:i,mergeType:n}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),n=getDataType(t);if("Object"!==a||"Object"!==n)return e;const o=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=o.targetClone?shallowCopy(e):e;for(let e in t){const a=s[e],n=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(a,n,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=n;else{let t=o.useEnable?mergeEnableObject(a,n):n;a!==t&&null===t?"ignore"===o.nullBehavior||("delete"===o.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):a!==t&&void 0===t?"ignore"===o.undefinedBehavior||("delete"===o.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=n):s[e]=n}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&o.inheritMissing&&(s[e]=n)}if(o.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),n=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=n.length));e++){smartMerger(n[e],t[e],{...a,parent:n}).flag||(n[e]=t[e])}else"concat"===a.dataMode||(n.length=0),n.push(...t);return n},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Map([...e]):e;for(const[e,o]of t.entries())if(n.has(e)){const t=n.get(e),r=o,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&n.set(e,s.result):n.set(e,r)}else r.inheritMissing&&n.set(e,o);return n},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),n=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...n],r=[...t],o=smartMerger(e,r,a);n.clear();for(let e of o.result)n.add(e)}else if("concat"===a.dataMode)for(let e of t)n.add(e);else{n.clear();for(let e of t)n.add(e)}return n};return smartMerger(e,t,a).result},getEl=(e,t=document.body)=>{let r=getDataType(e),a=getDataType(t).includes("HTML")?t:document.querySelector(t),n=a&&a instanceof HTMLTemplateElement?a.content:a,o=null;if(e)if(r.includes("HTML"))o=e;else if("String"===r)try{o=(n||document).querySelector(e.trim())}catch{o=null}return o},isEmpty=e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t},getEls=(e,t=document.body)=>{let r=getDataType(e),a=getEl(t),n=a&&a instanceof HTMLTemplateElement?a.content:a||document,o=[];return isEmpty(e)?o:(r.includes("HTML")?o.push(e):"String"===r?o=(e=e.trim()).split(",").map(e=>[...n.querySelectorAll(e)]).flat():"Array"===r&&(o=e.map(e=>getEl(e,a))),o.filter(Boolean))},createEl=(e,t,r)=>{let a=(e=e||"div").toUpperCase().trim(),n=document.createElement(a),o=getDataType(t);if(t&&"Object"===o)for(let e in t)t.hasOwnProperty(e)&&n.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===a)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(n,r),n},utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:getEls,createEl:createEl};export{utils as default};
package/dist/utils.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2025-12-27 14:35:7
3
+ * @since Last modified: 2026-1-5 10:51:1
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.18
5
+ * @version 0.0.20
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -765,6 +765,146 @@
765
765
  return smartMerger(target, source, options).result;
766
766
  };
767
767
 
768
+ const getEl = (obj, wrap = document.body) => {
769
+ let objType = getDataType(obj), parType = getDataType(wrap), parent = parType.includes('HTML') ? wrap : document.querySelector(wrap),
770
+ //如果parent是template节点,需要通过node.content.querySelector取得子节点
771
+ root = parent && parent instanceof HTMLTemplateElement ? parent.content : parent, result = null;
772
+ if (obj) {
773
+ if (objType.includes('HTML')) {
774
+ result = obj;
775
+ }
776
+ else if (objType === 'String') {
777
+ try {
778
+ result = (root || document).querySelector(obj.trim());
779
+ //可能会报错,报错则返回null
780
+ }
781
+ catch {
782
+ result = null;
783
+ }
784
+ }
785
+ }
786
+ return result;
787
+ };
788
+
789
+ const isEmpty = (data) => {
790
+ let type = getDataType(data), flag;
791
+ if (!data) {
792
+ //0,'',false,undefined,null
793
+ flag = true;
794
+ }
795
+ else {
796
+ //function(){}|()=>{}
797
+ //[null]|[undefined]|['']|[""]
798
+ //[]|{}
799
+ //Symbol()|Symbol.for()
800
+ //Set,Map
801
+ //Date/Regex
802
+ flag = (type === 'Object') ? (Object.keys(data).length === 0) :
803
+ (type === 'Array') ? data.join('') === '' :
804
+ (type === 'Function') ? (data.toString().replace(/\s+/g, '').match(/{.*}/g)[0] === '{}') :
805
+ (type === 'Symbol') ? (data.toString().replace(/\s+/g, '').match(/\(.*\)/g)[0] === '()') :
806
+ (type === 'Set' || type === 'Map') ? data.size === 0 :
807
+ type === 'Date' ? isNaN(data.getTime()) :
808
+ type === 'RegExp' ? data.source === '' :
809
+ type === 'ArrayBuffer' ? data.byteLength === 0 :
810
+ (type === 'NodeList' || type === 'HTMLCollection') ? data.length === 0 :
811
+ ('length' in data && typeof data.length === 'number') ? data.length === 0 :
812
+ ('size' in data && typeof data.size === 'number') ? data.size === 0 :
813
+ (type === 'Error' || data instanceof Error) ? data.message === '' :
814
+ (type.includes('Array') && (['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array'].includes(type))) ? data.length === 0 :
815
+ false;
816
+ }
817
+ return flag;
818
+ };
819
+
820
+ const getEls = (data, parent = document.body) => {
821
+ let type = getDataType(data), parentEl = getEl(parent), root = parentEl && parentEl instanceof HTMLTemplateElement ? parentEl.content : (parentEl || document), result = [];
822
+ //data为空直接返回空数组
823
+ if (isEmpty(data)) {
824
+ return result;
825
+ }
826
+ if (type.includes('HTML')) {
827
+ //一个节点
828
+ result.push(data);
829
+ }
830
+ else if (type === 'String') {
831
+ data = data.trim();
832
+ //以英文逗号作为节点选择器分隔符
833
+ result = data.split(',').map((k) => {
834
+ return [...root.querySelectorAll(k)];
835
+ }).flat();
836
+ }
837
+ else if (type === 'Array') {
838
+ result = data.map((k) => {
839
+ return getEl(k, parentEl);
840
+ });
841
+ }
842
+ return result.filter(Boolean);
843
+ };
844
+
845
+ const createEl = (name, attrs, content) => {
846
+ //默认为div
847
+ name = name || 'div';
848
+ //统一大小写
849
+ let rootName = name.toUpperCase().trim(), rootEl = document.createElement(rootName), attrsType = getDataType(attrs), loop = (host, data) => {
850
+ if (data === '' || data === null || data === undefined) {
851
+ //为空、未定义则不再执行
852
+ return false;
853
+ }
854
+ let dataType = getDataType(data);
855
+ //template是DocumentFragment类型不能用insertAdjacentHTML
856
+ if (rootName === 'TEMPLATE') {
857
+ host.innerHTML = data.toString();
858
+ }
859
+ else {
860
+ if (dataType === 'Array' && data.length > 0) {
861
+ //节点数组
862
+ //data.forEach((i: T_obj) => loop(el, i));
863
+ for (let k of data) {
864
+ let childType = getDataType(k);
865
+ if (childType.includes('HTML')) {
866
+ //是个节点
867
+ host.appendChild(k);
868
+ }
869
+ else {
870
+ //是个对象{name:'',attrs:{},content:''}
871
+ let child = createEl(k.name, k.attrs, k.content);
872
+ child && host.appendChild(child);
873
+ }
874
+ }
875
+ }
876
+ else if (dataType.includes('HTML')) {
877
+ //HTML节点
878
+ host.appendChild(data);
879
+ }
880
+ else if (dataType === 'String' && data.trim().startsWith('#') && data.trim().length > 1) {
881
+ //是字符串且是#id选择器,则取其文本
882
+ let el = getEl(data);
883
+ if (!el)
884
+ return;
885
+ //如果是template模板节点则需要特殊处理
886
+ el.nodeName === 'TEMPLATE' ? host.appendChild(el.content.cloneNode(true)) : host.insertAdjacentHTML('beforeEnd', el.innerHTML);
887
+ }
888
+ else {
889
+ //字符串数字等
890
+ host.insertAdjacentHTML('beforeEnd', data);
891
+ }
892
+ }
893
+ };
894
+ //添加属性
895
+ if (attrs && attrsType === 'Object') {
896
+ for (let k in attrs) {
897
+ //注意,attrs[k]可能是一个{}或[],不一定是字符串
898
+ // JSON.stringify可以将所有格式的数据都转成文本,会忽略函数和节点数据
899
+ //字符串则不需要stringify,否则会将字符串的引号也一并输出
900
+ attrs.hasOwnProperty(k) && rootEl.setAttribute(k, typeof attrs[k] === 'string' ? attrs[k] : JSON.stringify(attrs[k]));
901
+ }
902
+ }
903
+ //执行循环创建子节点
904
+ loop(rootEl, content);
905
+ return rootEl;
906
+ };
907
+
768
908
  const utils = {
769
909
  //executeStr,
770
910
  getDataType,
@@ -783,6 +923,9 @@
783
923
  deepMerge,
784
924
  shallowCopy,
785
925
  copyObjectWithSymbol,
926
+ getEl,
927
+ getEls,
928
+ createEl,
786
929
  };
787
930
 
788
931
  return utils;
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-27 14:35:7
2
+ * @since Last modified: 2026-1-5 10:51:1
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.18
4
+ * @version 0.0.20
5
5
  * @author AXUI development team <3217728223@qq.com>
6
6
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
7
7
  * @see {@link https://www.axui.cn|Official website}
@@ -12,4 +12,4 @@
12
12
  * @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
13
13
  * @license MIT license
14
14
  */
15
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),n=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(n.interceptor&&"function"==typeof n.interceptor){let t=n.interceptor({input:e,type:r,parent:n.parent});if(t)return t}n.onBeforeClone?.({input:e,type:r,parent:n.parent});let o,a=!0;if("Object"===r&&n.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],n);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...n,parent:e});o=t}else if("Array"===r&&n.cloneArray)o=e.map(t=>deepClone(t,{...n,parent:e}));else if("Map"===r&&n.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,n),deepClone(o,{...n,parent:e}));o=t}else if("Set"===r&&n.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...n,parent:e}));o=t}else if("Date"===r&&n.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,a=!1;return n.onAfterClone?.({output:o,input:e,type:r,cloned:a,parent:n.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],o=getDataType(e),a=o.toLowerCase(),s=n.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,o)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return o},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=e);const s={};for(let e of o)s[e]=function(...o){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...o];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=o,n=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-n:r;s.deletedItems=t.slice(n,n+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const l=o[1]||0,c=void 0===o[2]?i:o[2];s.oldItems=t.slice(l,c),s.start=l,s.end=c}r?.(s);const l=Array.prototype[e].apply(t,o),c={value:l,key:e,args:o,context:s,target:t,...a};return n?.(c),l};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...o){const s={};switch(t){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}r(s);const i=e[t].apply(e,o),l={method:t,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:n=()=>{},allowList:o=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...o){const s={};switch(r){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const i=e[r].apply(e,o),l={method:r,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,n=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${n?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepMerge:(e,t,r={})=>{const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,n)=>{let o,a,s=getDataType(e),i=getDataType(t),l=!0;if(n.interceptor&&"function"==typeof n.interceptor){let r=n.interceptor({target:e,source:t,targetType:s,sourceType:i,parent:n.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return n?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:i,parent:n.parent}),"Object"===s&&"Object"===i?(a=deepMergeObjects(e,t,n),o="Object"):"Array"===s&&"Array"===i?(a=deepMergeArrays(e,t,n),o="Array"):"Set"===s&&"Set"===i?(a=deepMergeSets(e,t,n),o="Set"):"Map"===s&&"Map"===i?(a=deepMergeMaps(e,t,n),o="Map"):(l=!1,a=e),n?.onAfterMerge?.({result:a,target:e,source:t,targetType:s,sourceType:i,mergeType:o,parent:r.parent}),{result:a,flag:l,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let n=getDataType(e),o=getDataType(t);if("Object"!==n||"Object"!==o)return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=a.targetClone?shallowCopy(e):e;for(let e in t){const n=s[e],o=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(n,o,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=o;else{let t=a.useEnable?mergeEnableObject(n,o):o;n!==t&&null===t?"ignore"===a.nullBehavior||("delete"===a.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):n!==t&&void 0===t?"ignore"===a.undefinedBehavior||("delete"===a.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=o):s[e]=o}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.inheritMissing&&(s[e]=o)}if(a.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=n.targetClone?[...e]:e;if("replace"===n.dataMode)for(let e=0;e<t.length&&(n.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...n,parent:o}).flag||(o[e]=t[e])}else"concat"===n.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Map([...e]):e;for(const[e,a]of t.entries())if(o.has(e)){const t=o.get(e),r=a,s=smartMerger(t,r,n);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,a);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Set(...e):e;if("replace"===n.dataMode){const e=[...o],r=[...t],a=smartMerger(e,r,n);o.clear();for(let e of a.result)o.add(e)}else if("concat"===n.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,n).result},shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol}});
15
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),n=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(n.interceptor&&"function"==typeof n.interceptor){let t=n.interceptor({input:e,type:r,parent:n.parent});if(t)return t}n.onBeforeClone?.({input:e,type:r,parent:n.parent});let o,a=!0;if("Object"===r&&n.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],n);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...n,parent:e});o=t}else if("Array"===r&&n.cloneArray)o=e.map(t=>deepClone(t,{...n,parent:e}));else if("Map"===r&&n.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,n),deepClone(o,{...n,parent:e}));o=t}else if("Set"===r&&n.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...n,parent:e}));o=t}else if("Date"===r&&n.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,a=!1;return n.onAfterClone?.({output:o,input:e,type:r,cloned:a,parent:n.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},getEl=(e,t=document.body)=>{let r=getDataType(e),n=getDataType(t).includes("HTML")?t:document.querySelector(t),o=n&&n instanceof HTMLTemplateElement?n.content:n,a=null;if(e)if(r.includes("HTML"))a=e;else if("String"===r)try{a=(o||document).querySelector(e.trim())}catch{a=null}return a},createEl=(e,t,r)=>{let n=(e=e||"div").toUpperCase().trim(),o=document.createElement(n),a=getDataType(t);if(t&&"Object"===a)for(let e in t)t.hasOwnProperty(e)&&o.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let r=getDataType(t);if("TEMPLATE"===n)e.innerHTML=t.toString();else if("Array"===r&&t.length>0)for(let r of t){if(getDataType(r).includes("HTML"))e.appendChild(r);else{let t=createEl(r.name,r.attrs,r.content);t&&e.appendChild(t)}}else if(r.includes("HTML"))e.appendChild(t);else if("String"===r&&t.trim().startsWith("#")&&t.trim().length>1){let r=getEl(t);if(!r)return;"TEMPLATE"===r.nodeName?e.appendChild(r.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",r.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(o,r),o};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],o=getDataType(e),a=o.toLowerCase(),s=n.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,o)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return o},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=e);const s={};for(let e of o)s[e]=function(...o){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...o];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=o,n=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-n:r;s.deletedItems=t.slice(n,n+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const l=o[1]||0,c=void 0===o[2]?i:o[2];s.oldItems=t.slice(l,c),s.start=l,s.end=c}r?.(s);const l=Array.prototype[e].apply(t,o),c={value:l,key:e,args:o,context:s,target:t,...a};return n?.(c),l};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...o){const s={};switch(t){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}r(s);const i=e[t].apply(e,o),l={method:t,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:n=()=>{},allowList:o=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...o){const s={};switch(r){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const i=e[r].apply(e,o),l={method:r,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,n=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${n?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepMerge:(e,t,r={})=>{const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,nullBehavior:"preserve",undefinedBehavior:"preserve",deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,n)=>{let o,a,s=getDataType(e),i=getDataType(t),l=!0;if(n.interceptor&&"function"==typeof n.interceptor){let r=n.interceptor({target:e,source:t,targetType:s,sourceType:i,parent:n.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return n?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:i,parent:n.parent}),"Object"===s&&"Object"===i?(a=deepMergeObjects(e,t,n),o="Object"):"Array"===s&&"Array"===i?(a=deepMergeArrays(e,t,n),o="Array"):"Set"===s&&"Set"===i?(a=deepMergeSets(e,t,n),o="Set"):"Map"===s&&"Map"===i?(a=deepMergeMaps(e,t,n),o="Map"):(l=!1,a=e),n?.onAfterMerge?.({result:a,target:e,source:t,targetType:s,sourceType:i,mergeType:o,parent:r.parent}),{result:a,flag:l,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let n=getDataType(e),o=getDataType(t);if("Object"!==n||"Object"!==o)return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=a.targetClone?shallowCopy(e):e;for(let e in t){const n=s[e],o=t[e];if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){const t=smartMerger(n,o,{...r,parent:s});if(t.flag)t.mergeType?"Object"===t.mergeType&&(s[e]=t.result):s[e]=o;else{let t=a.useEnable?mergeEnableObject(n,o):o;n!==t&&null===t?"ignore"===a.nullBehavior||("delete"===a.nullBehavior?Reflect.deleteProperty(s,e):s[e]=t):n!==t&&void 0===t?"ignore"===a.undefinedBehavior||("delete"===a.undefinedBehavior?Reflect.deleteProperty(s,e):s[e]=o):s[e]=o}}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.inheritMissing&&(s[e]=o)}if(a.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=n.targetClone?[...e]:e;if("replace"===n.dataMode)for(let e=0;e<t.length&&(n.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...n,parent:o}).flag||(o[e]=t[e])}else"concat"===n.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Map([...e]):e;for(const[e,a]of t.entries())if(o.has(e)){const t=o.get(e),r=a,s=smartMerger(t,r,n);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,a);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Set(...e):e;if("replace"===n.dataMode){const e=[...o],r=[...t],a=smartMerger(e,r,n);o.clear();for(let e of a.result)o.add(e)}else if("concat"===n.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,n).result},shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol,getEl:getEl,getEls:(e,t=document.body)=>{let r=getDataType(e),n=getEl(t),o=n&&n instanceof HTMLTemplateElement?n.content:n||document,a=[];return(e=>{let t,r=getDataType(e);return t=!e||("Object"===r?0===Object.keys(e).length:"Array"===r?""===e.join(""):"Function"===r?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===r?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===r||"Map"===r?0===e.size:"Date"===r?isNaN(e.getTime()):"RegExp"===r?""===e.source:"ArrayBuffer"===r?0===e.byteLength:"NodeList"===r||"HTMLCollection"===r||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===r||e instanceof Error?""===e.message:!(!r.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(r))&&0===e.length),t})(e)?a:(r.includes("HTML")?a.push(e):"String"===r?a=(e=e.trim()).split(",").map(e=>[...o.querySelectorAll(e)]).flat():"Array"===r&&(a=e.map(e=>getEl(e,n))),a.filter(Boolean))},createEl:createEl}});
package/dist.zip CHANGED
Binary file
package/modules.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Last modified: 2025/12/25 14:29:40
2
+ * Last modified: 2026/01/05 10:31:32
3
3
  */
4
4
  'use strict';
5
5
  import deepClone from './src/deepClone';
@@ -16,6 +16,9 @@ import wrapMapMethods from './src/wrapMapMethods';
16
16
  import deepMerge from './src/deepMerge';
17
17
  import shallowCopy from './src/shallowCopy';
18
18
  import copyObjectWithSymbol from './src/copyObjectWithSymbol';
19
+ import getEl from './src/getEl';
20
+ import getEls from './src/getEls';
21
+ import createEl from './src/createEl';
19
22
  const utils = {
20
23
  //executeStr,
21
24
  getDataType,
@@ -34,5 +37,8 @@ const utils = {
34
37
  deepMerge,
35
38
  shallowCopy,
36
39
  copyObjectWithSymbol,
40
+ getEl,
41
+ getEls,
42
+ createEl,
37
43
  };
38
44
  export default utils;
package/modules.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Last modified: 2025/12/25 14:29:40
2
+ * Last modified: 2026/01/05 10:31:32
3
3
  */
4
4
  'use strict'
5
5
  import deepClone from './src/deepClone';
@@ -24,6 +24,9 @@ import deepMergeSets from './src/deepMergeSets';
24
24
  import deepEqual from './src/deepEqual';
25
25
  import shallowCopy from './src/shallowCopy';
26
26
  import copyObjectWithSymbol from './src/copyObjectWithSymbol';
27
+ import getEl from './src/getEl';
28
+ import getEls from './src/getEls';
29
+ import createEl from './src/createEl';
27
30
 
28
31
 
29
32
 
@@ -45,6 +48,9 @@ const utils = {
45
48
  deepMerge,
46
49
  shallowCopy,
47
50
  copyObjectWithSymbol,
51
+ getEl,
52
+ getEls,
53
+ createEl,
48
54
 
49
55
  };
50
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codady/utils",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "author": "AXUI Development Team",
5
5
  "license": "MIT",
6
6
  "description": "This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.",
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @since Last modified: 2026/01/05 10:30:46
3
+ * @function createEl
4
+ * @description Create a node or a group of father-son nodes.
5
+ * @param {string} name="div" - Node name, requierd.
6
+ * @param {object} [attrs] - Node attributes.Format : {class:'demo',style:'width:100px;height:50px;',disabled:''}
7
+ * @param {string|number|array} [content] - Node content.If it is an array,create a sub-node of the cycle.
8
+ * @returns {HTMLElement|null} Return a node or null
9
+ * @example
10
+ * ax.createEl('div',{class:'demo'},'I love you');
11
+ * <!--return a HTMLElement node-->
12
+ */
13
+ //简介:创建一个节点或一组父子节点
14
+ //参数name:节点名称,不可为空
15
+ //参数attrs:节点上的属性,键值对的对象格式
16
+ //参数content:节点内容,如果是数组,那么将创建子节点
17
+ //返回:一个节点或null
18
+ 'use strict';
19
+ import getDataType from './getDataType';
20
+ import getEl from './getEl';
21
+ const createEl = (name, attrs, content) => {
22
+ //默认为div
23
+ name = name || 'div';
24
+ //统一大小写
25
+ let rootName = name.toUpperCase().trim(), rootEl = document.createElement(rootName), attrsType = getDataType(attrs), loop = (host, data) => {
26
+ if (data === '' || data === null || data === undefined) {
27
+ //为空、未定义则不再执行
28
+ return false;
29
+ }
30
+ let dataType = getDataType(data);
31
+ //template是DocumentFragment类型不能用insertAdjacentHTML
32
+ if (rootName === 'TEMPLATE') {
33
+ host.innerHTML = data.toString();
34
+ }
35
+ else {
36
+ if (dataType === 'Array' && data.length > 0) {
37
+ //节点数组
38
+ //data.forEach((i: T_obj) => loop(el, i));
39
+ for (let k of data) {
40
+ let childType = getDataType(k);
41
+ if (childType.includes('HTML')) {
42
+ //是个节点
43
+ host.appendChild(k);
44
+ }
45
+ else {
46
+ //是个对象{name:'',attrs:{},content:''}
47
+ let child = createEl(k.name, k.attrs, k.content);
48
+ child && host.appendChild(child);
49
+ }
50
+ }
51
+ }
52
+ else if (dataType.includes('HTML')) {
53
+ //HTML节点
54
+ host.appendChild(data);
55
+ }
56
+ else if (dataType === 'String' && data.trim().startsWith('#') && data.trim().length > 1) {
57
+ //是字符串且是#id选择器,则取其文本
58
+ let el = getEl(data);
59
+ if (!el)
60
+ return;
61
+ //如果是template模板节点则需要特殊处理
62
+ el.nodeName === 'TEMPLATE' ? host.appendChild(el.content.cloneNode(true)) : host.insertAdjacentHTML('beforeEnd', el.innerHTML);
63
+ }
64
+ else {
65
+ //字符串数字等
66
+ host.insertAdjacentHTML('beforeEnd', data);
67
+ }
68
+ }
69
+ };
70
+ //添加属性
71
+ if (attrs && attrsType === 'Object') {
72
+ for (let k in attrs) {
73
+ //注意,attrs[k]可能是一个{}或[],不一定是字符串
74
+ // JSON.stringify可以将所有格式的数据都转成文本,会忽略函数和节点数据
75
+ //字符串则不需要stringify,否则会将字符串的引号也一并输出
76
+ attrs.hasOwnProperty(k) && rootEl.setAttribute(k, typeof attrs[k] === 'string' ? attrs[k] : JSON.stringify(attrs[k]));
77
+ }
78
+ }
79
+ //执行循环创建子节点
80
+ loop(rootEl, content);
81
+ return rootEl;
82
+ };
83
+ export default createEl;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @since Last modified: 2026/01/05 10:30:46
3
+ * @function createEl
4
+ * @description Create a node or a group of father-son nodes.
5
+ * @param {string} name="div" - Node name, requierd.
6
+ * @param {object} [attrs] - Node attributes.Format : {class:'demo',style:'width:100px;height:50px;',disabled:''}
7
+ * @param {string|number|array} [content] - Node content.If it is an array,create a sub-node of the cycle.
8
+ * @returns {HTMLElement|null} Return a node or null
9
+ * @example
10
+ * ax.createEl('div',{class:'demo'},'I love you');
11
+ * <!--return a HTMLElement node-->
12
+ */
13
+ //简介:创建一个节点或一组父子节点
14
+ //参数name:节点名称,不可为空
15
+ //参数attrs:节点上的属性,键值对的对象格式
16
+ //参数content:节点内容,如果是数组,那么将创建子节点
17
+ //返回:一个节点或null
18
+ 'use strict';
19
+ import getDataType from './getDataType';
20
+ import getEl from './getEl';
21
+ const createEl = (name: string, attrs?: Record<string,any> | null, content?: any) => {
22
+ //默认为div
23
+ name = name || 'div';
24
+ //统一大小写
25
+ let rootName = name.toUpperCase().trim(),
26
+ rootEl = document.createElement(rootName),
27
+ attrsType = getDataType(attrs),
28
+ loop = (host: any, data: any) => {
29
+ if (data === '' || data === null || data === undefined) {
30
+ //为空、未定义则不再执行
31
+ return false;
32
+ }
33
+ let dataType = getDataType(data);
34
+ //template是DocumentFragment类型不能用insertAdjacentHTML
35
+ if (rootName === 'TEMPLATE') {
36
+ host.innerHTML = data.toString();
37
+ } else {
38
+ if (dataType === 'Array' && data.length > 0) {
39
+ //节点数组
40
+ //data.forEach((i: T_obj) => loop(el, i));
41
+ for (let k of data) {
42
+ let childType = getDataType(k);
43
+ if (childType.includes('HTML')) {
44
+ //是个节点
45
+ host.appendChild(k);
46
+ } else {
47
+ //是个对象{name:'',attrs:{},content:''}
48
+ let child = createEl(k.name, k.attrs, k.content);
49
+ child && host.appendChild(child);
50
+ }
51
+ }
52
+ } else if (dataType.includes('HTML')) {
53
+ //HTML节点
54
+ host.appendChild(data);
55
+ } else if (dataType === 'String' && data.trim().startsWith('#') && data.trim().length > 1) {
56
+ //是字符串且是#id选择器,则取其文本
57
+ let el = getEl(data);
58
+ if (!el) return;
59
+ //如果是template模板节点则需要特殊处理
60
+ el.nodeName === 'TEMPLATE' ? host.appendChild((el as any).content.cloneNode(true)) : host.insertAdjacentHTML('beforeEnd',(el as any).innerHTML);
61
+ } else {
62
+ //字符串数字等
63
+ host.insertAdjacentHTML('beforeEnd', data);
64
+ }
65
+ }
66
+ }
67
+ //添加属性
68
+ if (attrs && attrsType === 'Object') {
69
+ for (let k in attrs) {
70
+ //注意,attrs[k]可能是一个{}或[],不一定是字符串
71
+ // JSON.stringify可以将所有格式的数据都转成文本,会忽略函数和节点数据
72
+ //字符串则不需要stringify,否则会将字符串的引号也一并输出
73
+ attrs.hasOwnProperty(k) && rootEl.setAttribute(k, typeof attrs[k] === 'string' ? attrs[k] : JSON.stringify(attrs[k]));
74
+ }
75
+ }
76
+ //执行循环创建子节点
77
+ loop(rootEl, content);
78
+ return rootEl;
79
+ }
80
+ export default createEl;
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:50:46
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') || parType === 'ShadowRoot' ? 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;