@whitesev/utils 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Utils.ts CHANGED
@@ -43,17 +43,87 @@ export declare interface AnyObject {
43
43
  }
44
44
 
45
45
  export declare interface Vue2Context extends AnyObject {
46
- _isVue: true;
46
+ $attrs: AnyObject;
47
+ $children: Vue2Context[];
48
+ $createElement: (...args: any[]) => any;
49
+ $el: HTMLElement;
50
+ $listeners: AnyObject;
47
51
  $options: AnyObject;
48
52
  $parent: Vue2Context;
53
+ $refs: AnyObject;
49
54
  $root: Vue2Context;
50
- $children: Vue2Context[];
51
- $vnode: AnyObject;
52
- $slots: AnyObject;
53
55
  $scopedSlots: AnyObject;
54
- $attrs: AnyObject;
55
- $listeners: AnyObject;
56
+ $slots: AnyObject;
56
57
  $store: AnyObject;
58
+ $vnode: AnyObject;
59
+
60
+ _data: AnyObject;
61
+ _directInactive: boolean;
62
+ _events: AnyObject;
63
+ _hasHookEvent: boolean;
64
+ _isBeingDestroyed: boolean;
65
+ _isDestroyed: boolean;
66
+ _isMounted: boolean;
67
+ _isVue: boolean;
68
+
69
+ $data: AnyObject;
70
+ $isServer: boolean;
71
+ $props: AnyObject;
72
+ $route: AnyObject & {
73
+ fullPath: string;
74
+ hash: string;
75
+ matched: AnyObject[];
76
+ meta: AnyObject;
77
+ name: string;
78
+ params: AnyObject;
79
+ path: string;
80
+ query: AnyObject;
81
+ };
82
+ $router: AnyObject & {
83
+ afterHooks: AnyObject[];
84
+ app: Vue2Context;
85
+ apps: Vue2Context[];
86
+ beforeHooks: ((...args: any[]) => any)[];
87
+ fallback: boolean;
88
+ history: AnyObject & {
89
+ base: string;
90
+ current: AnyObject;
91
+ listeners: AnyObject[];
92
+ router: Vue2Context["$router"];
93
+ /**
94
+ *
95
+ * @param delta 访问的距离。如果 delta < 0 则后退相应数量的记录,如果 > 0 则前进。
96
+ * @param triggerListeners 是否应该触发连接到该历史的监听器
97
+ * @returns
98
+ */
99
+ go: (delta: number, triggerListeners?: boolean) => void;
100
+ /**
101
+ *
102
+ * @param to 要设置的地址
103
+ * @param data 可选的 HistoryState 以关联该导航记录
104
+ * @returns
105
+ */
106
+ push: (to: string, data?: AnyObject) => void;
107
+ /**
108
+ *
109
+ * @param to 要设置的地址
110
+ * @param data 可选的 HistoryState 以关联该导航记录
111
+ * @returns
112
+ */
113
+ replace: (to: string, data?: AnyObject) => void;
114
+ };
115
+ matcher: AnyObject & {
116
+ addRoute: (...args: any[]) => any;
117
+ addRoutes: (...args: any[]) => any;
118
+ getRoutes: () => any;
119
+ match: (...args: any[]) => any;
120
+ };
121
+ mode: string;
122
+ resolveHooks: ((...args: any[]) => any)[];
123
+ currentRoute: AnyObject;
124
+ };
125
+ $ssrContext: AnyObject;
126
+
57
127
  $watch: (
58
128
  key: string | string[],
59
129
  handler: (this: any, newVal: any, oldVal: any) => void,
@@ -62,12 +132,11 @@ export declare interface Vue2Context extends AnyObject {
62
132
  deep?: boolean;
63
133
  }
64
134
  ) => void;
65
- $el: Element;
66
135
  }
67
136
 
68
137
  class Utils {
69
138
  /** 版本号 */
70
- version = "2024.5.28";
139
+ version = "2024.5.30";
71
140
 
72
141
  /**
73
142
  * 在页面中增加style元素,如果html节点存在子节点,添加子节点第一个,反之,添加到html节点的子节点最后一个
@@ -3918,426 +3987,579 @@ class Utils {
3918
3987
  );
3919
3988
  }
3920
3989
  /**
3921
- * 等待指定元素出现,支持多个selector
3922
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
3990
+ * 等待元素出现
3991
+ * @param selector CSS选择器
3992
+ * @param parent (可选)父元素,默认document
3923
3993
  * @example
3924
- * Utils.waitNode("div.xxx").then( element =>{
3925
- * console.log(element); // div.xxx => HTMLElement
3994
+ * Utils.waitNode("div").then( $div =>{
3995
+ * console.log($div); // div => HTMLDivELement
3926
3996
  * })
3997
+ * Utils.waitNode("div",document).then( $div =>{
3998
+ * console.log($div); // div => HTMLDivELement
3999
+ * })
4000
+ */
4001
+ waitNode<T extends Element>(
4002
+ selector: string,
4003
+ parent?: Node | Element | Document | HTMLElement
4004
+ ): Promise<T>;
4005
+ /**
4006
+ * 等待元素出现
4007
+ * @param selectorList CSS选择器数组
4008
+ * @param parent (可选)父元素,默认document
3927
4009
  * @example
3928
- * Utils.waitNode("div.xxx","a.xxx").then( (elementList)=>{
3929
- * console.log(elementList[0]); // div.xxx => HTMLElement
3930
- * console.log(elementList[1]); // a.xxx => HTMLElement
4010
+ * Utils.waitNode(["div"]).then( ([$div]) =>{
4011
+ * console.log($div); // div => HTMLDivELement[]
4012
+ * })
4013
+ * Utils.waitNode(["div"],document).then( ([$div]) =>{
4014
+ * console.log($div); // div => HTMLDivELement[]
3931
4015
  * })
3932
4016
  */
3933
- waitNode<T extends HTMLElement>(nodeSelector: string | [string]): Promise<T>;
4017
+ waitNode<T extends Element[]>(
4018
+ selectorList: string[],
4019
+ parent?: Node | Element | Document | HTMLElement
4020
+ ): Promise<T>;
3934
4021
  /**
3935
- * 等待指定元素出现,支持多个selector
3936
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
4022
+ * 等待元素出现
4023
+ * @param selector CSS选择器
4024
+ * @param parent 父元素,默认document
4025
+ * @param timeout 超时时间,默认0
3937
4026
  * @example
3938
- * Utils.waitNode("div.xxx").then( element =>{
3939
- * console.log(element); // div.xxx => HTMLElement
4027
+ * Utils.waitNode("div",document,1000).then( $div =>{
4028
+ * console.log($div); // $div => HTMLDivELement | null
3940
4029
  * })
4030
+ */
4031
+ waitNode<T extends Element>(
4032
+ selector: string,
4033
+ parent: Node | Element | Document | HTMLElement,
4034
+ timeout: number
4035
+ ): Promise<T | null>;
4036
+ /**
4037
+ * 等待元素出现
4038
+ * @param selectorList CSS选择器数组
4039
+ * @param parent 父元素,默认document
4040
+ * @param timeout 超时时间,默认0
3941
4041
  * @example
3942
- * Utils.waitNode("div.xxx","a.xxx").then( (elementList)=>{
3943
- * console.log(elementList[0]); // div.xxx => HTMLElement
3944
- * console.log(elementList[1]); // a.xxx => HTMLElement
4042
+ * Utils.waitNode(["div"],document,1000).then( ([$div]) =>{
4043
+ * console.log($div); // $div => HTMLDivELement[] | null
3945
4044
  * })
3946
4045
  */
3947
- waitNode<T extends HTMLElement>(...nodeSelectors: string[]): Promise<T[]>;
4046
+ waitNode<T extends Element[]>(
4047
+ selectorList: string[],
4048
+ parent: Node | Element | Document | HTMLElement,
4049
+ timeout: number
4050
+ ): Promise<T | null>;
3948
4051
  /**
3949
- * 等待指定元素出现,支持多个selector
3950
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
4052
+ * 等待元素出现
4053
+ * @param selector CSS选择器
4054
+ * @param timeout 超时时间,默认0
3951
4055
  * @example
3952
- * Utils.waitNode("div.xxx").then( element =>{
3953
- * console.log(element); // div.xxx => HTMLElement
4056
+ * Utils.waitNode("div",1000).then( $div =>{
4057
+ * console.log($div); // $div => HTMLDivELement | null
3954
4058
  * })
4059
+ */
4060
+ waitNode<T extends Element>(
4061
+ selector: string,
4062
+ timeout: number
4063
+ ): Promise<T | null>;
4064
+ /**
4065
+ * 等待元素出现
4066
+ * @param selectorList CSS选择器数组
4067
+ * @param timeout 超时时间,默认0
3955
4068
  * @example
3956
- * Utils.waitNode("div.xxx","a.xxx").then( (elementList)=>{
3957
- * console.log(elementList[0]); // div.xxx => HTMLElement
3958
- * console.log(elementList[1]); // a.xxx => HTMLElement
4069
+ * Utils.waitNode(["div"],1000).then( [$div] =>{
4070
+ * console.log($div); // $div => HTMLDivELement[] | null
3959
4071
  * })
3960
4072
  */
3961
- waitNode<T extends HTMLElement>(...nodeSelectors: string[]): Promise<T | T[]>;
3962
- async waitNode<T extends HTMLElement>(
3963
- ...nodeSelectors: string | string[] | any
3964
- ): Promise<T | T[]> {
3965
- /* 检查每个参数是否为字符串类型 */
3966
- for (let nodeSelector of nodeSelectors) {
3967
- if (typeof nodeSelector !== "string") {
3968
- throw new Error("Utils.waitNode 参数必须都是 string 类型");
4073
+ waitNode<T extends Element[]>(
4074
+ selectorList: string[],
4075
+ timeout: number
4076
+ ): Promise<T | null>;
4077
+ waitNode<T extends Element | Element[]>(...args: any[]): Promise<T | null> {
4078
+ // 过滤掉undefined
4079
+ args = args.filter((arg) => arg !== void 0);
4080
+ let that = this;
4081
+ // 选择器
4082
+ let selector = args[0] as unknown as string | string[];
4083
+ // 父元素(监听的元素)
4084
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4085
+ // 超时时间
4086
+ let timeout = 0;
4087
+ if (typeof args[0] !== "string" && !Array.isArray(args[0])) {
4088
+ throw new TypeError("Utils.waitNode 第一个参数必须是string|string[]");
4089
+ }
4090
+ if (args.length === 1) {
4091
+ // 上面已做处理
4092
+ } else if (args.length === 2) {
4093
+ let secondParam = args[1];
4094
+ if (typeof secondParam === "number") {
4095
+ // "div",10000
4096
+ timeout = secondParam;
4097
+ } else if (
4098
+ typeof secondParam === "object" &&
4099
+ secondParam instanceof Node
4100
+ ) {
4101
+ // "div",document
4102
+ parent = secondParam;
4103
+ } else {
4104
+ throw new TypeError("Utils.waitNode 第二个参数必须是number|Node");
4105
+ }
4106
+ } else if (args.length === 3) {
4107
+ // "div",document,10000
4108
+ // 第二个参数,parent
4109
+ let secondParam = args[1];
4110
+ // 第三个参数,timeout
4111
+ let thirdParam = args[2];
4112
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4113
+ parent = secondParam;
4114
+ if (typeof thirdParam === "number") {
4115
+ timeout = thirdParam;
4116
+ } else {
4117
+ throw new TypeError("Utils.waitNode 第三个参数必须是number");
4118
+ }
4119
+ } else {
4120
+ throw new TypeError("Utils.waitNode 第二个参数必须是Node");
3969
4121
  }
4122
+ } else {
4123
+ throw new TypeError("Utils.waitNode 参数个数错误");
3970
4124
  }
3971
- let UtilsContext = this;
3972
4125
  return new Promise((resolve) => {
3973
- /* 防止触发第二次回调 */
3974
- let isReturn = false;
3975
-
3976
- /**
3977
- * 检查所有选择器是否匹配到节点
3978
- * @param observer
3979
- */
3980
- let checkNodes = (observer?: MutationObserver) => {
3981
- let isFind = true;
3982
- let selectNodeArray: HTMLElement[] = [];
3983
- for (let selector of nodeSelectors) {
3984
- let element = document.querySelector(selector) as HTMLElement | null;
3985
- if (!element) {
3986
- /* 没找到,直接退出循环 */
3987
- isFind = false;
3988
- break;
4126
+ function getNode() {
4127
+ if (Array.isArray(selector)) {
4128
+ let result: T[] = [];
4129
+ for (let index = 0; index < selector.length; index++) {
4130
+ let node = (parent as Element).querySelector(selector[index]);
4131
+ if (node) {
4132
+ result.push(node as any);
4133
+ }
3989
4134
  }
3990
- selectNodeArray.push(element);
3991
- }
3992
- if (isFind) {
3993
- isReturn = true;
3994
- observer?.disconnect();
3995
- /* 如果只有一个选择器,那么返回数组中存储的第一个 */
3996
- if (selectNodeArray.length === 1) {
3997
- resolve(selectNodeArray[0] as any);
3998
- } else {
3999
- resolve(selectNodeArray as any);
4135
+ if (result.length === selector.length) {
4136
+ return result;
4000
4137
  }
4138
+ } else {
4139
+ return (parent as Element).querySelector(selector);
4001
4140
  }
4002
- };
4003
-
4004
- /* 在函数开始时检查节点是否已经存在 */
4005
- checkNodes();
4006
-
4007
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4008
- UtilsContext.mutationObserver(document.documentElement, {
4009
- config: { subtree: true, childList: true, attributes: true },
4010
- callback: (mutations, observer) => {
4011
- if (isReturn) {
4141
+ }
4142
+ let node = getNode();
4143
+ if (node) {
4144
+ resolve(node as any as T);
4145
+ return;
4146
+ }
4147
+ let observer = that.mutationObserver(parent, {
4148
+ config: {
4149
+ subtree: true,
4150
+ childList: true,
4151
+ attributes: true,
4152
+ },
4153
+ callback() {
4154
+ let node = getNode();
4155
+ if (node) {
4156
+ // 取消观察器
4157
+ observer.disconnect();
4158
+ resolve(node as any as T);
4012
4159
  return;
4013
4160
  }
4014
- checkNodes(observer);
4015
4161
  },
4016
4162
  });
4163
+ if (timeout > 0) {
4164
+ setTimeout(() => {
4165
+ // 取消观察器
4166
+ observer.disconnect();
4167
+ resolve(null);
4168
+ }, timeout);
4169
+ }
4017
4170
  });
4018
4171
  }
4019
4172
  /**
4020
- * 在规定时间内,等待任意元素出现,支持多个selector,如果未出现,则关闭监听
4021
- * @param nodeSelectorsList 一个或多个节点选择器,必须为字符串类型
4022
- * @param maxTime (可选)xx毫秒(ms)后关闭监听,默认:0(ms)
4173
+ * 等待任意元素出现
4174
+ * @param selectorList CSS选择器数组
4175
+ * @param parent (可选)监听的父元素
4023
4176
  * @example
4024
- * Utils.waitNodeWithInterval("a.xxx",30000).then(element=>{
4025
- * console.log(element);
4177
+ * Utils.waitAnyNode(["div","div"]).then( $div =>{
4178
+ * console.log($div); // $div => HTMLDivELement 这里是第一个
4179
+ * })
4180
+ * Utils.waitAnyNode(["a","div"],document).then( $a =>{
4181
+ * console.log($a); // $a => HTMLAnchorElement 这里是第一个
4026
4182
  * })
4183
+ */
4184
+ waitAnyNode<T extends Element>(
4185
+ selectorList: string[],
4186
+ parent?: Node | Element | Document | HTMLElement
4187
+ ): Promise<T>;
4188
+ /**
4189
+ * 等待任意元素出现
4190
+ * @param selectorList CSS选择器数组
4191
+ * @param parent 父元素,默认document
4192
+ * @param timeout 超时时间,默认0
4027
4193
  * @example
4028
- * Utils.waitNodeWithInterval(["div.xxx","a.xxx"],30000).then(elementList=>{
4029
- * console.log(elementList[0]); // div.xxx => HTMLElement
4030
- * console.log(elementList[1]); // a.xxx => HTMLElement
4194
+ * Utils.waitAnyNode(["div","div"],document,10000).then( $div =>{
4195
+ * console.log($div); // $div => HTMLDivELement | null
4031
4196
  * })
4032
4197
  */
4033
- waitNodeWithInterval<T extends HTMLElement>(
4034
- nodeSelectorsList?: string[] | string,
4035
- maxTime?: number
4036
- ): Promise<T | T[]>;
4037
- waitNodeWithInterval<T extends HTMLElement>(
4038
- nodeSelectorsList: string[] | string = [],
4039
- maxTime: number = 0
4040
- ): Promise<T | T[]> {
4041
- let UtilsContext = this;
4042
- let nodeSelectors: string[] = [];
4043
- /* 检查每个参数是否为字符串类型 */
4044
- if (Array.isArray(nodeSelectorsList)) {
4045
- for (let nodeSelector of nodeSelectorsList) {
4046
- if (typeof nodeSelector !== "string") {
4047
- throw new Error(
4048
- "Utils.waitNodeWithInterval 参数nodeSelectorsList必须为 string[] 类型"
4049
- );
4198
+ waitAnyNode<T extends Element>(
4199
+ selectorList: string[],
4200
+ parent: Node | Element | Document | HTMLElement,
4201
+ timeout: number
4202
+ ): Promise<T | null>;
4203
+ /**
4204
+ * 等待任意元素出现
4205
+ * @param selectorList CSS选择器数组
4206
+ * @param timeout 超时时间,默认0
4207
+ * @example
4208
+ * Utils.waitAnyNode(["div","div"],10000).then( $div =>{
4209
+ * console.log($div); // $div => HTMLDivELement | null
4210
+ * })
4211
+ */
4212
+ waitAnyNode<T extends Element>(
4213
+ selectorList: string[],
4214
+ timeout: number
4215
+ ): Promise<T | null>;
4216
+ waitAnyNode<T extends Element>(...args: any[]): Promise<T | null> {
4217
+ // 过滤掉undefined
4218
+ args = args.filter((arg) => arg !== void 0);
4219
+ let that = this;
4220
+ // 选择器
4221
+ let selectorList = args[0] as unknown as string[];
4222
+ // 父元素(监听的元素)
4223
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4224
+ // 超时时间
4225
+ let timeout = 0;
4226
+ if (typeof args[0] !== "object" && !Array.isArray(args[0])) {
4227
+ throw new TypeError("Utils.waitAnyNode 第一个参数必须是string[]");
4228
+ }
4229
+ if (args.length === 1) {
4230
+ // 上面已做处理
4231
+ } else if (args.length === 2) {
4232
+ let secondParam = args[1];
4233
+ if (typeof secondParam === "number") {
4234
+ // "div",10000
4235
+ timeout = secondParam;
4236
+ } else if (
4237
+ typeof secondParam === "object" &&
4238
+ secondParam instanceof Node
4239
+ ) {
4240
+ // "div",document
4241
+ parent = secondParam;
4242
+ } else {
4243
+ throw new TypeError("Utils.waitAnyNode 第二个参数必须是number|Node");
4244
+ }
4245
+ } else if (args.length === 3) {
4246
+ // "div",document,10000
4247
+ // 第二个参数,parent
4248
+ let secondParam = args[1];
4249
+ // 第三个参数,timeout
4250
+ let thirdParam = args[2];
4251
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4252
+ parent = secondParam;
4253
+ if (typeof thirdParam === "number") {
4254
+ timeout = thirdParam;
4255
+ } else {
4256
+ throw new TypeError("Utils.waitAnyNode 第三个参数必须是number");
4050
4257
  }
4258
+ } else {
4259
+ throw new TypeError("Utils.waitAnyNode 第二个参数必须是Node");
4051
4260
  }
4052
- nodeSelectors = nodeSelectorsList;
4053
4261
  } else {
4054
- nodeSelectors.push(nodeSelectorsList);
4262
+ throw new TypeError("Utils.waitAnyNode 参数个数错误");
4055
4263
  }
4056
-
4057
- return new Promise((resolve, reject) => {
4058
- /* 防止触发第二次回调 */
4059
- let isReturn = false;
4060
-
4061
- /* 检查所有选择器是否匹配到节点 */
4062
- let checkNodes = (observer?: MutationObserver) => {
4063
- let isFind = true;
4064
- let selectNodeArray = [];
4065
- for (let selector of nodeSelectors) {
4066
- let element = document.querySelector(selector);
4067
- if (!element) {
4068
- /* 没找到,直接退出循环 */
4069
- isFind = false;
4070
- break;
4071
- }
4072
- selectNodeArray.push(element);
4073
- }
4074
- if (isFind) {
4075
- isReturn = true;
4076
- observer?.disconnect();
4077
- /* 如果只有一个选择器,那么返回数组中存储的第一个 */
4078
- if (selectNodeArray.length === 1) {
4079
- resolve(selectNodeArray[0] as any);
4080
- } else {
4081
- resolve(selectNodeArray as any);
4082
- }
4083
- }
4084
- };
4085
-
4086
- /* 在函数开始时检查节点是否已经存在 */
4087
- checkNodes();
4088
-
4089
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4090
- let mutationObserver = UtilsContext.mutationObserver(
4091
- document.documentElement,
4092
- {
4093
- config: { subtree: true, childList: true, attributes: true },
4094
- callback: (mutations, observer) => {
4095
- if (isReturn) {
4096
- return;
4097
- }
4098
- checkNodes(observer);
4099
- },
4100
- }
4101
- );
4102
- setTimeout(() => {
4103
- mutationObserver.disconnect();
4104
- reject();
4105
- }, maxTime);
4264
+ let promiseList = selectorList.map((selector) => {
4265
+ return that.waitNode<T>(selector, parent, timeout);
4106
4266
  });
4267
+ return Promise.any(promiseList);
4107
4268
  }
4108
4269
 
4109
4270
  /**
4110
- * 等待任意元素出现,支持多个selector
4111
- * @param nodeSelectors 一个或多个节点选择器,必须为字符串类型
4271
+ * 等待元素数组出现
4272
+ * @param selector CSS选择器
4273
+ * @param parent (可选)监听的父元素
4112
4274
  * @example
4113
- * Utils.waitAnyNode("div.xxx","a.xxx").then( element =>{
4114
- * console.log(element); // a.xxx => HTMLElement
4275
+ * Utils.waitNodeList("div").then( $result =>{
4276
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4277
+ * })
4278
+ * Utils.waitNodeList("div",document).then( $result =>{
4279
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4115
4280
  * })
4116
4281
  */
4117
- waitAnyNode<T extends HTMLElement>(...nodeSelectors: any[]): Promise<T>;
4118
- waitAnyNode<T extends HTMLElement>(...nodeSelectors: any[]): Promise<T> {
4119
- let UtilsContext = this;
4120
- /* 检查每个参数是否为字符串类型 */
4121
- for (let nodeSelector of nodeSelectors) {
4122
- if (typeof nodeSelector !== "string") {
4123
- throw new Error("Utils.waitNode 参数必须为 ...string 类型");
4124
- }
4125
- }
4126
-
4127
- return new Promise((resolve) => {
4128
- /* 防止触发第二次回调 */
4129
- let isReturn = false;
4130
-
4131
- /* 检查所有选择器是否存在任意匹配到元素 */
4132
- let checkNodes = (observer?: MutationObserver) => {
4133
- let selectNode = null;
4134
- for (let selector of nodeSelectors) {
4135
- selectNode = document.querySelector(selector);
4136
- if (selectNode) {
4137
- /* 找到,退出循环 */
4138
- break;
4139
- }
4140
- }
4141
- if (selectNode) {
4142
- isReturn = true;
4143
- observer?.disconnect();
4144
- resolve(selectNode);
4145
- }
4146
- };
4147
-
4148
- /* 在函数开始时检查节点是否已经存在 */
4149
- checkNodes();
4150
-
4151
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4152
- UtilsContext.mutationObserver(document.documentElement, {
4153
- config: { subtree: true, childList: true, attributes: true },
4154
- callback: (mutations, observer) => {
4155
- if (isReturn) {
4156
- return;
4157
- }
4158
- checkNodes(observer);
4159
- },
4160
- });
4161
- });
4162
- }
4282
+ waitNodeList<T extends NodeListOf<Element>>(
4283
+ selector: string,
4284
+ parent?: Node | Element | Document | HTMLElement
4285
+ ): Promise<T>;
4163
4286
  /**
4164
- * 等待指定元素出现
4165
- * @param nodeSelectors
4166
- * @returns 当nodeSelectors为数组多个时,
4167
- * 返回如:[ NodeList, NodeList ],
4168
- * 当nodeSelectors为单个时,
4169
- * 返回如:NodeList。
4170
- * NodeList元素与页面存在强绑定,当已获取该NodeList,但是页面中却删除了,该元素在NodeList中会被自动删除
4287
+ * 等待元素数组出现
4288
+ * @param selectorList CSS选择器数组
4289
+ * @param parent (可选)监听的父元素
4171
4290
  * @example
4172
- * Utils.waitNodeList("div.xxx").then( nodeList =>{
4173
- * console.log(nodeList) // div.xxx => NodeList
4291
+ * Utils.waitNodeList(["div"]).then( $result =>{
4292
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[]
4174
4293
  * })
4175
- * @example
4176
- * Utils.waitNodeList("div.xxx","a.xxx").then( nodeListArray =>{
4177
- * console.log(nodeListArray[0]) // div.xxx => NodeList
4178
- * console.log(nodeListArray[1]) // a.xxx => NodeList
4294
+ * Utils.waitNodeList(["div"],document).then( $result =>{
4295
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[]
4179
4296
  * })
4180
4297
  */
4181
- waitNodeList<T extends HTMLElement>(nodeSelector: string): Promise<T>;
4182
- /**
4183
- * 等待指定元素出现
4184
- * @param nodeSelectors
4185
- * @returns 当nodeSelectors为数组多个时,
4186
- * 返回如:[ NodeList, NodeList ],
4187
- * 当nodeSelectors为单个时,
4188
- * 返回如:NodeList。
4189
- * NodeList元素与页面存在强绑定,当已获取该NodeList,但是页面中却删除了,该元素在NodeList中会被自动删除
4298
+ waitNodeList<T extends NodeListOf<Element>[]>(
4299
+ selectorList: string[],
4300
+ parent?: Node | Element | Document | HTMLElement
4301
+ ): Promise<T>;
4302
+ /**
4303
+ * 等待元素数组出现
4304
+ * @param selector CSS选择器
4305
+ * @param parent 监听的父元素
4306
+ * @param timeout 超时时间,默认0
4190
4307
  * @example
4191
- * Utils.waitNodeList("div.xxx").then( nodeList =>{
4192
- * console.log(nodeList) // div.xxx => NodeList
4308
+ * Utils.waitNodeList("div",document,10000).then( $result =>{
4309
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4193
4310
  * })
4311
+ */
4312
+ waitNodeList<T extends NodeListOf<Element>>(
4313
+ selector: string,
4314
+ parent: Node | Element | Document | HTMLElement,
4315
+ timeout: number
4316
+ ): Promise<T | null>;
4317
+ /**
4318
+ * 等待元素数组出现
4319
+ * @param selectorList CSS选择器数组
4320
+ * @param parent 监听的父元素
4321
+ * @param timeout 超时时间,默认0
4194
4322
  * @example
4195
- * Utils.waitNodeList("div.xxx","a.xxx").then( nodeListArray =>{
4196
- * console.log(nodeListArray[0]) // div.xxx => NodeList
4197
- * console.log(nodeListArray[1]) // a.xxx => NodeList
4323
+ * Utils.waitNodeList(["div"],document,10000).then( $result =>{
4324
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[] | null
4198
4325
  * })
4199
4326
  */
4200
- waitNodeList<T extends HTMLElement[]>(nodeSelector: string): Promise<T>;
4201
- /**
4202
- * 等待指定元素出现,支持多个selector
4203
- * @param nodeSelectors
4204
- * @returns 当nodeSelectors为数组多个时,
4205
- * 返回如:[ NodeList, NodeList ],
4206
- * 当nodeSelectors为单个时,
4207
- * 返回如:NodeList。
4208
- * NodeList元素与页面存在强绑定,当已获取该NodeList,但是页面中却删除了,该元素在NodeList中会被自动删除
4327
+ waitNodeList<T extends NodeListOf<Element>[]>(
4328
+ selectorList: string[],
4329
+ parent: Node | Element | Document | HTMLElement,
4330
+ timeout: number
4331
+ ): Promise<T | null>;
4332
+ /**
4333
+ * 等待元素数组出现
4334
+ * @param selector CSS选择器数组
4335
+ * @param timeout 超时时间,默认0
4209
4336
  * @example
4210
- * Utils.waitNodeList("div.xxx").then( nodeList =>{
4211
- * console.log(nodeList) // div.xxx => NodeList
4337
+ * Utils.waitNodeList("div",10000).then( $result =>{
4338
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4212
4339
  * })
4340
+ */
4341
+ waitNodeList<T extends NodeListOf<Element>>(
4342
+ selector: string[],
4343
+ timeout: number
4344
+ ): Promise<T | null>;
4345
+ /**
4346
+ * 等待元素数组出现
4347
+ * @param selectorList CSS选择器数组
4348
+ * @param timeout 超时时间,默认0
4213
4349
  * @example
4214
- * Utils.waitNodeList("div.xxx","a.xxx").then( nodeListArray =>{
4215
- * console.log(nodeListArray[0]) // div.xxx => NodeList
4216
- * console.log(nodeListArray[1]) // a.xxx => NodeList
4350
+ * Utils.waitNodeList(["div"],10000).then( $result =>{
4351
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>[] | null
4217
4352
  * })
4218
4353
  */
4219
- waitNodeList<T extends HTMLElement>(
4220
- ...nodeSelectors: string[]
4221
- ): Promise<NodeListOf<T>[]>;
4222
- waitNodeList<T extends HTMLElement>(
4223
- ...nodeSelectors: string[]
4224
- ): Promise<NodeListOf<T>[]> {
4225
- let UtilsContext = this;
4226
- /* 检查每个参数是否为字符串类型 */
4227
- for (let nodeSelector of nodeSelectors) {
4228
- if (typeof nodeSelector !== "string") {
4229
- throw new Error("Utils.waitNode 参数必须为 ...string 类型");
4354
+ waitNodeList<T extends NodeListOf<Element>>(
4355
+ selectorList: string[],
4356
+ timeout: number
4357
+ ): Promise<T[] | null>;
4358
+ waitNodeList<T extends NodeListOf<Element> | NodeListOf<Element>[]>(
4359
+ ...args: any[]
4360
+ ): Promise<T | null> {
4361
+ // 过滤掉undefined
4362
+ args = args.filter((arg) => arg !== void 0);
4363
+ let that = this;
4364
+ // 选择器数组
4365
+ let selector = args[0] as unknown as string | string[];
4366
+ // 父元素(监听的元素)
4367
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4368
+ // 超时时间
4369
+ let timeout = 0;
4370
+ if (typeof args[0] !== "string" && !Array.isArray(args[0])) {
4371
+ throw new TypeError("Utils.waitNodeList 第一个参数必须是string|string[]");
4372
+ }
4373
+ if (args.length === 1) {
4374
+ // 上面已做处理
4375
+ } else if (args.length === 2) {
4376
+ let secondParam = args[1];
4377
+ if (typeof secondParam === "number") {
4378
+ // "div",10000
4379
+ timeout = secondParam;
4380
+ } else if (
4381
+ typeof secondParam === "object" &&
4382
+ secondParam instanceof Node
4383
+ ) {
4384
+ // "div",document
4385
+ parent = secondParam;
4386
+ } else {
4387
+ throw new TypeError("Utils.waitNodeList 第二个参数必须是number|Node");
4230
4388
  }
4389
+ } else if (args.length === 3) {
4390
+ // "div",document,10000
4391
+ // 第二个参数,parent
4392
+ let secondParam = args[1];
4393
+ // 第三个参数,timeout
4394
+ let thirdParam = args[2];
4395
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4396
+ parent = secondParam;
4397
+ if (typeof thirdParam === "number") {
4398
+ timeout = thirdParam;
4399
+ } else {
4400
+ throw new TypeError("Utils.waitNodeList 第三个参数必须是number");
4401
+ }
4402
+ } else {
4403
+ throw new TypeError("Utils.waitNodeList 第二个参数必须是Node");
4404
+ }
4405
+ } else {
4406
+ throw new TypeError("Utils.waitNodeList 参数个数错误");
4231
4407
  }
4232
-
4233
4408
  return new Promise((resolve) => {
4234
- /* 防止触发第二次回调 */
4235
- let isReturn = false;
4236
-
4237
- /* 检查所有选择器是否匹配到节点 */
4238
- let checkNodes = (observer?: MutationObserver) => {
4239
- let isFind = true;
4240
- let selectNodes = [];
4241
- for (let selector of nodeSelectors) {
4242
- let nodeList = document.querySelectorAll(selector);
4243
- if (nodeList.length === 0) {
4244
- /* 没找到,直接退出循环 */
4245
- isFind = false;
4246
- break;
4409
+ function getNodeList() {
4410
+ if (Array.isArray(selector)) {
4411
+ let result: T[] = [];
4412
+ for (let index = 0; index < selector.length; index++) {
4413
+ let nodeList = (parent as Element).querySelectorAll(
4414
+ selector[index]
4415
+ ) as T;
4416
+ if (nodeList.length) {
4417
+ result.push(nodeList);
4418
+ }
4247
4419
  }
4248
- selectNodes.push(nodeList);
4249
- }
4250
- if (isFind) {
4251
- isReturn = true;
4252
- observer?.disconnect();
4253
- /* 如果只有一个选择器,那么返回第一个 */
4254
- if (selectNodes.length === 1) {
4255
- resolve(selectNodes[0] as any);
4256
- } else {
4257
- resolve(selectNodes as any);
4420
+ if (result.length === selector.length) {
4421
+ return result;
4422
+ }
4423
+ } else {
4424
+ let nodeList = (parent as Element).querySelectorAll(selector) as T;
4425
+ if (nodeList.length) {
4426
+ return nodeList;
4258
4427
  }
4259
4428
  }
4260
- };
4261
-
4262
- /* 在函数开始时检查节点是否已经存在 */
4263
- checkNodes();
4264
-
4265
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4266
- UtilsContext.mutationObserver(document.documentElement, {
4267
- config: { subtree: true, childList: true, attributes: true },
4268
- callback: (mutations, observer) => {
4269
- if (isReturn) {
4429
+ }
4430
+ let nodeList = getNodeList();
4431
+ if (nodeList) {
4432
+ resolve(nodeList as T);
4433
+ return;
4434
+ }
4435
+ let observer = that.mutationObserver(parent, {
4436
+ config: {
4437
+ subtree: true,
4438
+ childList: true,
4439
+ attributes: true,
4440
+ },
4441
+ callback() {
4442
+ let node = getNodeList();
4443
+ if (node) {
4444
+ // 取消观察器
4445
+ observer.disconnect();
4446
+ resolve(node as T);
4270
4447
  return;
4271
4448
  }
4272
- checkNodes(observer);
4273
4449
  },
4274
4450
  });
4451
+ if (timeout > 0) {
4452
+ setTimeout(() => {
4453
+ // 取消观察器
4454
+ observer.disconnect();
4455
+ resolve(null);
4456
+ }, timeout);
4457
+ }
4275
4458
  });
4276
4459
  }
4277
4460
  /**
4278
- * 等待任意元素出现,支持多个selector
4279
- * @param nodeSelectors
4280
- * @returns 返回NodeList
4281
- * NodeList元素与页面存在强绑定,当已获取该NodeList,但是页面中却删除了,该元素在NodeList中会被自动删除
4461
+ * 等待任意元素数组出现
4462
+ * @param selectorList CSS选择器数组
4463
+ * @param parent (可选)监听的父元素
4282
4464
  * @example
4283
- * Utils.waitAnyNodeList("div.xxx").then( nodeList =>{
4284
- * console.log(nodeList) // div.xxx => NodeList
4465
+ * Utils.waitAnyNodeList(["div","a"]).then( $result =>{
4466
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4467
+ * })
4468
+ * Utils.waitAnyNodeList(["div","a"],document).then( $result =>{
4469
+ * console.log($result); // $result => NodeListOf<HTMLDivElement>
4285
4470
  * })
4471
+ */
4472
+ waitAnyNodeList<T extends Element>(
4473
+ selectorList: string[],
4474
+ parent?: Node | Element | Document | HTMLElement
4475
+ ): Promise<NodeListOf<T>>;
4476
+ /**
4477
+ * 等待任意元素数组出现
4478
+ * @param selectorList CSS选择器数组
4479
+ * @param parent 父元素,默认document
4480
+ * @param timeout 超时时间,默认0
4286
4481
  * @example
4287
- * Utils.waitAnyNodeList("div.xxx","a.xxx").then( nodeList =>{
4288
- * console.log(nodeList) // a.xxx => NodeList
4482
+ * Utils.waitAnyNodeList(["div","a"],document,10000).then( $result =>{
4483
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4289
4484
  * })
4290
4485
  */
4291
- waitAnyNodeList<T extends HTMLElement>(
4292
- ...nodeSelectors: string[]
4293
- ): Promise<NodeListOf<T>[]>;
4294
- waitAnyNodeList<T extends HTMLElement>(
4295
- ...nodeSelectors: string[]
4296
- ): Promise<NodeListOf<T>[]> {
4297
- let UtilsContext = this;
4298
- /* 检查每个参数是否为字符串类型 */
4299
- for (let nodeSelector of nodeSelectors) {
4300
- if (typeof nodeSelector !== "string") {
4301
- throw new Error("Utils.waitNode 参数必须为 ...string 类型");
4486
+ waitAnyNodeList<T extends Element>(
4487
+ selectorList: string[],
4488
+ parent: Node | Element | Document | HTMLElement,
4489
+ timeout: number
4490
+ ): Promise<NodeListOf<T> | null>;
4491
+ /**
4492
+ * 等待任意元素出现
4493
+ * @param selectorList CSS选择器数组
4494
+ * @param timeout 超时时间,默认0
4495
+ * @example
4496
+ * Utils.waitAnyNodeList(["div","div"],10000).then( $result =>{
4497
+ * console.log($result); // $result => NodeListOf<HTMLDivElement> | null
4498
+ * })
4499
+ */
4500
+ waitAnyNodeList<T extends Element>(
4501
+ selectorList: string[],
4502
+ timeout: number
4503
+ ): Promise<NodeListOf<T> | null>;
4504
+ waitAnyNodeList<T extends Element>(
4505
+ ...args: any[]
4506
+ ): Promise<NodeListOf<T> | null> {
4507
+ // 过滤掉undefined
4508
+ args = args.filter((arg) => arg !== void 0);
4509
+ let that = this;
4510
+ // 选择器数组
4511
+ let selectorList = args[0] as unknown as string[];
4512
+ // 父元素(监听的元素)
4513
+ let parent = UtilsCore.document as Node | Element | Document | HTMLElement;
4514
+ // 超时时间
4515
+ let timeout = 0;
4516
+ if (!Array.isArray(args[0])) {
4517
+ throw new TypeError("Utils.waitAnyNodeList 第一个参数必须是string[]");
4518
+ }
4519
+ if (args.length === 1) {
4520
+ // 上面已做处理
4521
+ } else if (args.length === 2) {
4522
+ let secondParam = args[1];
4523
+ if (typeof secondParam === "number") {
4524
+ // "div",10000
4525
+ timeout = secondParam;
4526
+ } else if (
4527
+ typeof secondParam === "object" &&
4528
+ secondParam instanceof Node
4529
+ ) {
4530
+ // "div",document
4531
+ parent = secondParam;
4532
+ } else {
4533
+ throw new TypeError(
4534
+ "Utils.waitAnyNodeList 第二个参数必须是number|Node"
4535
+ );
4302
4536
  }
4303
- }
4304
-
4305
- return new Promise((resolve) => {
4306
- /* 防止触发第二次回调 */
4307
- let isReturn = false;
4308
-
4309
- /* 检查所有选择器是否匹配到节点 */
4310
- let checkNodes = (observer?: MutationObserver) => {
4311
- let selectNodes = [];
4312
- for (let selector of nodeSelectors) {
4313
- selectNodes = document.querySelectorAll(selector) as any;
4314
- if (selectNodes.length) {
4315
- /* 找到,退出循环 */
4316
- break;
4317
- }
4318
- }
4319
- if (selectNodes.length) {
4320
- isReturn = true;
4321
- observer?.disconnect();
4322
- resolve(selectNodes);
4537
+ } else if (args.length === 3) {
4538
+ // "div",document,10000
4539
+ // 第二个参数,parent
4540
+ let secondParam = args[1];
4541
+ // 第三个参数,timeout
4542
+ let thirdParam = args[2];
4543
+ if (typeof secondParam === "object" && secondParam instanceof Node) {
4544
+ parent = secondParam;
4545
+ if (typeof thirdParam === "number") {
4546
+ timeout = thirdParam;
4547
+ } else {
4548
+ throw new TypeError("Utils.waitAnyNodeList 第三个参数必须是number");
4323
4549
  }
4324
- };
4325
-
4326
- /* 在函数开始时检查节点是否已经存在 */
4327
- checkNodes();
4550
+ } else {
4551
+ throw new TypeError("Utils.waitAnyNodeList 第二个参数必须是Node");
4552
+ }
4553
+ } else {
4554
+ throw new TypeError("Utils.waitAnyNodeList 参数个数错误");
4555
+ }
4328
4556
 
4329
- /* 监听 DOM 的变化,直到至少有一个节点被匹配到 */
4330
- UtilsContext.mutationObserver(document.documentElement, {
4331
- config: { subtree: true, childList: true, attributes: true },
4332
- callback: (mutations, observer) => {
4333
- if (isReturn) {
4334
- return;
4335
- }
4336
- checkNodes(observer);
4337
- },
4338
- });
4557
+ let promiseList = selectorList.map((selector) => {
4558
+ return that.waitNodeList<NodeListOf<T>>(selector, parent, timeout);
4339
4559
  });
4560
+ return Promise.any(promiseList);
4340
4561
  }
4562
+
4341
4563
  /**
4342
4564
  * 等待对象上的属性出现
4343
4565
  * @param checkObj 检查的对象